Tests for globals with different kinds of behavior in DS Analysis.
authorVikram S. Adve <vadve@cs.uiuc.edu>
Wed, 16 Jul 2003 21:48:38 +0000 (21:48 +0000)
committerVikram S. Adve <vadve@cs.uiuc.edu>
Wed, 16 Jul 2003 21:48:38 +0000 (21:48 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@7191 91177308-0d34-0410-b5e6-96231b3b80d8

test/Analysis/DSGraph/globalgraph.c [new file with mode: 0644]
test/Analysis/DSGraph/globals.c [new file with mode: 0644]
test/DSGraphs/ggcollapse.c [new file with mode: 0644]
test/DSGraphs/ggfuncptr.c [new file with mode: 0644]

diff --git a/test/Analysis/DSGraph/globalgraph.c b/test/Analysis/DSGraph/globalgraph.c
new file mode 100644 (file)
index 0000000..cd50d49
--- /dev/null
@@ -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);
+}
diff --git a/test/Analysis/DSGraph/globals.c b/test/Analysis/DSGraph/globals.c
new file mode 100644 (file)
index 0000000..f0fb55d
--- /dev/null
@@ -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;
+}
diff --git a/test/DSGraphs/ggcollapse.c b/test/DSGraphs/ggcollapse.c
new file mode 100644 (file)
index 0000000..c055caf
--- /dev/null
@@ -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);
+}
diff --git a/test/DSGraphs/ggfuncptr.c b/test/DSGraphs/ggfuncptr.c
new file mode 100644 (file)
index 0000000..9349124
--- /dev/null
@@ -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;
+}