This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[tree-ssa] Fix mudflap codegen and allow optimizations [patch]


The last mainline merge exposed a bug in mudflap's code
generation.  Mudflap replaces most pointer and array dereferences
with a statement-expression:

*p = 5;

is rewritten into:

-----------------------------------------------------------------------------
*({
  int *const __mf_value = p;
  uintptr_t __mf_base = (uintptr_t) (int) __mf_value;
  uintptr_t __mf_size = 4;
  struct __mf_cache *__mf_elem;
  __mf_elem = &__mf_lookup_cache[__mf_base >> __mf_lookup_shift_l
                                 & __mf_lookup_mask_l];
  if (__builtin_expect (__mf_elem->low > __mf_base
			|| __mf_elem->high < __mf_base + __mf_size - 1, 0))
    {
      __mf_check ((void *) __mf_base, (unsigned int) __mf_size, 1, "file:line");
      __mf_lookup_shift_l = __mf_lc_shift;
      __mf_lookup_mask_l = __mf_lc_mask;
    }
  __mf_value;
}) = 5;
-----------------------------------------------------------------------------

Once transformed, the program is fed into the gimplifier to
generate GIMPLE code.  There were some problems with this:

- Instead of generating a STMT_EXPR, mudflap was emitting a
  BIND_EXPR.  The above was emitting a BIND_EXPR inside an
  INDIRECT_REF node.  This would sometimes cause bad RTL to be
  generated (unfortunately I didn't find out exactly when, but as
  soon as I changed mudflap to emit a proper STMT_EXPR, the
  testcase I was looking at started working again).

- The call to __builtin_expect was using BIT_IOR_EXPR instead of
  TRUTH_ORIF_EXPR.  This prevents the short-circuit evaluation of
  the predicate, producing slightly slower code.

- Variables weren't being declared with DECL_CONTEXT set.  This
  would sometimes cause ICEs in the backend (this only started
  happening after I converted mudflap to emit STMT_EXPR).

The change to emitting STMT_EXPRs fixes the regression on
pass33-frag.c.  This patch is only temporary, a proper fix for
this is to change mudflap to generate GIMPLE code directly.
Emitting C trees and calling the genericizer/gimplifier again is
not a good idea.  But that change is a bit invasive.  I'll
probably start on that shortly.

The patch also adds debugging dumps to mudflap using the standard
-fdump-tree switch.  It supports -fdump-tree-mudflap and
-fdump-tree-mudflap-details.

Finally, I moved mudflap to run after the SSA optimizers.
Although the optimizers are still not very smart wrt pointers and
arrays, they do manage to remove the odd pointer or array
reference.  And, in fact, after I did that a bunch of libmudflap
tests started failing because DCE was removing the very code that
mudflap was supposed to instrument.  So, I needed to sprinkle
volatile here and there to tie the optimizers hands.

Bootstrapped and tested x86 and x86-64.  I tried to test on PPC
but dejagnu returns this:

-----------------------------------------------------------------------------
Using /usr/share/dejagnu/baseboards/unix.exp as board description file for targe
t.
Using /usr/share/dejagnu/config/unix.exp as generic interface file for target.
Using /home/dnovillo/tree-ssa/src.ppc/libmudflap/testsuite/config/default.exp as
 tool-and-target-specific interface file.
Running /home/dnovillo/tree-ssa/src.ppc/libmudflap/testsuite/libmudflap.c/cfrags
.exp ...
ERROR: (DejaGnu) proc "dg-trim-dirname /home/dnovillo/tree-ssa/src.ppc/libmudfla
p/testsuite /home/dnovillo/tree-ssa/src.ppc/libmudflap/testsuite/libmudflap.c/fa
il1-frag.c" does not exist.
The error code is NONE
The info on the error is:
no files matched glob pattern "/home/dnovillo/tree-ssa/src.ppc/libmudflap/testsu
ite/libmudflap.c++/libmudflap*"
    while executing
"glob /home/dnovillo/tree-ssa/src.ppc/libmudflap/testsuite/libmudflap.c++/libmud
flap*"
    invoked from within
"catch "glob ${path}/${pattern}" tmp"
-----------------------------------------------------------------------------

Frank, I checked and the file it complains about does exist.  I'm
not very familiar with dejagnu.  Do you recognize the above?
Also, could you take a look at the changes I made to
tree-mudflap.c?  I want to make sure I didn't miss anything.


Thanks.  Diego.


gcc/

	* Makefile.in (tree-mudflap.o): Add dependency on $(TREE_DUMP_H).
	* c-decl.c (c_expand_body_1): Don't call simplify_function_tree
	after mudflap_c_function.
	Move mudflap instrumentation after SSA optimizers.
	* tree-dump.c (dump_files): Add entry for -fdump-tree-mudflap.
	* tree.h (enum tree_dump_index): Add TDI_mudflap.
	* doc/invoke.texi: Document -fdump-tree-mudflap.
	* tree-mudflap.c: Include tree-dump.h.
	(dump_file): New local variable.
	(dump_flags): New local variable.
	(mudflap_c_function): Call dump_begin, dump_end and dump_function.
	(mf_decl_cache_locals): Set DECL_CONTEXT for __mf_lookup_shift_l
	and __mf_lookup_mask_l to current_function_decl.
	(mf_offset_expr_of_array_ref): Likewise for __mf_index_X.
	(mf_build_check_statement_for): Re-implement to emit a proper
	STMT_EXPR.
	(mx_xfn_indirect_ref): Emit detailed debugging info if
	-fdump-tree-mudflap-details is given.
	(mudflap_enqueue_decl): Likewise
	* tree-optimize.c (optimize_function_tree): Don't check for
	-fmudflap.


