mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-14 16:33:28 +00:00
Tests for globals with different kinds of behavior in DS Analysis.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@7191 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
a53e3da92c
commit
71b35cd0fe
80
test/Analysis/DSGraph/globalgraph.c
Normal file
80
test/Analysis/DSGraph/globalgraph.c
Normal file
@ -0,0 +1,80 @@
|
||||
#include <stdio.h>
|
||||
|
||||
typedef struct Tree_struct {
|
||||
int data;
|
||||
struct Tree_struct *left, *right;
|
||||
} Tree;
|
||||
|
||||
static Tree T1, T2, T3, T4, T5, T6, T7;
|
||||
static Tree *Root, *ANode;
|
||||
static int N = 4107;
|
||||
|
||||
/* forces *Tb->right to be collapsed */
|
||||
void makeMore(Tree* Ta, Tree* Tb)
|
||||
{
|
||||
Ta->left = &T1;
|
||||
Ta->right = &T2;
|
||||
Tb->left = &T4;
|
||||
/* Tb->right = &T5; */
|
||||
Tb->right = (Tree*) (((char*) &T5) + 5); /* point to fifth byte of T5 */
|
||||
}
|
||||
|
||||
/* multiple calls to this should force globals to be merged in TD graph
|
||||
* but not in globals graph
|
||||
*/
|
||||
void makeData(Tree* Ta)
|
||||
{
|
||||
static int N = 101;
|
||||
Ta->data = N;
|
||||
}
|
||||
|
||||
void makeRoots()
|
||||
{
|
||||
T1.left = &T2;
|
||||
makeMore(&T1, &T3);
|
||||
}
|
||||
|
||||
/* BU graph shows T1.left->{T2}, but TD graph should show T1.left->{T1,T2,T6,H}
|
||||
* and T.right->{T1,T2,T6,H} */
|
||||
void makeAfter1()
|
||||
{
|
||||
T1.left = &T2;
|
||||
}
|
||||
|
||||
/* BU graph shows:
|
||||
* T2.right->{H}, H.left->{T6}; H.right->{T2}, T3.left<->T7.left
|
||||
*
|
||||
* TD graph and GlobalsGraph should show:
|
||||
* T2.right->{T1,T2,T6,H}
|
||||
* H.left->{T1,T2,T6,H}; H.right->{T1,T2,T6,H}.
|
||||
* T3.left->{T4,T7}, T3.right->{T4,T7}, T7.left->{T3}
|
||||
*/
|
||||
void makeAfter2()
|
||||
{
|
||||
Tree* newT = (Tree*) malloc(sizeof(Tree));
|
||||
T2.right = newT; /* leaked: do not access T2 in main */
|
||||
newT->left = &T6;
|
||||
newT->right = &T2;
|
||||
|
||||
T3.left = &T7;
|
||||
T7.left = &T3;
|
||||
}
|
||||
|
||||
/* BU and TD graphs should have no reachable globals, forcing callers and
|
||||
* callees to get all globals from GlobalsGraph
|
||||
*/
|
||||
void makePass()
|
||||
{
|
||||
makeAfter1();
|
||||
makeAfter2();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
makeRoots();
|
||||
T3.right = &T4;
|
||||
makeData(&T3);
|
||||
makeData(&T5);
|
||||
makePass();
|
||||
printf("T3.data = %d\n", T3.data);
|
||||
}
|
43
test/Analysis/DSGraph/globals.c
Normal file
43
test/Analysis/DSGraph/globals.c
Normal file
@ -0,0 +1,43 @@
|
||||
/* Test globals used and unused within different parts of a program */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
extern void exit_dummy(int*);
|
||||
|
||||
static int** G;
|
||||
static int N, M;
|
||||
|
||||
void
|
||||
foo(int *Z) /* accesses globals printf and format string, and */
|
||||
{ /* N = alloca(int) from test() */
|
||||
if (Z == 0) exit_dummy(Z); /* call to external function */
|
||||
++*Z;
|
||||
printf("N = %d\n", *Z);
|
||||
}
|
||||
|
||||
void leaf2(int* Y)
|
||||
{
|
||||
if (Y == 0) exit_dummy(Y); /* second call to external function */
|
||||
}
|
||||
|
||||
void
|
||||
test(int* X) /* accesses global G */
|
||||
{ /* allocates G = malloc(int*) and N = alloca(int) */
|
||||
if (X == 0)
|
||||
X = &N;
|
||||
G = (int**) alloca(sizeof(int*));
|
||||
*G = &N;
|
||||
**G = 10;
|
||||
foo(*G);
|
||||
leaf2(*G);
|
||||
*X = **G;
|
||||
/* free(G); */
|
||||
}
|
||||
|
||||
int
|
||||
main() /* only accesses global N */
|
||||
{
|
||||
/* N = 0; */
|
||||
test(0 /*&N*/);
|
||||
return 0;
|
||||
}
|
32
test/DSGraphs/ggcollapse.c
Normal file
32
test/DSGraphs/ggcollapse.c
Normal file
@ -0,0 +1,32 @@
|
||||
#include <stdio.h>
|
||||
|
||||
typedef struct Tree_struct {
|
||||
int data;
|
||||
struct Tree_struct *left, *right;
|
||||
} Tree;
|
||||
|
||||
static Tree T1, T2, T3, T4, T5;
|
||||
static Tree *Root, *ANode;
|
||||
static int N = 4107;
|
||||
|
||||
/* forces *Tb->right to be collapsed */
|
||||
void makeMore(Tree* Ta, Tree* Tb)
|
||||
{
|
||||
Ta->left = &T1;
|
||||
Ta->right = &T2;
|
||||
Tb->left = &T4;
|
||||
Tb->right = (Tree*) (((char*) &T5) + 5); /* point to fifth byte of T5 */
|
||||
}
|
||||
|
||||
void makeRoots()
|
||||
{
|
||||
T1.left = &T2;
|
||||
makeMore(&T1, &T3);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
makeRoots();
|
||||
T3.right = &T4;
|
||||
printf("T3.data = %d\n", T3.data);
|
||||
}
|
34
test/DSGraphs/ggfuncptr.c
Normal file
34
test/DSGraphs/ggfuncptr.c
Normal file
@ -0,0 +1,34 @@
|
||||
/* Test resolvable and unresolvable calls through function pointers:
|
||||
* -- both should be retained in function graphs until resolved or until main
|
||||
* -- former should get resolved in or before main() and never appear in GG
|
||||
* -- latter should remain unresolved in main() and copied to GG
|
||||
* -- globals in GG pointed to by latter should be marked I, but not other nodes
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
extern void exit_dummy(int*);
|
||||
|
||||
static int X, M, Z;
|
||||
|
||||
void makeCalls(void(*GpKnown)(int*), void(*GpUnknown)(int*))
|
||||
{
|
||||
if (Z == 0) GpUnknown(&X); /* pass to exit_dummy: never resolved */
|
||||
else GpKnown(&M); /* pass to knownF: resolved in main*/
|
||||
++Z;
|
||||
printf("&Z = %p\n", &Z); /* "known external": resolved here */
|
||||
}
|
||||
|
||||
void knownF(int* Y)
|
||||
{
|
||||
if (Y == 0) knownF(Y); /* direct call to self: resolved here */
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
void(*GpKnown)(int*) = knownF;
|
||||
void(*GpUnknown)(int*) = exit_dummy;
|
||||
Z = argc;
|
||||
makeCalls(GpKnown, GpUnknown);
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user