[patch] for PR 29902

Zdenek Dvorak rakdver@atrey.karlin.mff.cuni.cz
Mon Nov 20 16:25:00 GMT 2006


Hello,

unrolling uses expressions that describe the number of iterations of the
loop.  These expressions are derived by scalar evolution analysis, and
they may contain ssa names that appear on abnormal edges.  Using these
as the bounds of the unrolled loop may prolong their life ranges, make
them overlap, and consequently ICE in out-of-ssa.

This patch fixes the problem by preventing us from unrolling the loop
when abnormal ssa names appear in one of the expressions.

Another solution would be to copy the values of the abnormal ssa names
to "normal" ssa names just after their definitions, and replace them in
the expressions.  I did not choose this way, since this is more
complicated, and the problem apparently is not too common (given the
lack of ICEs due to this bug so far).  Also, hopefully we should be able
to make exception edges redirectable soon, which would decrease the
amount of abnormal edges dramatically.

Bootstrapped & regtested on i686, with -fprefetch-loop-arrays
-march=athlon.  Unless someone comments on this patch till tomorrow,
I will commit it then.

Zdenek

	PR tree-optimization/29902
	* tree-ssa-loop-manip.c (can_unroll_loop_p): Return false if
	any involved ssa name appears in abnormal phi node.

	* g++.dg/tree-ssa/pr29902.C: New test.

Index: tree-ssa-loop-manip.c
===================================================================
*** tree-ssa-loop-manip.c	(revision 119009)
--- tree-ssa-loop-manip.c	(working copy)
*************** can_unroll_loop_p (struct loop *loop, un
*** 651,657 ****
      return false;
  
    if (!number_of_iterations_exit (loop, exit, niter, false)
!       || niter->cmp == ERROR_MARK)
      return false;
  
    /* And of course, we must be able to duplicate the loop.  */
--- 651,666 ----
      return false;
  
    if (!number_of_iterations_exit (loop, exit, niter, false)
!       || niter->cmp == ERROR_MARK
!       /* Scalar evolutions analysis might have copy propagated
! 	 the abnormal ssa names into these expressions, hence
! 	 emiting the computations based on them during loop
! 	 unrolling might create overlapping life ranges for
! 	 them, and failures in out-of-ssa.  */
!       || contains_abnormal_ssa_name_p (niter->may_be_zero)
!       || contains_abnormal_ssa_name_p (niter->control.base)
!       || contains_abnormal_ssa_name_p (niter->control.step)
!       || contains_abnormal_ssa_name_p (niter->bound))
      return false;
  
    /* And of course, we must be able to duplicate the loop.  */
Index: testsuite/g++.dg/tree-ssa/pr29902.C
===================================================================
*** testsuite/g++.dg/tree-ssa/pr29902.C	(revision 0)
--- testsuite/g++.dg/tree-ssa/pr29902.C	(revision 0)
***************
*** 0 ****
--- 1,19 ----
+ /* { dg-do compile { target i?86-*-* } } */
+ /* { dg-options "-O1 -fprefetch-loop-arrays -march=athlon" } */
+ 
+ int length1();
+ int g(int);
+ void f(int capacity_, char *old_storage)
+ {
+   try {
+       length1();
+       int old_capacity = capacity_;
+       capacity_ *= 2;
+       g(capacity_);
+       for (int i = 1; i < old_capacity; i++)
+ 	old_storage[i] = old_storage[i - 1];
+   } catch (...) {
+       for (int i = 1; i < capacity_; i++){old_storage[i] = 0;}
+   }
+ }
+ 



More information about the Gcc-patches mailing list