SOURCES (GCC_4_1): gcc-pr26435-pr20256.patch (NEW) - additional pa...

pluto pluto at pld-linux.org
Thu May 18 14:16:38 CEST 2006


Author: pluto                        Date: Thu May 18 12:16:38 2006 GMT
Module: SOURCES                       Tag: GCC_4_1
---- Log message:
- additional patches scheduled for post 4.1.1 release.

---- Files affected:
SOURCES:
   gcc-pr26435-pr20256.patch (NONE -> 1.1.2.1)  (NEW)

---- Diffs:

================================================================
Index: SOURCES/gcc-pr26435-pr20256.patch
diff -u /dev/null SOURCES/gcc-pr26435-pr20256.patch:1.1.2.1
--- /dev/null	Thu May 18 14:16:38 2006
+++ SOURCES/gcc-pr26435-pr20256.patch	Thu May 18 14:16:33 2006
@@ -0,0 +1,519 @@
+Index: tree-loop-linear.c
+===================================================================
+*** tree-loop-linear.c	(revision 113884)
+--- tree-loop-linear.c	(working copy)
+***************
+*** 1,5 ****
+  /* Linear Loop transforms
+!    Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+     Contributed by Daniel Berlin <dberlin at dberlin.org>.
+  
+  This file is part of GCC.
+--- 1,5 ----
+  /* Linear Loop transforms
+!    Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+     Contributed by Daniel Berlin <dberlin at dberlin.org>.
+  
+  This file is part of GCC.
+*************** try_interchange_loops (lambda_trans_matr
+*** 243,248 ****
+--- 243,249 ----
+  void
+  linear_transform_loops (struct loops *loops)
+  {
++   bool modified = false;
+    unsigned int i;
+    VEC(tree,heap) *oldivs = NULL;
+    VEC(tree,heap) *invariants = NULL;
+*************** linear_transform_loops (struct loops *lo
+*** 257,263 ****
+        lambda_loopnest before, after;
+        lambda_trans_matrix trans;
+        bool problem = false;
+-       bool need_perfect_nest = false;
+        /* If it's not a loop nest, we don't want it.
+           We also don't handle sibling loops properly, 
+           which are loops of the following form:
+--- 258,263 ----
+*************** linear_transform_loops (struct loops *lo
+*** 334,345 ****
+  	    fprintf (dump_file, "Can't transform loop, transform is illegal:\n");
+  	  continue;
+  	}
+!       if (!perfect_nest_p (loop_nest))
+! 	need_perfect_nest = true;
+!       before = gcc_loopnest_to_lambda_loopnest (loops,
+! 						loop_nest, &oldivs, 
+! 						&invariants,
+! 						need_perfect_nest);
+        if (!before)
+  	continue;
+              
+--- 334,342 ----
+  	    fprintf (dump_file, "Can't transform loop, transform is illegal:\n");
+  	  continue;
+  	}
+! 
+!       before = gcc_loopnest_to_lambda_loopnest (loops, loop_nest, &oldivs, 
+! 						&invariants);
+        if (!before)
+  	continue;
+              
+*************** linear_transform_loops (struct loops *lo
+*** 357,362 ****
+--- 354,361 ----
+  	}
+        lambda_loopnest_to_gcc_loopnest (loop_nest, oldivs, invariants,
+  				       after, trans);
++       modified = true;
++ 
+        if (dump_file)
+  	fprintf (dump_file, "Successfully transformed loop.\n");
+        free_dependence_relations (dependence_relations);
+*************** linear_transform_loops (struct loops *lo
+*** 365,369 ****
+    VEC_free (tree, heap, oldivs);
+    VEC_free (tree, heap, invariants);
+    scev_reset ();
+!   rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa_full_phi);
+  }
+--- 364,370 ----
+    VEC_free (tree, heap, oldivs);
+    VEC_free (tree, heap, invariants);
+    scev_reset ();
+! 
+!   if (modified)
+!     rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa_full_phi);
+  }
+Index: lambda.h
+===================================================================
+*** lambda.h	(revision 113884)
+--- lambda.h	(working copy)
+***************
+*** 1,5 ****
+  /* Lambda matrix and vector interface.
+!    Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+     Contributed by Daniel Berlin <dberlin at dberlin.org>
+  
+  This file is part of GCC.
+--- 1,5 ----
+  /* Lambda matrix and vector interface.
+!    Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+     Contributed by Daniel Berlin <dberlin at dberlin.org>
+  
+  This file is part of GCC.
+*************** void print_lambda_body_vector (FILE *, l
+*** 200,207 ****
+  lambda_loopnest gcc_loopnest_to_lambda_loopnest (struct loops *,
+  						 struct loop *,
+  						 VEC(tree,heap) **,
+! 						 VEC(tree,heap) **,
+! 						 bool);
+  void lambda_loopnest_to_gcc_loopnest (struct loop *,
+  				      VEC(tree,heap) *, VEC(tree,heap) *,
+  				      lambda_loopnest, lambda_trans_matrix);
+--- 200,206 ----
+  lambda_loopnest gcc_loopnest_to_lambda_loopnest (struct loops *,
+  						 struct loop *,
+  						 VEC(tree,heap) **,
+! 						 VEC(tree,heap) **);
+  void lambda_loopnest_to_gcc_loopnest (struct loop *,
+  				      VEC(tree,heap) *, VEC(tree,heap) *,
+  				      lambda_loopnest, lambda_trans_matrix);
+Index: lambda-code.c
+===================================================================
+*** lambda-code.c	(revision 113884)
+--- lambda-code.c	(working copy)
+***************
+*** 1,5 ****
+  /*  Loop transformation code generation
+!     Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+      Contributed by Daniel Berlin <dberlin at dberlin.org>
+  
+      This file is part of GCC.
+--- 1,5 ----
+  /*  Loop transformation code generation
+!     Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+      Contributed by Daniel Berlin <dberlin at dberlin.org>
+  
+      This file is part of GCC.
+*************** static lambda_lattice lambda_lattice_new
+*** 149,154 ****
+--- 149,155 ----
+  static lambda_lattice lambda_lattice_compute_base (lambda_loopnest);
+  
+  static tree find_induction_var_from_exit_cond (struct loop *);
++ static bool can_convert_to_perfect_nest (struct loop *);
+  
+  /* Create a new lambda body vector.  */
+  
+*************** DEF_VEC_ALLOC_P(lambda_loop,heap);
+*** 1498,1511 ****
+  
+  lambda_loopnest
+  gcc_loopnest_to_lambda_loopnest (struct loops *currloops,
+! 				 struct loop * loop_nest,
+  				 VEC(tree,heap) **inductionvars,
+! 				 VEC(tree,heap) **invariants,
+! 				 bool need_perfect_nest)
+  {
+    lambda_loopnest ret = NULL;
+!   struct loop *temp;
+!   int depth = 0;
+    size_t i;
+    VEC(lambda_loop,heap) *loops = NULL;
+    VEC(tree,heap) *uboundvars = NULL;
+--- 1499,1511 ----
+  
+  lambda_loopnest
+  gcc_loopnest_to_lambda_loopnest (struct loops *currloops,
+! 				 struct loop *loop_nest,
+  				 VEC(tree,heap) **inductionvars,
+! 				 VEC(tree,heap) **invariants)
+  {
+    lambda_loopnest ret = NULL;
+!   struct loop *temp = loop_nest;
+!   int depth = depth_of_nest (loop_nest);
+    size_t i;
+    VEC(lambda_loop,heap) *loops = NULL;
+    VEC(tree,heap) *uboundvars = NULL;
+*************** gcc_loopnest_to_lambda_loopnest (struct 
+*** 1513,1521 ****
+    VEC(int,heap) *steps = NULL;
+    lambda_loop newloop;
+    tree inductionvar = NULL;
+!   
+!   depth = depth_of_nest (loop_nest);
+!   temp = loop_nest;
+    while (temp)
+      {
+        newloop = gcc_loop_to_lambda_loop (temp, depth, invariants,
+--- 1513,1523 ----
+    VEC(int,heap) *steps = NULL;
+    lambda_loop newloop;
+    tree inductionvar = NULL;
+!   bool perfect_nest = perfect_nest_p (loop_nest);
+! 
+!   if (!perfect_nest && !can_convert_to_perfect_nest (loop_nest))
+!     goto fail;
+! 
+    while (temp)
+      {
+        newloop = gcc_loop_to_lambda_loop (temp, depth, invariants,
+*************** gcc_loopnest_to_lambda_loopnest (struct 
+*** 1523,1534 ****
+  					 &lboundvars, &uboundvars,
+  					 &steps);
+        if (!newloop)
+! 	return NULL;
+        VEC_safe_push (tree, heap, *inductionvars, inductionvar);
+        VEC_safe_push (lambda_loop, heap, loops, newloop);
+        temp = temp->inner;
+      }
+!   if (need_perfect_nest)
+      {
+        if (!perfect_nestify (currloops, loop_nest, 
+  			    lboundvars, uboundvars, steps, *inductionvars))
+--- 1525,1538 ----
+  					 &lboundvars, &uboundvars,
+  					 &steps);
+        if (!newloop)
+! 	goto fail;
+! 
+        VEC_safe_push (tree, heap, *inductionvars, inductionvar);
+        VEC_safe_push (lambda_loop, heap, loops, newloop);
+        temp = temp->inner;
+      }
+! 
+!   if (!perfect_nest)
+      {
+        if (!perfect_nestify (currloops, loop_nest, 
+  			    lboundvars, uboundvars, steps, *inductionvars))
+*************** gcc_loopnest_to_lambda_loopnest (struct 
+*** 1542,1550 ****
+--- 1546,1557 ----
+  	fprintf (dump_file,
+  		 "Successfully converted loop nest to perfect loop nest.\n");
+      }
++ 
+    ret = lambda_loopnest_new (depth, 2 * depth);
++ 
+    for (i = 0; VEC_iterate (lambda_loop, loops, i, newloop); i++)
+      LN_LOOPS (ret)[i] = newloop;
++ 
+   fail:
+    VEC_free (lambda_loop, heap, loops);
+    VEC_free (tree, heap, uboundvars);
+*************** replace_uses_equiv_to_x_with_y (struct l
+*** 2156,2168 ****
+      {
+        tree use = USE_FROM_PTR (use_p);
+        tree step = NULL_TREE;
+!       tree access_fn = NULL_TREE;
+!       
+!       
+!       access_fn = instantiate_parameters
+! 	(loop, analyze_scalar_evolution (loop, use));
+!       if (access_fn != NULL_TREE && access_fn != chrec_dont_know)
+! 	step = evolution_part_in_loop_num (access_fn, loop->num);
+        if ((step && step != chrec_dont_know 
+  	   && TREE_CODE (step) == INTEGER_CST
+  	   && int_cst_value (step) == xstep)
+--- 2163,2174 ----
+      {
+        tree use = USE_FROM_PTR (use_p);
+        tree step = NULL_TREE;
+!       tree scev = instantiate_parameters (loop,
+! 					  analyze_scalar_evolution (loop, use));
+! 
+!       if (scev != NULL_TREE && scev != chrec_dont_know)
+! 	step = evolution_part_in_loop_num (scev, loop->num);
+! 
+        if ((step && step != chrec_dont_know 
+  	   && TREE_CODE (step) == INTEGER_CST
+  	   && int_cst_value (step) == xstep)
+*************** replace_uses_equiv_to_x_with_y (struct l
+*** 2171,2192 ****
+      }
+  }
+  
+- /* Return TRUE if STMT uses tree OP in it's uses.  */
+- 
+- static bool
+- stmt_uses_op (tree stmt, tree op)
+- {
+-   ssa_op_iter iter;
+-   tree use;
+- 
+-   FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
+-     {
+-       if (use == op)
+- 	return true;
+-     }
+-   return false;
+- }
+- 
+  /* Return true if STMT is an exit PHI for LOOP */
+  
+  static bool
+--- 2177,2182 ----
+*************** can_put_in_inner_loop (struct loop *inne
+*** 2236,2250 ****
+    
+  }
+  
+  
+! /* Return TRUE if LOOP is an imperfect nest that we can convert to a perfect
+!    one.  LOOPIVS is a vector of induction variables, one per loop.  
+!    ATM, we only handle imperfect nests of depth 2, where all of the statements
+!    occur after the inner loop.  */
+  
+  static bool
+! can_convert_to_perfect_nest (struct loop *loop,
+! 			     VEC(tree,heap) *loopivs)
+  {
+    basic_block *bbs;
+    tree exit_condition, phi;
+--- 2226,2264 ----
+    
+  }
+  
++ /* Return true if STMT can be put *after* the inner loop of LOOP.  */
++ 
++ static bool
++ can_put_after_inner_loop (struct loop *loop, tree stmt)
++ {
++   imm_use_iterator imm_iter;
++   use_operand_p use_p;
++ 
++   if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
++     return false;
++   
++   FOR_EACH_IMM_USE_FAST (use_p, imm_iter, TREE_OPERAND (stmt, 0))
++     {
++       if (!exit_phi_for_loop_p (loop, USE_STMT (use_p)))
++ 	{
++ 	  basic_block immbb = bb_for_stmt (USE_STMT (use_p));
++ 	  
++ 	  if (!dominated_by_p (CDI_DOMINATORS,
++ 			       immbb,
++ 			       loop->inner->header)
++ 	      && !can_put_in_inner_loop (loop->inner, stmt))
++ 	    return false;
++ 	}
++     }
++   return true;
++ }
+  
+! /* Return TRUE if LOOP is an imperfect nest that we can convert to a
+!    perfect one.  At the moment, we only handle imperfect nests of
+!    depth 2, where all of the statements occur after the inner loop.  */
+  
+  static bool
+! can_convert_to_perfect_nest (struct loop *loop)
+  {
+    basic_block *bbs;
+    tree exit_condition, phi;
+*************** can_convert_to_perfect_nest (struct loop
+*** 2264,2282 ****
+  	{
+  	  for (bsi = bsi_start (bbs[i]); !bsi_end_p (bsi); bsi_next (&bsi))
+  	    { 
+- 	      size_t j;
+  	      tree stmt = bsi_stmt (bsi);
+! 	      tree iv;
+! 	      
+  	      if (stmt == exit_condition
+  		  || not_interesting_stmt (stmt)
+  		  || stmt_is_bumper_for_loop (loop, stmt))
+  		continue;
+! 	      /* If the statement uses inner loop ivs, we == screwed.  */
+! 	      for (j = 1; VEC_iterate (tree, loopivs, j, iv); j++)
+! 		if (stmt_uses_op (stmt, iv))
+! 		  goto fail;
+! 	      
+  	      /* If this is a simple operation like a cast that is invariant
+  		 in the inner loop, only used there, and we can place it
+  		 there, then it's not going to hurt us.
+--- 2278,2290 ----
+  	{
+  	  for (bsi = bsi_start (bbs[i]); !bsi_end_p (bsi); bsi_next (&bsi))
+  	    { 
+  	      tree stmt = bsi_stmt (bsi);
+! 
+  	      if (stmt == exit_condition
+  		  || not_interesting_stmt (stmt)
+  		  || stmt_is_bumper_for_loop (loop, stmt))
+  		continue;
+! 
+  	      /* If this is a simple operation like a cast that is invariant
+  		 in the inner loop, only used there, and we can place it
+  		 there, then it's not going to hurt us.
+*************** can_convert_to_perfect_nest (struct loop
+*** 2286,2295 ****
+  		 theory that we are going to gain a lot more by interchanging
+  		 the loop than we are by leaving some invariant code there for
+  		 some other pass to clean up.  */
+! 	      if (TREE_CODE (stmt) == MODIFY_EXPR
+! 		  && is_gimple_cast (TREE_OPERAND (stmt, 1))
+! 		  && can_put_in_inner_loop (loop->inner, stmt))
+! 		continue;
+  
+  	      /* Otherwise, if the bb of a statement we care about isn't
+  		 dominated by the header of the inner loop, then we can't
+--- 2294,2358 ----
+  		 theory that we are going to gain a lot more by interchanging
+  		 the loop than we are by leaving some invariant code there for
+  		 some other pass to clean up.  */
+! 	      if (TREE_CODE (stmt) == MODIFY_EXPR)
+! 		{
+! 		  use_operand_p use_a, use_b;
+! 		  imm_use_iterator imm_iter;
+! 		  ssa_op_iter op_iter, op_iter1;
+! 		  tree op0 = TREE_OPERAND (stmt, 0);
+! 		  tree scev = instantiate_parameters
+! 		    (loop, analyze_scalar_evolution (loop, op0));
+! 
+! 		  /* If the IV is simple, it can be duplicated.  */
+! 		  if (!automatically_generated_chrec_p (scev))
+! 		    {
+! 		      tree step = evolution_part_in_loop_num (scev, loop->num);
+! 		      if (step && step != chrec_dont_know 
+! 			  && TREE_CODE (step) == INTEGER_CST)
+! 			continue;
+! 		    }
+! 
+! 		  /* The statement should not define a variable used
+! 		     in the inner loop.  */
+! 		  if (TREE_CODE (op0) == SSA_NAME)
+! 		    FOR_EACH_IMM_USE_FAST (use_a, imm_iter, op0)
+! 		      if (bb_for_stmt (USE_STMT (use_a))->loop_father
+! 			  == loop->inner)
+! 			goto fail;
+! 
+! 		  FOR_EACH_SSA_USE_OPERAND (use_a, stmt, op_iter, SSA_OP_USE)
+! 		    {
+! 		      tree node, op = USE_FROM_PTR (use_a);
+! 
+! 		      /* The variables should not be used in both loops.  */
+! 		      FOR_EACH_IMM_USE_FAST (use_b, imm_iter, op)
+! 		      if (bb_for_stmt (USE_STMT (use_b))->loop_father
+! 			  == loop->inner)
+! 			goto fail;
+! 
+! 		      /* The statement should not use the value of a
+! 			 scalar that was modified in the loop.  */
+! 		      node = SSA_NAME_DEF_STMT (op);
+! 		      if (TREE_CODE (node) == PHI_NODE)
+! 			FOR_EACH_PHI_ARG (use_b, node, op_iter1, SSA_OP_USE)
+! 			  {
+! 			    tree arg = USE_FROM_PTR (use_b);
+! 
+! 			    if (TREE_CODE (arg) == SSA_NAME)
+! 			      {
+! 				tree arg_stmt = SSA_NAME_DEF_STMT (arg);
+! 
+! 				if (bb_for_stmt (arg_stmt)->loop_father
+! 				    == loop->inner)
+! 				  goto fail;
+! 			      }
+! 			  }
+! 		    }
+! 
+! 		  if (can_put_in_inner_loop (loop->inner, stmt)
+! 		      || can_put_after_inner_loop (loop, stmt))
+! 		    continue;
+! 		}
+  
+  	      /* Otherwise, if the bb of a statement we care about isn't
+  		 dominated by the header of the inner loop, then we can't
+*************** perfect_nestify (struct loops *loops,
+*** 2379,2392 ****
+    tree stmt;
+    tree oldivvar, ivvar, ivvarinced;
+    VEC(tree,heap) *phis = NULL;
+! 
+!   if (!can_convert_to_perfect_nest (loop, loopivs))
+!     return false;
+! 
+!   /* Create the new loop */
+! 
+    olddest = loop->single_exit->dest;
+!   preheaderbb =  loop_split_edge_with (loop->single_exit, NULL);
+    headerbb = create_empty_bb (EXIT_BLOCK_PTR->prev_bb);
+    
+    /* Push the exit phi nodes that we are moving.  */
+--- 2442,2451 ----
+    tree stmt;
+    tree oldivvar, ivvar, ivvarinced;
+    VEC(tree,heap) *phis = NULL;
+!   
+!   /* Create the new loop.  */
+    olddest = loop->single_exit->dest;
+!   preheaderbb = loop_split_edge_with (loop->single_exit, NULL);
+    headerbb = create_empty_bb (EXIT_BLOCK_PTR->prev_bb);
+    
+    /* Push the exit phi nodes that we are moving.  */
+*************** perfect_nestify (struct loops *loops,
+*** 2552,2561 ****
+  		      continue;
+  		    }
+  		  
+! 		  replace_uses_equiv_to_x_with_y (loop, stmt, 
+! 						  oldivvar,  
+! 						  VEC_index (int, steps, 0),
+! 						  ivvar);
+  		  bsi_move_before (&bsi, &tobsi);
+  		  
+  		  /* If the statement has any virtual operands, they may
+--- 2611,2619 ----
+  		      continue;
+  		    }
+  		  
+! 		  replace_uses_equiv_to_x_with_y 
+! 		    (loop, stmt, oldivvar, VEC_index (int, steps, 0), ivvar);
+! 
+  		  bsi_move_before (&bsi, &tobsi);
+  		  
+  		  /* If the statement has any virtual operands, they may
+
================================================================


More information about the pld-cvs-commit mailing list