libmudflap/

	* testsuite/libmudflap.c/fail1-frag.c: Add volatile
	modifiers to prevent being optimized away.
	* testsuite/libmudflap.c/fail10-frag.c: Likewise.
	* testsuite/libmudflap.c/fail13-frag.c: Likewise.
	* testsuite/libmudflap.c/fail14-frag.c: Likewise.
	* testsuite/libmudflap.c/fail15-frag.c: Likewise.
	* testsuite/libmudflap.c/fail2-frag.c: Likewise.
	* testsuite/libmudflap.c/fail20-frag.c: Likewise.
	* testsuite/libmudflap.c/fail3-frag.c: Likewise.

Index: gcc/Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.903.2.87
diff -d -u -p -r1.903.2.87 Makefile.in
--- gcc/Makefile.in	18 Apr 2003 05:07:21 -0000	1.903.2.87
+++ gcc/Makefile.in	27 Apr 2003 17:46:06 -0000
@@ -1557,7 +1557,8 @@ tree-simple.o : tree-simple.c $(CONFIG_H
 	$(RTL_H) $(TREE_SIMPLE_H) $(TM_H) coretypes.h
 tree-mudflap.o : $(CONFIG_H) errors.h $(SYSTEM_H) $(TREE_H) tree-inline.h \
    $(C_TREE_H) $(C_COMMON_H) $(TREE_SIMPLE_H) diagnostic.h $(HASHTAB_H) \
-   output.h varray.h langhooks.h tree-mudflap.h $(TM_H) coretypes.h
+   output.h varray.h langhooks.h tree-mudflap.h $(TM_H) coretypes.h \
+   $(TREE_DUMP_H)
 c-mudflap.o : $(CONFIG_H) errors.h $(SYSTEM_H) $(TREE_H) tree-inline.h \
    $(C_TREE_H) $(C_COMMON_H) $(TREE_SIMPLE_H) diagnostic.h $(HASHTAB_H) \
    output.h varray.h langhooks.h tree-mudflap.h $(TM_H) coretypes.h
Index: gcc/c-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v
retrieving revision 1.334.2.43
diff -d -u -p -r1.334.2.43 c-decl.c
--- gcc/c-decl.c	16 Apr 2003 15:25:59 -0000	1.334.2.43
+++ gcc/c-decl.c	27 Apr 2003 17:46:11 -0000
@@ -6593,21 +6593,13 @@ c_expand_body_1 (fndecl, nested_p)
       /* Debugging dump after simplification.  */
       dump_function (TDI_simple, fndecl);
 
-      if (flag_mudflap)
-	{
-	  mudflap_c_function (fndecl);
-
-	  /* Simplify mudflap instrumentation.  FIXME  Long term: Would it
-	     be better for mudflap to simplify each tree as it generates
-	     them?  It definitely would be good if mudflap didn't
-	     require another simplification pass.  simplification is
-	     the single most expensive part of the tree-ssa path! */
-	  simplify_function_tree (fndecl);
-	}
-
       /* Invoke the SSA tree optimizer.  */
       if (optimize >= 1 && !flag_disable_tree_ssa)
 	optimize_function_tree (fndecl);
+
+      /* Add mudflap instrumentation.  */
+      if (flag_mudflap)
+	mudflap_c_function (fndecl);
     }
 
   timevar_push (TV_EXPAND);
Index: gcc/tree-dump.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-dump.c,v
retrieving revision 1.6.2.24
diff -d -u -p -r1.6.2.24 tree-dump.c
--- gcc/tree-dump.c	1 Mar 2003 00:09:07 -0000	1.6.2.24
+++ gcc/tree-dump.c	27 Apr 2003 17:46:12 -0000
@@ -689,6 +689,7 @@ static struct dump_file_info dump_files[
   {".copyprop", "dump-tree-copyprop", 0, 0},
   {".dce", "dump-tree-dce", 0, 0},
   {".optimized", "dump-tree-optimized", 0, 0},
+  {".mudflap", "dump-tree-mudflap", 0, 0},
   {".xml", "dump-call-graph", 0, 0},
   {NULL, "dump-tree-all", 0, 0},
 };
Index: gcc/tree-mudflap.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-mudflap.c,v
retrieving revision 1.1.2.38
diff -d -u -p -r1.1.2.38 tree-mudflap.c
--- gcc/tree-mudflap.c	10 Mar 2003 22:39:15 -0000	1.1.2.38
+++ gcc/tree-mudflap.c	27 Apr 2003 17:46:13 -0000
@@ -43,7 +43,7 @@ Software Foundation, 59 Temple Place - S
 #include "toplev.h"
 #include "function.h"
 #include "demangle.h"
