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]

Re: Tree-SSA self checking infrastructure


Hi,
here is updated patch so it deals correctly with sharing of _REFs.  Now
it passes most of testsuite with exception of -O3 compilations (caused
by ADDRESSOF bug disucssed earlier).  I also had to disable SSAPRE pass
as it does not pass veirfy_ssa anymore. The same step (together with
mustalias fixes present in the patch too) makes all bootstraps of
sibcall testing to pass, but it may be conicidence.  I am will try to
figure out what is gong on.

I will break out the fixes and prepare cleaner patch at friday.

Honza

Index: tree-cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-cfg.c,v
retrieving revision 1.1.4.220
diff -c -3 -p -r1.1.4.220 tree-cfg.c
*** tree-cfg.c	19 Nov 2003 02:22:18 -0000	1.1.4.220
--- tree-cfg.c	20 Nov 2003 01:21:07 -0000
*************** make_exit_edges (basic_block bb)
*** 562,567 ****
--- 562,572 ----
  	 create abnormal edges to them.  */
        make_eh_edges (last);
  
+       if (call_expr_flags (last) & ECF_LONGJMP)
+ 	{
+ 	  make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
+ 	  return;
+ 	}
        /* Some calls are known not to return.  For such calls we create
  	 a fake edge.
  
*************** tree_verify_flow_info (void)
*** 2752,2759 ****
      {
        edge e;
        bool found_ctrl_stmt = false;
-       tree phi;
-       int i;
  
        for (e = bb->pred; e; e = e->pred_next)
  	if (e->aux)
--- 2757,2762 ----
*************** tree_verify_flow_info (void)
*** 2761,2803 ****
  	    error ("Aux pointer initialized for edge %d->%d\n", e->src->index, e->dest->index);
  	    err = 1;
  	  }
-       phi = phi_nodes (bb);
-       for ( ; phi; phi = TREE_CHAIN (phi))
- 	{
- 	  int phi_num_args = PHI_NUM_ARGS (phi);
- 
- 	  for (e = bb->pred; e; e = e->pred_next)
- 	    e->aux = (void *)1;
- 	  for (i = 0; i < phi_num_args; i++)
- 	    {
- 	      e = PHI_ARG_EDGE (phi, i);
- 	      if (e->dest != bb)
- 		{
- 		  error ("Phi node for edge %d->%d in %d\n", e->src->index, e->dest->index, bb->index);
- 		  err = 1;
- 		}
- 	      if (e->aux == (void *)0)
- 		{
- 		  error ("Phi node for dead edge %d->%d\n", e->src->index, e->dest->index);
- 		  err = 1;
- 		}
- 	      if (e->aux == (void *)2)
- 		{
- 		  error ("Phi node duplicated for edge %d->%d\n", e->src->index, e->dest->index);
- 		  err = 1;
- 		}
- 	      e->aux = (void *)2;
- 	    }
- 	  for (e = bb->pred; e; e = e->pred_next)
- 	    {
- 	      if (e->aux != (void *)2)
- 		{
- 		  error ("Edge %d->%d miss phi node entry\n", e->src->index, e->dest->index);
- 		  err = 1;
- 		}
- 	      e->aux = (void *)0;
- 	    }
- 	}
  
        /* Skip labels on the start of basic block.  */
        for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
--- 2764,2769 ----
*************** tree_verify_flow_info (void)
*** 3005,3010 ****
--- 2971,3340 ----
    return err;
  }
  
