From 71b35cd0fe1c17255e1c49af3e8f592725ed1721 Mon Sep 17 00:00:00 2001 From: "Vikram S. Adve" Date: Wed, 16 Jul 2003 21:48:38 +0000 Subject: [PATCH] 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 --- test/Analysis/DSGraph/globalgraph.c | 80 +++++++++++++++++++++++++++++ test/Analysis/DSGraph/globals.c | 43 ++++++++++++++++ test/DSGraphs/ggcollapse.c | 32 ++++++++++++ test/DSGraphs/ggfuncptr.c | 34 ++++++++++++ 4 files changed, 189 insertions(+) create mode 100644 test/Analysis/DSGraph/globalgraph.c create mode 100644 test/Analysis/DSGraph/globals.c create mode 100644 test/DSGraphs/ggcollapse.c create mode 100644 test/DSGraphs/ggfuncptr.c diff --git a/test/Analysis/DSGraph/globalgraph.c b/test/Analysis/DSGraph/globalgraph.c new file mode 100644 index 00000000000..cd50d49d7bc --- /dev/null +++ b/test/Analysis/DSGraph/globalgraph.c @@ -0,0 +1,80 @@ +#include + +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); +} diff --git a/test/Analysis/DSGraph/globals.c b/test/Analysis/DSGraph/globals.c new file mode 100644 index 00000000000..f0fb55d21d6 --- /dev/null +++ b/test/Analysis/DSGraph/globals.c @@ -0,0 +1,43 @@ +/* Test globals used and unused within different parts of a program */ + +#include + +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; +} diff --git a/test/DSGraphs/ggcollapse.c b/test/DSGraphs/ggcollapse.c new file mode 100644 index 00000000000..c055caf668c --- /dev/null +++ b/test/DSGraphs/ggcollapse.c @@ -0,0 +1,32 @@ +#include + +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); +} diff --git a/test/DSGraphs/ggfuncptr.c b/test/DSGraphs/ggfuncptr.c new file mode 100644 index 00000000000..93491248555 --- /dev/null +++ b/test/DSGraphs/ggfuncptr.c @@ -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 + +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; +} -- 2.34.1