-
+#include "tree-dump.h"
 
 /* Internal function decls */
 
@@ -64,6 +64,10 @@ static tree mf_build_check_statement_for
 						  const char *, int));
 static void mx_register_decls PARAMS ((tree, tree *));
 
+/* Debugging dumps.  */
+static FILE *dump_file;
+static int dump_flags;
+
 
 /* These macros are used to mark tree nodes, so that they are not
    repeatedly transformed.  The `bounded' flag is not otherwise used.  */
@@ -79,16 +83,8 @@ void 
 mudflap_c_function (t)
      tree t;
 {
-  if (getenv ("UNPARSE"))  /* XXX */
-    {
-      print_generic_expr (stderr, DECL_RESULT (t), 0);
-      fprintf (stderr, " ");
-      print_generic_expr (stderr, DECL_NAME (t), 0);
-      fprintf (stderr, " (");
-      print_generic_expr (stderr, DECL_ARGUMENTS (t), 0);
-      fprintf (stderr, " )\n");
-      print_generic_stmt (stderr, DECL_SAVED_TREE (t), 0);
-    }
+  /* Initialize debugging dumps.  */
+  dump_file = dump_begin (TDI_mudflap, &dump_flags);
 
   mf_init_extern_trees ();
 
@@ -97,10 +93,15 @@ mudflap_c_function (t)
   mf_xform_decls (DECL_SAVED_TREE (t), DECL_ARGUMENTS (t));
   mf_xform_derefs (DECL_SAVED_TREE (t));
 
-  if (getenv ("UNPARSE"))  /* XXX */
+  /* Simplify mudflap instrumentation.  FIXME  It definitely would be good
+     if mudflap didn't require another simplification pass.  simplification
+     is the single most expensive part of the tree-ssa path! */
+  simplify_function_tree (t);
+
+  if (dump_file)
     {
-      fprintf (stderr, "/* after -fmudflap: */\n");
-      print_generic_stmt (stderr, DECL_SAVED_TREE (t), 0);
+      dump_end (TDI_mudflap, dump_file);
+      dump_function (TDI_mudflap, t);
     }
 
   mf_decl_clear_locals ();
@@ -159,6 +160,7 @@ mf_init_extern_trees ()
 /* Create and initialize local shadow variables for the lookup cache
    globals.  Put their decls in the *_l globals for use by
    mf_build_check_statement_for. */
+
 static void 
 mf_decl_cache_locals (body)
      tree* body;
@@ -170,11 +172,13 @@ mf_decl_cache_locals (body)
 					       get_identifier ("__mf_lookup_shift_l"),
 					       TREE_TYPE (mf_cache_shift_decl)));
   DECL_ARTIFICIAL (mf_cache_shift_decl_l) = 1;
+  DECL_CONTEXT (mf_cache_shift_decl_l) = current_function_decl;
 
   mf_cache_mask_decl_l = mx_flag (build_decl (VAR_DECL,
 					      get_identifier ("__mf_lookup_mask_l"),
 					      TREE_TYPE (mf_cache_mask_decl)));
   DECL_ARTIFICIAL (mf_cache_mask_decl_l) = 1;
+  DECL_CONTEXT (mf_cache_mask_decl_l) = current_function_decl;
   TREE_CHAIN (mf_cache_shift_decl_l) = mf_cache_mask_decl_l;
 
   /* Build initialization nodes for them.  */
@@ -435,6 +439,7 @@ mf_offset_expr_of_array_ref (t, offset, 
 			    TREE_TYPE (idxexpr));
       DECL_ARTIFICIAL (newdecl) = 1;
       DECL_INITIAL (newdecl) = idxexpr;
+      DECL_CONTEXT (newdecl) = current_function_decl;
 
       /* Accumulate this new decl. */
       *decls = tree_cons (NULL_TREE, newdecl, *decls);