+ /* Callback for walk_tree, check that all elements with address taken are
+    properly noticed as such.  */
+ 
+ static tree
+ verify_addr_expr (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
+ 		  void *data ATTRIBUTE_UNUSED)
+ {
+   if (TREE_CODE (*tp) == ADDR_EXPR)
+     {
+       tree x = TREE_OPERAND (*tp, 0);
+       if (TREE_CODE (x) == ARRAY_REF
+ 	  || TREE_CODE (x) == COMPONENT_REF
+ 	  || TREE_CODE (x) == REALPART_EXPR
+ 	  || TREE_CODE (x) == IMAGPART_EXPR)
+ 	x = TREE_OPERAND (x, 0);
+       if (TREE_CODE (x) == STRING_CST
+ 	  || TREE_CODE (x) == LABEL_DECL
+ 	  || TREE_CODE (x) == FUNCTION_DECL)
+ 	return NULL;
+       if (!TREE_ADDRESSABLE (x))
+         return x;
+     }
+   return NULL;
+ }
+ 
+ /* Verify the STMT, return true if STMT is missformed.
+    Always keep global so it can be called via GDB. 
+ 
+    TODO: Implement type checking.  */
+ bool
+ verify_stmt (tree stmt)
+ {
+   tree addr;
+ 
+   if (!is_gimple_stmt (stmt))
+     {
+       debug_generic_stmt (stmt);
+       error ("Is not valid gimple statement.");
+       return true;
+     }
+   addr = walk_tree (&stmt, verify_addr_expr, NULL, NULL);
+   if (addr)
+     {
+       debug_generic_stmt (addr);
+       error ("Address taken, but ADDRESABLE bit not set");
+       return true;
+     }
+   return false;
+ }
+ 
+ /* Return true when the T can be shared.  */
+ static bool
+ tree_node_shared_p (tree t)
+ {
+   if (TYPE_P (t) || DECL_P (t)
+       || is_gimple_min_invariant (t)
+       || TREE_CODE (t) == SSA_NAME)
+     return true;
+   if ((TREE_CODE (t) == ARRAY_REF
+        || TREE_CODE (t) == COMPONENT_REF)
+       && DECL_P (TREE_OPERAND (t, 0))
+       && is_gimple_min_invariant (TREE_OPERAND (t, 1)))
+     return true;
+   if ((TREE_CODE (t) == REALPART_EXPR
+        || TREE_CODE (t) == INDIRECT_REF
+        || TREE_CODE (t) == IMAGPART_EXPR)
+       && is_gimple_min_invariant (TREE_OPERAND (t, 0)))
+     return true;
+   return false;
+ }
+ 
+ /* Called via walk_trees.  Verify tree sharing.  */
+ static tree
+ verify_node_sharing (tree * tp, int *walk_subtrees, void *data)
+ {
+   htab_t htab = (htab_t) data;
+   void **slot;
+ 
+   if (tree_node_shared_p (*tp))
+     {
+       *walk_subtrees = false;
+       return NULL;
+     }
+   slot = htab_find_slot (htab, *tp, INSERT);
+   if (*slot)
+     return *slot;
+   *slot = *tp;
+   return NULL;
+ }
+ 
+ 
+ /* Verify GIMPLE stmt chain.  */
+ void
+ verify_stmts (void)
+ {
+   basic_block bb;
+   block_stmt_iterator bsi;
+   bool err = false;
+   htab_t htab;
+   tree addr;
+ 
+   htab = htab_create (37, htab_hash_pointer, htab_eq_pointer, NULL);
+ 
+   FOR_EACH_BB (bb)
+     {
+       tree phi;
+       int i;
+ 
+       phi = phi_nodes (bb);
+       for (; phi; phi = TREE_CHAIN (phi))
+ 	{
+ 	  int phi_num_args = PHI_NUM_ARGS (phi);
+ 
+ 	  for (i = 0; i < phi_num_args; i++)
+ 	    {
+ 	      tree t = PHI_ARG_DEF (phi, i);
+ 	      tree addr;
+ 
+ 	      /* Addressable variables do have SSA_NAMEs but they
+ 	         are not considered gimple values.  */
+ 	      if (TREE_CODE (t) != SSA_NAME
+ 		  && TREE_CODE (t) != FUNCTION_DECL
+ 		  && !is_gimple_val (t))
+ 		{
+ 		  debug_generic_stmt (phi);
+ 		  debug_generic_stmt (t);
+ 		  error ("PHI def is not GIMPLE value");
+ 		  err |= true;
+ 		}
+ 	      addr = walk_tree (&t, verify_addr_expr, NULL, NULL);
+ 	      if (addr)
+ 		{
+ 		  debug_generic_stmt (addr);
+ 		  error ("Address taken, but ADDRESABLE bit not set");
+ 		  err |= true;
+ 		}
+ 	      addr = walk_tree (&t, verify_node_sharing, htab, NULL);
+ 	      if (addr)
+ 		{
+ 		  debug_generic_stmt (phi);
+ 		  debug_generic_stmt (addr);
+ 		  error ("Wrong sharing of tree nodes");
+ 		  err |= true;
+ 		}
+ 	    }
+ 	}
+       for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ 	{
+ 	  tree stmt = bsi_stmt (bsi);
+ 	  err |= verify_stmt (stmt);
+ 	  addr = walk_tree (&stmt, verify_node_sharing, htab, NULL);
+ 	  if (addr)
+ 	    {
+ 	      debug_generic_stmt (stmt);
+ 	      debug_generic_stmt (addr);
+ 	      error ("Wrong sharing of tree nodes");
+ 	      err |= true;
+ 	    }
+ 	}
+     }
+   if (err)
+     internal_error ("verify_stmts failed.");
+   htab_delete (htab);
+ }
+ 
+ /* Used by verify_ssa.  Do sanity checking on OP defined by SSA in block BB.  */
+ static bool
+ verify_def (basic_block bb, basic_block * definition_block, tree op,
+     	    tree stmt)
+ {
+   bool err = false;
+   if (definition_block[SSA_NAME_VERSION (op)])
+     {
+       debug_generic_stmt (stmt);
+       debug_generic_stmt (op);
+       error ("SSA_NAME set in BB %i and %i",
+ 	     definition_block[SSA_NAME_VERSION (op)]->index, bb->index);
+       err = 1;
+     }
+   definition_block[SSA_NAME_VERSION (op)] = bb;
+   if (SSA_NAME_DEF_STMT (op) != stmt)
+     {
+       debug_generic_stmt (stmt);
+       error ("SSA_NAME_DEF_STMT wrong");
+       err = 1;
+     }
+   return err;
+ }
+ 
+ /* Used by verify_ssa.  Do sanity checking on OP used by SSA in block BB.  */
+ static bool
+ verify_use (basic_block bb, basic_block * definition_block, tree op,
+ 	    tree stmt, dominance_info idom, bool abnormal)
+ {
+   basic_block dbb = definition_block [SSA_NAME_VERSION (op)];
+   bool err = false;
+ 
+   if (IS_EMPTY_STMT (SSA_NAME_DEF_STMT (op)))
+     ;
+   else if (!dbb)
+     {
+       debug_generic_stmt (stmt);
+       debug_generic_stmt (op);
+       error ("Definition is missing");
+       err = 1;
+     }
+   else if (bb != dbb && !dominated_by_p (idom, bb, dbb))
+     {
+       debug_generic_stmt (stmt);
+       debug_generic_stmt (op);
+       error ("Definition in bb %i does not dominate use in bb %i",
+ 	     dbb->index, bb->index);
+       err = 1;
+     }
+   if (!SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op) && abnormal)
+     {
+       debug_generic_stmt (stmt);
+       error ("SSA_NAME_OCCURS_IN_ABNORMAL_PHI shall be set");
+       err = 1;
+     }
+   return err;
+ }
+ /* Verify common invariants about SSA graph.
+    TODO: verify the variable annotations.  */
+ void
+ verify_ssa (void)
+ {
+   int err = 0;
+   basic_block bb;
+   dominance_info idom;
+   basic_block *definition_block = xcalloc (highest_ssa_version,
+ 		  			   sizeof (basic_block));
+ 
+   idom = calculate_dominance_info (CDI_DOMINATORS);
+   FOR_EACH_BB (bb)
+   {
+     tree phi;
+     block_stmt_iterator bsi;
+ 
+     phi = phi_nodes (bb);
+     for (; phi; phi = TREE_CHAIN (phi))
+       err |= verify_def (bb, definition_block, PHI_RESULT (phi),
+ 	  		 phi);
+     for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+       {
+ 	tree stmt = bsi_stmt (bsi);
+ 	unsigned int j;
+ 	varray_type vdefs;
+ 	varray_type defs;
+ 
+ 	get_stmt_operands (stmt);
+ 	vdefs = vdef_ops (stmt_ann (stmt));
+ 
+ 	for (j = 0; vdefs && j < VARRAY_ACTIVE_SIZE (vdefs); j++)
+ 	  {
+ 	    tree op = VDEF_RESULT (VARRAY_TREE (vdefs, j));
+ 	    err |= verify_def (bb, definition_block, op, stmt);
+ 	  }
+ 	defs = def_ops (stmt_ann (stmt));
+ 	
+ 	for (j = 0; defs && j < VARRAY_ACTIVE_SIZE (defs); j++)
+ 	  {
+             tree op = *VARRAY_TREE_PTR (defs, j);
+ 	    err |= verify_def (bb, definition_block, op, stmt);
+ 	  }
+       }
+   }
+   FOR_EACH_BB (bb)
+   {
+     edge e;
+     tree phi;
+     block_stmt_iterator bsi;
+     int i;
+ 
+     for (e = bb->pred; e; e = e->pred_next)
+       {
+ 	if (e->aux)
+ 	  {
+ 	    error ("Aux pointer initialized for edge %d->%d\n", e->src->index,
+ 		   e->dest->index);
+ 	    err = 1;
+ 	  }
+       }
+     phi = phi_nodes (bb);
+     for (; phi; phi = TREE_CHAIN (phi))
+       {
+ 	int phi_num_args = PHI_NUM_ARGS (phi);
+ 	for (e = bb->pred; e; e = e->pred_next)
+ 	  e->aux = (void *) 1;
+ 	for (i = 0; i < phi_num_args; i++)
+ 	  {
+ 	    tree op = PHI_ARG_DEF (phi, i);
+ 
+ 	    e = PHI_ARG_EDGE (phi, i);
+ 	    if (!is_gimple_min_invariant (op))
+ 	      err |= verify_use (e->src, definition_block, op, phi, idom,
+ 			         e->flags & EDGE_ABNORMAL);
+ 	    if (e->dest != bb)
+ 	      {
+ 		error ("Phi node for edge %d->%d in %d\n", e->src->index,
+ 		       e->dest->index, bb->index);
+ 		err = 1;
+ 	      }
+ 	    if (e->aux == (void *) 0)
+ 	      {
+ 		error ("Phi node for dead edge %d->%d\n", e->src->index,
+ 		       e->dest->index);
+ 		err = 1;
+ 	      }
+ 	    if (e->aux == (void *) 2)
+ 	      {
+ 		error ("Phi node duplicated for edge %d->%d\n", e->src->index,
+ 		       e->dest->index);
+ 		err = 1;
+ 	      }
+ 	    e->aux = (void *) 2;
+ 
+ 	  }
+ 	for (e = bb->pred; e; e = e->pred_next)
+ 	  {
+ 	    if (e->aux != (void *) 2)
+ 	      {
+ 		error ("Edge %d->%d miss phi node entry\n", e->src->index,
+ 		       e->dest->index);
+ 		err = 1;
+ 	      }
+ 	    e->aux = (void *) 0;
+ 	  }
+       }
+ 
+     for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+       {
+ 	tree stmt = bsi_stmt (bsi);
+ 	unsigned int j;
+ 	varray_type vuses;
+ 	varray_type uses;
+ 
+ 	get_stmt_operands (stmt);
+ 	vuses = vuse_ops (stmt_ann (stmt));
+ 
+ 	/* For each VDEF on the original statement, we want to create a
+ 	   VUSE of the VDEF result on the new statement.  */
+ 	for (j = 0; vuses && j < VARRAY_ACTIVE_SIZE (vuses); j++)
+ 	  {
+             tree op = VARRAY_TREE (vuses, j);
+ 
+ 	    err |= verify_use (bb, definition_block, op, stmt, idom, false);
+ 	  }
+ 	uses = use_ops (stmt_ann (stmt));
+ 	
+ 	for (j = 0; uses && j < VARRAY_ACTIVE_SIZE (uses); j++)
+ 	  {
+             tree op = *VARRAY_TREE_PTR (uses, j);
+ 
+ 	    err |= verify_use (bb, definition_block, op, stmt, idom, false);
+ 	  }
+       }
+   }
+ 
+   free_dominance_info (idom);
+   free (definition_block);
+   if (err)
+     internal_error ("verify_ssa failed.");
+ }
  
  /* Split BB into entry part and rest; if REDIRECT_LATCH, redirect edges
     marked as latch into entry part, analogically for REDIRECT_NONLATCH.
Index: tree-dfa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-dfa.c,v
retrieving revision 1.1.4.181
diff -c -3 -p -r1.1.4.181 tree-dfa.c
*** tree-dfa.c	19 Nov 2003 20:10:00 -0000	1.1.4.181
--- tree-dfa.c	20 Nov 2003 01:21:07 -0000
*************** get_expr_operands (tree stmt, tree *expr
*** 467,473 ****
        get_expr_operands (stmt, &TREE_OPERAND (expr, 0), opf_none, prev_vops);
  
        for (op = TREE_OPERAND (expr, 1); op; op = TREE_CHAIN (op))
! 	add_stmt_operand (&TREE_VALUE (op), stmt, opf_none, prev_vops);
  
        if (num_call_clobbered_vars > 0)
  	{
--- 467,473 ----
        get_expr_operands (stmt, &TREE_OPERAND (expr, 0), opf_none, prev_vops);
  
        for (op = TREE_OPERAND (expr, 1); op; op = TREE_CHAIN (op))
!         get_expr_operands (stmt, &TREE_VALUE (op), opf_none, prev_vops);
  
        if (num_call_clobbered_vars > 0)
  	{
Index: tree-flow.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-flow.h,v
retrieving revision 1.1.4.156
diff -c -3 -p -r1.1.4.156 tree-flow.h
*** tree-flow.h	19 Nov 2003 20:10:01 -0000	1.1.4.156
--- tree-flow.h	20 Nov 2003 01:21:07 -0000
*************** extern void bsi_commit_edge_inserts (boo
*** 443,448 ****
--- 443,451 ----
  extern void bsi_insert_on_edge_immediate (edge, tree);
  extern void notice_special_calls (tree);
  extern void clear_special_calls (void);
+ extern bool verify_stmt (tree);
+ extern void verify_stmts (void);
+ extern void verify_ssa (void);
  
  /* In tree-pretty-print.c.  */
  extern void dump_generic_bb (FILE *, basic_block, int, int);
