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] Virtual operands in tree-tailcall


Hello,

while playing with new loop invariant motion pass, I have noticed
a problem with the tail recursion elimination -- we just forget the
vdefs of the call.  This causes problems in cases like

int n;

void bla (void)
{
  int p = n;
  n++;
  if (!p)
    bla ();
}

where the missing vdef enables us to hoist p = n assignment out of the
loop.  This patch turns the vdefs into loop phi nodes, thus fixing the
problem.

Ok if it passes regtesting?

Zdenek

	* tree-tailcall.c (eliminate_tail_call): Add phi nodes for the call
	vdefs.

Index: tree-tailcall.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-tailcall.c,v
retrieving revision 1.1.2.12
diff -c -3 -p -r1.1.2.12 tree-tailcall.c
*** tree-tailcall.c	19 Dec 2003 07:01:36 -0000	1.1.2.12
--- tree-tailcall.c	1 Jan 2004 22:44:51 -0000
*************** static void
*** 249,259 ****
  eliminate_tail_call (struct tailcall *t)
  {
    tree param, stmt, args;
!   basic_block bb;
    edge e;
    tree phi;
  
    stmt = bsi_stmt (t->call_bsi);
    bb = t->call_block;
  
    if (dump_file && (dump_flags & TDF_DETAILS))
--- 249,264 ----
  eliminate_tail_call (struct tailcall *t)
  {
    tree param, stmt, args;
!   basic_block bb, first;
    edge e;
    tree phi;
+   stmt_ann_t ann;
+   vdef_optype vdefs;
+   unsigned i;
  
    stmt = bsi_stmt (t->call_bsi);
+   get_stmt_operands (stmt);
+   ann = stmt_ann (stmt);
    bb = t->call_block;
  
    if (dump_file && (dump_flags & TDF_DETAILS))
*************** eliminate_tail_call (struct tailcall *t)
*** 274,298 ****
      }
    bsi_remove (&t->call_bsi);
  
!   e = redirect_edge_and_branch (t->call_block->succ,
! 				ENTRY_BLOCK_PTR->succ->dest);
    if (!e)
      abort ();
!   /* We expect that each PHI node on first basic block represent an argument.
!      Add proper entries.  */
!   for (phi = phi_nodes (ENTRY_BLOCK_PTR->succ->dest); phi;
!        phi = TREE_CHAIN (phi))
      {
!       for (param = DECL_ARGUMENTS (current_function_decl),
! 	   args = TREE_OPERAND (stmt, 1);
! 	   param;
! 	   param = TREE_CHAIN (param),
! 	   args = TREE_CHAIN (args))
  	if (param == SSA_NAME_VAR (PHI_RESULT (phi)))
  	  break;
!       if (!param)
  	abort ();
        add_phi_arg (&phi, TREE_VALUE (args), e);
      }
  }
  
--- 279,329 ----
      }
    bsi_remove (&t->call_bsi);
  
!   first = ENTRY_BLOCK_PTR->succ->dest;
!   e = redirect_edge_and_branch (t->call_block->succ, first);
    if (!e)
      abort ();
! 
!   /* Add phi node entries for arguments.  */
!   for (param = DECL_ARGUMENTS (current_function_decl),
!        args = TREE_OPERAND (stmt, 1);
!        param;
!        param = TREE_CHAIN (param),
!        args = TREE_CHAIN (args))
      {
!       for (phi = phi_nodes (first); phi; phi = TREE_CHAIN (phi))
  	if (param == SSA_NAME_VAR (PHI_RESULT (phi)))
  	  break;
!       if (!phi)
  	abort ();
        add_phi_arg (&phi, TREE_VALUE (args), e);
+     }
+ 
+   /* Add phi nodes for the call clobbered variables.  */
+   vdefs = VDEF_OPS (ann);
+   for (i = 0; i < NUM_VDEFS (vdefs); i++)
+     {
+       param = SSA_NAME_VAR (VDEF_RESULT (vdefs, i));
+       for (phi = phi_nodes (first); phi; phi = TREE_CHAIN (phi))
+ 	if (param == SSA_NAME_VAR (PHI_RESULT (phi)))
+ 	  break;
+ 
+       if (!phi)
+ 	{
+ 	  tree name = var_ann (param)->default_def;
+ 	  tree new_name = make_ssa_name (param, SSA_NAME_DEF_STMT (name));
+ 
+ 	  var_ann (param)->default_def = new_name;
+ 	  phi = create_phi_node (name, first);
+ 	  SSA_NAME_DEF_STMT (name) = phi;
+ 	  add_phi_arg (&phi, new_name, ENTRY_BLOCK_PTR->succ);
+ 
+ 	  /* For all calls the same set of variables should be clobbered.  */
+ 	  if (first->pred->pred_next->pred_next)
+ 	    abort ();
+ 	}
+ 
+       add_phi_arg (&phi, VDEF_OP (vdefs, i), e);
      }
  }
  


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