@@ -503,7 +508,6 @@ mf_build_check_statement_for (ptrvalue, 
   tree t1_2b_1;
   tree t1_3_1;
   tree t1_4_1, t1_4_2;
-  tree t0;
 
   /* Provide a default access type number */
   if (acctype == NULL_TREE)
@@ -513,13 +517,11 @@ mf_build_check_statement_for (ptrvalue, 
   while (chkdecls != NULL_TREE)
     {
       tree decl = TREE_VALUE (chkdecls);
-      tree init = DECL_INITIAL (decl);
-      tree type = TREE_TYPE (init);
-      tree declstmt = build (INIT_EXPR, type, decl, init);
-
-      DECL_INITIAL (decl) = NULL_TREE; /* use INIT_EXPR instead */
-      TREE_CHAIN (decl) = bind_decls; bind_decls = decl;
-      add_tree (declstmt, & bind_exprs);
+      tree declstmt = build_stmt (DECL_STMT, decl);
+      DECL_ARTIFICIAL (decl) = 1;
+      DECL_CONTEXT (decl) = current_function_decl;
+      bind_decls = chainon (bind_decls, decl);
+      bind_exprs = chainon (bind_exprs, declstmt);
 
       chkdecls = TREE_CHAIN (chkdecls);
     }
@@ -527,119 +529,176 @@ mf_build_check_statement_for (ptrvalue, 
   /* <TYPE> const __mf_value = <EXPR>; */
   t1_2_1 = build_decl (VAR_DECL, get_identifier ("__mf_value"), myptrtype);
   DECL_ARTIFICIAL (t1_2_1) = 1;
-  TREE_CHAIN (t1_2_1) = bind_decls; bind_decls = t1_2_1;
-  add_tree (build (INIT_EXPR, myptrtype, 
-		   t1_2_1,
-		   ptrvalue), 
-	    & bind_exprs);
+  DECL_INITIAL (t1_2_1) = ptrvalue;
+  DECL_CONTEXT (t1_2_1) = current_function_decl;
+  bind_decls = chainon (bind_decls, t1_2_1);
+  bind_exprs = chainon (bind_exprs, build_stmt (DECL_STMT, t1_2_1));
 
   /* uintptr_t __mf_base = <EXPR2>; */
-  t1_2a_1 = build_decl (VAR_DECL, get_identifier ("__mf_base"), mf_uintptr_type);
+  t1_2a_1 = build_decl (VAR_DECL, get_identifier ("__mf_base"),
+                        mf_uintptr_type);
   DECL_ARTIFICIAL (t1_2a_1) = 1;
-  TREE_CHAIN (t1_2a_1) = bind_decls; bind_decls = t1_2a_1;
-  add_tree (build (INIT_EXPR, mf_uintptr_type,
-		   t1_2a_1, 
-		   convert (mf_uintptr_type, ((chkbase == ptrvalue) ? t1_2_1 : chkbase))),
-	    & bind_exprs);
+  DECL_INITIAL (t1_2a_1) = convert (mf_uintptr_type,
+	                            ((chkbase == ptrvalue) ? t1_2_1 : chkbase));
+  DECL_CONTEXT (t1_2a_1) = current_function_decl;
+  bind_exprs = chainon (bind_exprs, build_stmt (DECL_STMT, t1_2a_1));
+  bind_decls = chainon (bind_decls, t1_2a_1);
 
   /* uintptr_t __mf_size = <EXPR>; */
-  t1_2b_1 = build_decl (VAR_DECL, get_identifier ("__mf_size"), mf_uintptr_type);
+  t1_2b_1 = build_decl (VAR_DECL, get_identifier ("__mf_size"),
+                        mf_uintptr_type);
   DECL_ARTIFICIAL (t1_2b_1) = 1;
-  TREE_CHAIN (t1_2b_1) = bind_decls; bind_decls = t1_2b_1;
-  add_tree (build (INIT_EXPR, mf_uintptr_type,
-		   t1_2b_1, 
-		   convert (mf_uintptr_type,
-			    ((chksize == NULL_TREE) ? integer_one_node : chksize))),
-	    & bind_exprs);
+  DECL_INITIAL (t1_2b_1) = convert (mf_uintptr_type,
+				    ((chksize == NULL_TREE)
+				     ? integer_one_node
+				     : chksize));
+  DECL_CONTEXT (t1_2b_1) = current_function_decl;
+  bind_decls = chainon (bind_decls, t1_2b_1);
+  bind_exprs = chainon (bind_exprs, build_stmt (DECL_STMT, t1_2b_1));
 
   /* struct __mf_cache * const __mf_elem = [...] */
-  t1_3_1 = build_decl (VAR_DECL, get_identifier ("__mf_elem"), mf_cache_structptr_type);
+  t1_3_1 = build_decl (VAR_DECL, get_identifier ("__mf_elem"),
+                       mf_cache_structptr_type);
   DECL_ARTIFICIAL (t1_3_1) = 1;
-  TREE_CHAIN (t1_3_1) = bind_decls; bind_decls = t1_3_1;
+  DECL_CONTEXT (t1_3_1) = current_function_decl;
+  bind_decls = chainon (bind_decls, t1_3_1);
+  bind_exprs = chainon (bind_exprs, build_stmt (DECL_STMT, t1_3_1));
 
-    /* & __mf_lookup_cache [(((uintptr_t)__mf_base) >> __mf_shift) & __mf_mask] */
-  add_tree (build (INIT_EXPR, mf_cache_structptr_type,
-		   t1_3_1, 
-		   mx_flag (build1 (ADDR_EXPR, mf_cache_structptr_type,
-				    mx_flag (build (ARRAY_REF, TYPE_MAIN_VARIANT (TREE_TYPE
-										  (TREE_TYPE
-										   (mf_cache_array_decl))),
-						    mf_cache_array_decl,
-						    build (BIT_AND_EXPR, mf_uintptr_type,
-							   build (RSHIFT_EXPR, mf_uintptr_type,
-								  convert (mf_uintptr_type, t1_2a_1),
-								  mf_cache_shift_decl_l),
-							   mf_cache_mask_decl_l)))))),
-	    & bind_exprs);
+  /* & __mf_lookup_cache [(((uintptr_t)__mf_base) >> __mf_shift) & __mf_mask] */
+  {
+    tree t0, t1, t2, t3;
+
+    t0 = build (RSHIFT_EXPR, mf_uintptr_type,
+		convert (mf_uintptr_type, t1_2a_1),
+		mf_cache_shift_decl_l);
+
+    t1 = build (BIT_AND_EXPR, mf_uintptr_type, t0, mf_cache_mask_decl_l);
+
+    t2 = mx_flag (build (ARRAY_REF,
+			 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (mf_cache_array_decl))),
+			 mf_cache_array_decl,
+			 t1));
+
+    t3 = mx_flag (build1 (ADDR_EXPR, mf_cache_structptr_type, t2));
+
+    bind_exprs = chainon (bind_exprs,
+			  build_stmt (EXPR_STMT,
+				      build (INIT_EXPR, mf_cache_structptr_type,
+					     t1_3_1, t3)));
+  }
   
-  /* Quick validity check.  */
-  t1_4_1 = build (BIT_IOR_EXPR /* is faster than TRUTH_OR_EXPR */, integer_type_node,
-		  build (GT_EXPR, integer_type_node,
-			 mx_flag (build (COMPONENT_REF, mf_uintptr_type, /* __mf_elem->low */
-					 mx_flag (build1 (INDIRECT_REF, 
-							  mf_cache_struct_type, t1_3_1)),
-					 TYPE_FIELDS (mf_cache_struct_type))),
-			 t1_2a_1), /* __mf_base */
-		  build (LT_EXPR, integer_type_node,
-			 mx_flag (build (COMPONENT_REF, mf_uintptr_type, /* __mf_elem->high */
-					 mx_flag (build1 (INDIRECT_REF, 
-							  mf_cache_struct_type, t1_3_1)),
-					 TREE_CHAIN (TYPE_FIELDS (mf_cache_struct_type)))),
-			 build (PLUS_EXPR, mf_uintptr_type, /* __mf_elem + sizeof(T) - 1 */
-				t1_2a_1,
-				fold (build (MINUS_EXPR, mf_uintptr_type,
-					     t1_2b_1,
-					     integer_one_node)))));
+  /* Quick validity check.
+     if (__builtin_expect (__mf_elem->low > __mf_base
+                           || __mf_elem_high < __mf_base + __mf_size - 1,
+			   0))
+	{
+	  __mf_check ();
+	  __mf_lookup_shift_1 = ...;
+	  __mf_lookup_mask_l = ...;
+	}  */
+  {
+    tree t0, t1, t2;
+
+    /* __mf_elem->low  */
+    t0 = mx_flag (build (COMPONENT_REF, mf_uintptr_type,
+			 mx_flag (build1 (INDIRECT_REF, mf_cache_struct_type,
+			                  t1_3_1)),
+			 TYPE_FIELDS (mf_cache_struct_type)));
+
+    /* __mf_elem->high  */
+    t1 = mx_flag (build (COMPONENT_REF, mf_uintptr_type,
+			 mx_flag (build1 (INDIRECT_REF, mf_cache_struct_type,
+			                  t1_3_1)),
+		         TREE_CHAIN (TYPE_FIELDS (mf_cache_struct_type))));
+
+    /* __mf_elem + sizeof (T) - 1  */
+    t2 = build (PLUS_EXPR, mf_uintptr_type,
+		t1_2a_1,
+		fold (build (MINUS_EXPR, mf_uintptr_type,
+		             t1_2b_1,
+			     integer_one_node)));
+
+    t1_4_1 = build (TRUTH_ORIF_EXPR, integer_type_node,
+		    build (GT_EXPR, integer_type_node, t0, t1_2a_1),
+		    build (LT_EXPR, integer_type_node, t1, t2));
+
+    /* Mark condition as UNLIKELY using __builtin_expect.  */
+    t1_4_1 = build_function_call (built_in_decls[BUILT_IN_EXPECT],
+				  tree_cons (NULL_TREE,
+					     convert (long_integer_type_node,
+					              t1_4_1),
+					     tree_cons (NULL_TREE,
+					  	        integer_zero_node,
+						        NULL_TREE)));
+  }
   
-  /* Mark condition as UNLIKELY using __builtin_expect.  */
-  t1_4_1 = build_function_call (built_in_decls[BUILT_IN_EXPECT],
-				tree_cons (NULL_TREE,
-					   convert (long_integer_type_node, t1_4_1),
-					   tree_cons (NULL_TREE,
-						      integer_zero_node,
-						      NULL_TREE)));
+  /* Build up the body of the cache-miss handling:
+     __mf_check(); refresh *_l vars.  */
+  {
+    tree t0, t1;
 
-  /* Build up the body of the cache-miss handling: __mf_check(); refresh *_l vars.  */
-  t1_4_2 = NULL_TREE;
-  add_tree (build_function_call (mf_check_fndecl,
-				 tree_cons (NULL_TREE,
-					    convert (ptr_type_node, t1_2a_1),
-					    tree_cons (NULL_TREE, 
-						       convert (size_type_node, t1_2b_1),
-						       tree_cons (NULL_TREE,
-								  acctype,
-								  tree_cons (NULL_TREE,
-									     location_string,
-									     NULL_TREE))))),
-	    & t1_4_2);
-  add_tree (build (MODIFY_EXPR, TREE_TYPE (mf_cache_shift_decl_l),
-		   mf_cache_shift_decl_l, mf_cache_shift_decl),
-	    & t1_4_2);
-  add_tree (build (MODIFY_EXPR, TREE_TYPE (mf_cache_mask_decl_l),
-		   mf_cache_mask_decl_l, mf_cache_mask_decl),
-	    & t1_4_2);
-  t1_4_2 = rationalize_compound_expr (t1_4_2);
+    t1_4_2 = NULL_TREE;
+    t0 = build_tree_list (NULL_TREE, convert (ptr_type_node, t1_2a_1));
+    t0 = chainon (t0, build_tree_list (NULL_TREE,
+	                               convert (size_type_node, t1_2b_1)));
+    t0 = chainon (t0, build_tree_list (NULL_TREE, acctype));
+    t0 = chainon (t0, build_tree_list (NULL_TREE, location_string));
+    t1_4_2 = chainon (t1_4_2, 
+	              build_stmt (EXPR_STMT,
+				  build_function_call (mf_check_fndecl, t0)));
 
-  add_tree (build (COND_EXPR, void_type_node,
-		   t1_4_1,
-		   t1_4_2,
-		   empty_stmt_node),
-	    & bind_exprs);
+    t1_4_2 = chainon (t1_4_2,
+		      build_stmt (EXPR_STMT,
+				  build (MODIFY_EXPR,
+					TREE_TYPE (mf_cache_shift_decl_l),
+					mf_cache_shift_decl_l,
+					mf_cache_shift_decl)));
+
+    t1_4_2 = chainon (t1_4_2,
+		      build_stmt (EXPR_STMT,
+				  build (MODIFY_EXPR,
+					TREE_TYPE (mf_cache_mask_decl_l),
+					mf_cache_mask_decl_l,
+					mf_cache_mask_decl)));
+
+    t0 = build_stmt (SCOPE_STMT, NULL_TREE);
+    SCOPE_BEGIN_P (t0) = 1;
+
+    t1 = build_stmt (SCOPE_STMT, NULL_TREE);
+    SCOPE_BEGIN_P (t1) = 0;
+
+    t0 = chainon (t0, t1_4_2);
+    t0 = chainon (t0, t1);
+    t1_4_2 = build_stmt (COMPOUND_STMT, t0);
+  }
+
+  bind_exprs = chainon (bind_exprs,
+		        build_stmt (IF_STMT, t1_4_1, t1_4_2, NULL_TREE));
 
   /* "return" __mf_value, or provided finale.  */
-  TREE_SIDE_EFFECTS (t1_2_1) = 1; /* add_tree antifreak */
-  add_tree (t1_2_1, & bind_exprs);
+  bind_exprs = chainon (bind_exprs, build_stmt (EXPR_STMT, t1_2_1));
 
-  /* Turn the tree into right-recursive form. */
-  bind_exprs = rationalize_compound_expr (bind_exprs);
+  /* Build the body of the statement-expression ({ decls; exprs; })  */
+  {
+    tree t0, t1, block;
 
-  t0 = build (BIND_EXPR, myptrtype, 
-	      nreverse (bind_decls),
-	      bind_exprs, 
-	      NULL_TREE); /* XXX: BLOCK == NULL */
-  TREE_SIDE_EFFECTS (t0) = 1;
+    block = build (BLOCK, void_type_node, NULL_TREE);
+    BLOCK_VARS (block) = bind_decls;
 
-  return t0;
+    t0 = build_stmt (SCOPE_STMT, block);
+    SCOPE_BEGIN_P (t0) = 1;
+
+    t1 = build_stmt (SCOPE_STMT, block);
+    SCOPE_BEGIN_P (t1) = 0;
+
+    t0 = chainon (t0, bind_exprs);
+    t0 = chainon (t0, t1);
+    t0 = build_stmt (COMPOUND_STMT, t0);
+    t0 = build1 (STMT_EXPR, myptrtype, t0);
+    TREE_SIDE_EFFECTS (t0) = 1;
+
+    return t0;
+  }
 }
 
 