Index: tree-inline.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-inline.h,v
retrieving revision 1.4.2.4
diff -c -3 -p -r1.4.2.4 tree-inline.h
*** tree-inline.h	25 Oct 2003 19:42:52 -0000	1.4.2.4
--- tree-inline.h	20 Nov 2003 01:21:07 -0000
*************** Boston, MA 02111-1307, USA.  */
*** 26,33 ****
  
  void optimize_inline_calls (tree);
  bool tree_inlinable_function_p (tree);
- tree walk_tree (tree*, walk_tree_fn, void*, void*);
- tree walk_tree_without_duplicates (tree*, walk_tree_fn, void*);
  tree copy_tree_r (tree*, int*, void*);
  void clone_body (tree, tree, void*);
  void remap_save_expr (tree*, void*, tree, int*);
--- 26,31 ----
Index: tree-must-alias.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-must-alias.c,v
retrieving revision 1.1.2.8
diff -c -3 -p -r1.1.2.8 tree-must-alias.c
*** tree-must-alias.c	11 Nov 2003 18:04:46 -0000	1.1.2.8
--- tree-must-alias.c	20 Nov 2003 01:21:07 -0000
*************** find_addressable_vars (sbitmap addresses
*** 172,180 ****
--- 172,194 ----
  	    {
  	      tree t = PHI_ARG_DEF (phi, i);
  
+ 	      if (TREE_CODE (t) == NOP_EXPR)
+ 		t = TREE_OPERAND (t, 0);
+ 
+ 	      if (TREE_CODE (t) == PLUS_EXPR)
+ 		t = TREE_OPERAND (t, 0);
+ 
+ 	      if (TREE_CODE (t) == NOP_EXPR)
+ 		t = TREE_OPERAND (t, 0);
+ 
  	      if (TREE_CODE (t) != ADDR_EXPR)
  		continue;
  	      t = TREE_OPERAND (t, 0);
+ 	      if (TREE_CODE (t) == ARRAY_REF
+ 		  || TREE_CODE (t) == COMPONENT_REF
+ 		  || TREE_CODE (t) == REALPART_EXPR
+ 		  || TREE_CODE (t) == IMAGPART_EXPR)
+ 		t = TREE_OPERAND (t, 0);
  	      if (TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL)
  		continue;
  	      SET_BIT (addresses_needed, var_ann (t)->uid);
Index: tree-optimize.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-optimize.c,v
retrieving revision 1.1.4.75
diff -c -3 -p -r1.1.4.75 tree-optimize.c
*** tree-optimize.c	18 Nov 2003 19:02:29 -0000	1.1.4.75
--- tree-optimize.c	20 Nov 2003 01:21:07 -0000
*************** optimize_function_tree (tree fndecl, tre
*** 93,98 ****
--- 93,103 ----
        /* Rewrite the function into SSA form.  Initially, request all
  	 variables to be renamed.  */
        rewrite_into_ssa (fndecl, NULL, TDI_ssa_1);
+ #ifdef ENABLE_CHECKING
+       verify_stmts ();
+       verify_ssa ();
+       verify_flow_info ();
+ #endif
  
        /* Set up VARS_TO_RENAME to allow passes to inform which variables
  	 need to be renamed.  */
*************** optimize_function_tree (tree fndecl, tre
*** 102,125 ****
        if (flag_tree_dom)
  	{
  	  tree_ssa_dominator_thread_jumps (fndecl, TDI_thread_jumps);
  
  	  sbitmap_zero (vars_to_rename);
  	  tree_ssa_dominator_optimize (fndecl, vars_to_rename, TDI_dom_1);
  
  	  /* If the dominator optimizations exposed new variables, we need
  	      to repeat the SSA renaming process for those symbols.  */
  	  if (sbitmap_first_set_bit (vars_to_rename) >= 0)
  	    rewrite_into_ssa (fndecl, vars_to_rename, TDI_ssa_2);
  	}
  
        /* Do a first DCE pass prior to must-alias.  This pass will remove
  	 dead pointer assignments taking the address of local variables.  */
        if (flag_tree_dce)
  	tree_ssa_dce (fndecl, TDI_dce_1);
  
! #if 0
!       /* Eliminate tail recursion calls.  */
!       tree_optimize_tail_calls (false, TDI_tail1);
  #endif
  
        /* The must-alias pass removes the aliasing and addressability bits
--- 107,144 ----
        if (flag_tree_dom)
  	{
  	  tree_ssa_dominator_thread_jumps (fndecl, TDI_thread_jumps);
+ #ifdef ENABLE_CHECKING
+ 	  verify_stmts ();
+ 	  verify_flow_info ();
+ #endif
  
  	  sbitmap_zero (vars_to_rename);
  	  tree_ssa_dominator_optimize (fndecl, vars_to_rename, TDI_dom_1);
+ #ifdef ENABLE_CHECKING
+ 	  verify_stmts ();
+ 	  verify_flow_info ();
+ #endif
  
  	  /* If the dominator optimizations exposed new variables, we need
  	      to repeat the SSA renaming process for those symbols.  */
  	  if (sbitmap_first_set_bit (vars_to_rename) >= 0)
  	    rewrite_into_ssa (fndecl, vars_to_rename, TDI_ssa_2);
  	}
+ #ifdef ENABLE_CHECKING
+       verify_stmts ();
+       verify_ssa ();
+       verify_flow_info ();
+ #endif
  
        /* Do a first DCE pass prior to must-alias.  This pass will remove
  	 dead pointer assignments taking the address of local variables.  */
        if (flag_tree_dce)
  	tree_ssa_dce (fndecl, TDI_dce_1);
  
! #ifdef ENABLE_CHECKING
!       verify_stmts ();
!       verify_ssa ();
!       verify_flow_info ();
  #endif
  
        /* The must-alias pass removes the aliasing and addressability bits
*************** optimize_function_tree (tree fndecl, tre
*** 133,138 ****
--- 152,171 ----
  	  if (sbitmap_first_set_bit (vars_to_rename) >= 0)
  	    rewrite_into_ssa (fndecl, vars_to_rename, TDI_ssa_3);
  	}
+ #ifdef ENABLE_CHECKING
+       verify_stmts ();
+       verify_ssa ();
+       verify_flow_info ();
+ #endif
+ 
+       /* Eliminate tail recursion calls and discover sibling calls.  */
+       tree_optimize_tail_calls ();
+ 
+ #ifdef ENABLE_CHECKING
+       verify_stmts ();
+       verify_ssa ();
+       verify_flow_info ();
+ #endif
  
        /* Run SCCP (Sparse Conditional Constant Propagation).  */
        if (flag_tree_ccp)
*************** optimize_function_tree (tree fndecl, tre
*** 144,153 ****
  	  if (sbitmap_first_set_bit (vars_to_rename) >= 0)
  	    rewrite_into_ssa (fndecl, vars_to_rename, TDI_ssa_4);
  	}
  
        /* Run SSA-PRE (Partial Redundancy Elimination).  */
!       if (flag_tree_pre)
  	tree_perform_ssapre (fndecl, TDI_pre);
  
        /* Perform a second pass of dominator optimizations.  */
        if (flag_tree_dom)
--- 177,196 ----
  	  if (sbitmap_first_set_bit (vars_to_rename) >= 0)
  	    rewrite_into_ssa (fndecl, vars_to_rename, TDI_ssa_4);
  	}
+ #ifdef ENABLE_CHECKING
+       verify_stmts ();
+       verify_ssa ();
+       verify_flow_info ();
+ #endif
  
        /* Run SSA-PRE (Partial Redundancy Elimination).  */
!       if (flag_tree_pre && 0)
  	tree_perform_ssapre (fndecl, TDI_pre);
+ #ifdef ENABLE_CHECKING
+       verify_stmts ();
+       verify_ssa ();
+       verify_flow_info ();
+ #endif
  
        /* Perform a second pass of dominator optimizations.  */
        if (flag_tree_dom)
Index: tree-ssa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa.c,v
retrieving revision 1.1.4.155
diff -c -3 -p -r1.1.4.155 tree-ssa.c
*** tree-ssa.c	19 Nov 2003 20:10:02 -0000	1.1.4.155
--- tree-ssa.c	20 Nov 2003 01:21:07 -0000
*************** rewrite_out_of_ssa (tree fndecl, enum tr
*** 2478,2483 ****
--- 2478,2486 ----
    if (dump_file && (dump_flags & TDF_DETAILS))
      dump_tree_cfg (dump_file, dump_flags & ~TDF_DETAILS);
  
+ #ifdef ENABLE_CHECKING
+   verify_stmts ();
+ #endif
    /* Do some cleanups which reduce the amount of data the
       tree->rtl expanders deal with.  */
    cfg_remove_useless_stmts ();
*************** rewrite_out_of_ssa (tree fndecl, enum tr
*** 2491,2496 ****
--- 2494,2502 ----
        dump_function_to_file (fndecl, dump_file, dump_flags & ~TDF_VOPS);
        dump_end (phase, dump_file);
      }
+ #ifdef ENABLE_CHECKING
+   verify_stmts ();
+ #endif
  
    /* Flush out flow graph and SSA data.  */
    delete_tree_ssa (fndecl);
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.342.2.133
diff -c -3 -p -r1.342.2.133 tree.h
*** tree.h	19 Nov 2003 20:10:03 -0000	1.342.2.133
--- tree.h	20 Nov 2003 01:21:08 -0000
*************** extern void dwarf2out_return_reg (const 
*** 3525,3530 ****
--- 3525,3532 ----
  /* The type of a callback function for walking over tree structure.  */
  
  typedef tree (*walk_tree_fn) (tree *, int *, void *);
+ tree walk_tree (tree*, walk_tree_fn, void*, void*);
+ tree walk_tree_without_duplicates (tree*, walk_tree_fn, void*);
  
  /* In tree-dump.c */
  


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