@@ -694,11 +753,12 @@ mx_xfn_indirect_ref (t, continue_p, data
   htab_t verboten = (htab_t) data;
   tree tree_role;
 
-#if 0
-  fprintf (stderr, "expr=%s: ", tree_code_name [TREE_CODE (*t)]);
-  print_generic_expr (stderr, *t, 0);
-  fprintf (stderr, "\n");
-#endif
+  if (dump_flags & TDF_DETAILS)
+    {
+      fprintf (dump_file, "expr=%s: ", tree_code_name [TREE_CODE (*t)]);
+      print_generic_expr (dump_file, *t, 0);
+      fprintf (dump_file, "\n");
+    }
 
   /* Track lvalue/rvalue status for this subtree.  */
   if (! tree_roles_init)
@@ -1183,11 +1243,12 @@ mudflap_enqueue_decl (obj, label)
       return;
     }
 
-  /*
-  fprintf (stderr, "enqueue_decl obj=`");
-  print_generic_expr (stderr, obj, 0);
-  fprintf (stderr, "' label=`%s'\n", label);
-  */
+  if (dump_flags & TDF_DETAILS)
+    {
+      fprintf (dump_file, "enqueue_decl obj=`");
+      print_generic_expr (dump_file, obj, 0);
+      fprintf (dump_file, "' label=`%s'\n", label);
+    }
 
   if (COMPLETE_TYPE_P (TREE_TYPE (obj))) 
     {
Index: gcc/tree-optimize.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-optimize.c,v
retrieving revision 1.1.4.36
diff -d -u -p -r1.1.4.36 tree-optimize.c
--- gcc/tree-optimize.c	25 Apr 2003 23:50:09 -0000	1.1.4.36
+++ gcc/tree-optimize.c	27 Apr 2003 17:46:13 -0000
@@ -54,13 +54,6 @@ optimize_function_tree (fndecl)
   if (errorcount || sorrycount)
     return;
   
-#if 1
-  /* FIXME  Temporary hack.  Mudflap generates code that we can't deal with yet
-     (TRY_FINALLY_EXPR).  */
-  if (flag_mudflap)
-    return;
-#endif
-
   fnbody = DECL_SAVED_TREE (fndecl);
 
   /* Build the flowgraph.  */
Index: gcc/tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.342.2.58
diff -d -u -p -r1.342.2.58 tree.h
--- gcc/tree.h	24 Apr 2003 19:20:05 -0000	1.342.2.58
+++ gcc/tree.h	27 Apr 2003 17:46:16 -0000
@@ -3508,6 +3508,7 @@ enum tree_dump_index
   TDI_dce,                      /* dump SSA DCE information for each
 				   function.  */
   TDI_optimized,		/* dump each function after optimizing it.  */
+  TDI_mudflap,			/* dump each function after mudflap.  */
   TDI_xml,                      /* dump function call graph.   */
   TDI_all,			/* enable all the dumps above.  */
   TDI_end
Index: gcc/doc/invoke.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/invoke.texi,v
retrieving revision 1.152.2.39
diff -d -u -p -r1.152.2.39 invoke.texi
--- gcc/doc/invoke.texi	9 Apr 2003 19:28:34 -0000	1.152.2.39
+++ gcc/doc/invoke.texi	27 Apr 2003 17:46:28 -0000
@@ -254,7 +254,7 @@ in the following sections.
 -fdump-tree-cfg -fdump-tree-dot @gol
 -fdump-tree-ssa at r{[}-@var{n} at r{]} -fdump-tree-pre at r{[}-@var{n} at r{]} @gol
 -fdump-tree-ccp at r{[}-@var{n} at r{]} -fdump-tree-dce at r{[}-@var{n} at r{]} @gol
--fdump-tree-simple at r{[}-raw@r{]} @gol
+-fdump-tree-simple at r{[}-raw@r{]} -fdump-tree-mudflap at r{[}-@var{n} at r{]} @gol
 -fmem-report @gol
 -feliminate-dwarf2-dups  -fmem-report @gol
 -fprofile-arcs  -fsched-verbose= at var{n} @gol
@@ -3384,8 +3384,13 @@ appending @file{.copyprop} to the source
 
 @item dce
 @opindex fdump-tree-dce
-Dump each function before and after DCE.  The file name is made by appending
- at file{ dot dce} to the source file name.
+Dump each function after dead code elimination.  The file name is made by
+appending @file{.dce} to the source file name.
+
+ at item mudflap
+ at opindex fdump-tree-mudflap
+Dump each function after adding mudflap instrumentation.  The file name is
+made by appending @file{.mudflap} to the source file name.
 
 @item all
 @opindex fdump-tree-all
Index: libmudflap/testsuite/libmudflap.c/fail1-frag.c
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/testsuite/libmudflap.c/Attic/fail1-frag.c,v
retrieving revision 1.1.2.1
diff -d -u -p -r1.1.2.1 fail1-frag.c
--- libmudflap/testsuite/libmudflap.c/fail1-frag.c	26 Feb 2003 19:00:37 -0000	1.1.2.1
+++ libmudflap/testsuite/libmudflap.c/fail1-frag.c	27 Apr 2003 17:46:37 -0000
@@ -3,7 +3,7 @@
 #include <string.h>
 int main ()
 {
-int foo [10];
+volatile int foo [10];
 foo[10] = 0;
 return 0;
 }
Index: libmudflap/testsuite/libmudflap.c/fail10-frag.c
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/testsuite/libmudflap.c/Attic/fail10-frag.c,v
retrieving revision 1.1.2.1
diff -d -u -p -r1.1.2.1 fail10-frag.c
--- libmudflap/testsuite/libmudflap.c/fail10-frag.c	26 Feb 2003 19:00:37 -0000	1.1.2.1
+++ libmudflap/testsuite/libmudflap.c/fail10-frag.c	27 Apr 2003 17:46:37 -0000
@@ -3,10 +3,10 @@
 #include <string.h>
 int main ()
 {
-int foo[10];
+volatile int foo[10];
 int sz = sizeof (int);
 
-char *bar = (char *)foo;
+volatile char *bar = (char *)foo;
 bar [sz * 10] = 0;
 return 0;
 }
Index: libmudflap/testsuite/libmudflap.c/fail13-frag.c
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/testsuite/libmudflap.c/Attic/fail13-frag.c,v
retrieving revision 1.1.2.1
diff -d -u -p -r1.1.2.1 fail13-frag.c
--- libmudflap/testsuite/libmudflap.c/fail13-frag.c	26 Feb 2003 19:00:37 -0000	1.1.2.1
+++ libmudflap/testsuite/libmudflap.c/fail13-frag.c	27 Apr 2003 17:46:37 -0000
@@ -16,7 +16,7 @@ struct b {
 
 struct b k;
 
-(*((struct a*) &k)).z = 'q';
+(*((volatile struct a*) &k)).z = 'q';
 
 return 0;
 }
Index: libmudflap/testsuite/libmudflap.c/fail14-frag.c
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/testsuite/libmudflap.c/Attic/fail14-frag.c,v
retrieving revision 1.1.2.1
diff -d -u -p -r1.1.2.1 fail14-frag.c
--- libmudflap/testsuite/libmudflap.c/fail14-frag.c	26 Feb 2003 19:00:37 -0000	1.1.2.1
+++ libmudflap/testsuite/libmudflap.c/fail14-frag.c	27 Apr 2003 17:46:37 -0000
@@ -14,8 +14,8 @@ struct b {
   int y;
 };
 
-struct b k;
-struct a *p;
+volatile struct b k;
+volatile struct a *p;
 
 p = (struct a*) &k;
 
Index: libmudflap/testsuite/libmudflap.c/fail15-frag.c
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/testsuite/libmudflap.c/Attic/fail15-frag.c,v
retrieving revision 1.1.2.1
diff -d -u -p -r1.1.2.1 fail15-frag.c
--- libmudflap/testsuite/libmudflap.c/fail15-frag.c	26 Feb 2003 19:00:37 -0000	1.1.2.1
+++ libmudflap/testsuite/libmudflap.c/fail15-frag.c	27 Apr 2003 17:46:37 -0000
@@ -12,8 +12,8 @@ struct derived { 
   char extra;
 };
 
-struct base b;
-struct base *bp;
+volatile struct base b;
+volatile struct base *bp;
 
 bp = (struct base *)&b;
 
Index: libmudflap/testsuite/libmudflap.c/fail2-frag.c
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/testsuite/libmudflap.c/Attic/fail2-frag.c,v
retrieving revision 1.1.2.1
diff -d -u -p -r1.1.2.1 fail2-frag.c
--- libmudflap/testsuite/libmudflap.c/fail2-frag.c	26 Feb 2003 19:00:37 -0000	1.1.2.1
+++ libmudflap/testsuite/libmudflap.c/fail2-frag.c	27 Apr 2003 17:46:37 -0000
@@ -3,7 +3,7 @@
 #include <string.h>
 int main ()
 {
-int foo [10][10];
+volatile int foo [10][10];
 foo[10][0] = 0;
 return 0;
 }
Index: libmudflap/testsuite/libmudflap.c/fail20-frag.c
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/testsuite/libmudflap.c/Attic/fail20-frag.c,v
retrieving revision 1.1.2.1
diff -d -u -p -r1.1.2.1 fail20-frag.c
--- libmudflap/testsuite/libmudflap.c/fail20-frag.c	26 Feb 2003 19:00:37 -0000	1.1.2.1
+++ libmudflap/testsuite/libmudflap.c/fail20-frag.c	27 Apr 2003 17:46:37 -0000
@@ -3,7 +3,7 @@
 #include <string.h>
 int main ()
 {
-char *p = (char *) 0;
+volatile char *p = (char *) 0;
 *p = 5;
 return 0;
 }
Index: libmudflap/testsuite/libmudflap.c/fail3-frag.c
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/testsuite/libmudflap.c/Attic/fail3-frag.c,v
retrieving revision 1.1.2.1
diff -d -u -p -r1.1.2.1 fail3-frag.c
--- libmudflap/testsuite/libmudflap.c/fail3-frag.c	26 Feb 2003 19:00:37 -0000	1.1.2.1
+++ libmudflap/testsuite/libmudflap.c/fail3-frag.c	27 Apr 2003 17:46:37 -0000
@@ -3,7 +3,7 @@
 #include <string.h>
 int main ()
 {
-int foo [10][10][10];
+volatile int foo [10][10][10];
 foo[9][10][0] = 0;
 return 0;
 }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]