patches/gcc/4.3.2/360-fix-expensive-optimize.patch
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Mon May 25 17:22:54 2009 +0000 (2009-05-25)
branchgcc-4.4
changeset 1382 b3b1369752ba
permissions -rw-r--r--
/devel/gcc-4.4:
- TODO: add new item

-------- diffstat follows --------
/devel/gcc-4.4/TODO | 1 1 0 0 +
1 file changed, 1 insertion(+)
     1 PR tree-optimization/32044
     2 
     3 From: rakdver
     4 Date: 2008-12-12 21:32:47 +0100
     5 
     6 * tree-scalar-evolution.h (expression_expensive_p): Declare.
     7 * tree-scalar-evolution.c (expression_expensive_p): New function.
     8 (scev_const_prop): Avoid introducing expensive expressions.
     9 * tree-ssa-loop-ivopts.c (may_eliminate_iv): Ditto.
    10 
    11 * gcc.dg/pr34027-1.c: Change outcome.
    12 * gcc.dg/tree-ssa/pr32044.c: New test.
    13 
    14 cherry picked from svn://gcc.gnu.org/svn/gcc/trunk, rev 142719 and adapted to
    15 apply on gcc 4.3.2
    16 
    17 ------------------------------------------------------------------------
    18 Index: gcc-4.3.2/gcc/tree-scalar-evolution.c
    19 ===================================================================
    20 --- gcc-4.3.2.orig/gcc/tree-scalar-evolution.c	2009-01-28 10:14:37.000000000 +0100
    21 +++ gcc-4.3.2/gcc/tree-scalar-evolution.c	2009-01-28 10:17:50.000000000 +0100
    22 @@ -2716,6 +2716,50 @@
    23    scalar_evolution_info = NULL;
    24  }
    25  
    26 +/* Returns true if the expression EXPR is considered to be too expensive
    27 +   for scev_const_prop.  */
    28 +
    29 +bool
    30 +expression_expensive_p (tree expr)
    31 +{
    32 +  enum tree_code code;
    33 +
    34 +  if (is_gimple_val (expr))
    35 +    return false;
    36 +
    37 +  code = TREE_CODE (expr);
    38 +  if (code == TRUNC_DIV_EXPR
    39 +      || code == CEIL_DIV_EXPR
    40 +      || code == FLOOR_DIV_EXPR
    41 +      || code == ROUND_DIV_EXPR
    42 +      || code == TRUNC_MOD_EXPR
    43 +      || code == CEIL_MOD_EXPR
    44 +      || code == FLOOR_MOD_EXPR
    45 +      || code == ROUND_MOD_EXPR
    46 +      || code == EXACT_DIV_EXPR)
    47 +    {
    48 +      /* Division by power of two is usually cheap, so we allow it.
    49 +	 Forbid anything else.  */
    50 +      if (!integer_pow2p (TREE_OPERAND (expr, 1)))
    51 +	return true;
    52 +    }
    53 +
    54 +  switch (TREE_CODE_CLASS (code))
    55 +    {
    56 +    case tcc_binary:
    57 +    case tcc_comparison:
    58 +      if (expression_expensive_p (TREE_OPERAND (expr, 1)))
    59 +	return true;
    60 +
    61 +      /* Fallthru.  */
    62 +    case tcc_unary:
    63 +      return expression_expensive_p (TREE_OPERAND (expr, 0));
    64 +
    65 +    default:
    66 +      return true;
    67 +    }
    68 +}
    69 +
    70  /* Replace ssa names for that scev can prove they are constant by the
    71     appropriate constants.  Also perform final value replacement in loops,
    72     in case the replacement expressions are cheap.
    73 @@ -2802,12 +2846,6 @@
    74  	continue;
    75  
    76        niter = number_of_latch_executions (loop);
    77 -      /* We used to check here whether the computation of NITER is expensive,
    78 -	 and avoided final value elimination if that is the case.  The problem
    79 -	 is that it is hard to evaluate whether the expression is too
    80 -	 expensive, as we do not know what optimization opportunities the
    81 -	 the elimination of the final value may reveal.  Therefore, we now
    82 -	 eliminate the final values of induction variables unconditionally.  */
    83        if (niter == chrec_dont_know)
    84  	continue;
    85  
    86 @@ -2838,7 +2876,15 @@
    87  	      /* Moving the computation from the loop may prolong life range
    88  		 of some ssa names, which may cause problems if they appear
    89  		 on abnormal edges.  */
    90 -	      || contains_abnormal_ssa_name_p (def))
    91 +	      || contains_abnormal_ssa_name_p (def)
    92 +	      /* Do not emit expensive expressions.  The rationale is that
    93 +		 when someone writes a code like
    94 +
    95 +		 while (n > 45) n -= 45;
    96 +
    97 +		 he probably knows that n is not large, and does not want it
    98 +		 to be turned into n %= 45.  */
    99 +	      || expression_expensive_p (def))
   100  	    continue;
   101  
   102  	  /* Eliminate the PHI node and replace it by a computation outside
   103 Index: gcc-4.3.2/gcc/tree-scalar-evolution.h
   104 ===================================================================
   105 --- gcc-4.3.2.orig/gcc/tree-scalar-evolution.h	2009-01-28 10:22:47.000000000 +0100
   106 +++ gcc-4.3.2/gcc/tree-scalar-evolution.h	2009-01-28 10:23:10.000000000 +0100
   107 @@ -35,6 +35,7 @@
   108  extern void scev_analysis (void);
   109  unsigned int scev_const_prop (void);
   110  
   111 +bool expression_expensive_p (tree);
   112  extern bool simple_iv (struct loop *, tree, tree, affine_iv *, bool);
   113  
   114  /* Returns the loop of the polynomial chrec CHREC.  */
   115 Index: gcc-4.3.2/gcc/testsuite/gcc.dg/pr34027-1.c
   116 ===================================================================
   117 --- gcc-4.3.2.orig/gcc/testsuite/gcc.dg/pr34027-1.c	2009-01-28 10:24:09.000000000 +0100
   118 +++ gcc-4.3.2/gcc/testsuite/gcc.dg/pr34027-1.c	2009-01-28 10:24:43.000000000 +0100
   119 @@ -8,5 +8,9 @@
   120    return ns;
   121  }
   122  
   123 -/* { dg-final { scan-tree-dump "ns % 10000" "optimized" } } */
   124 +/* This test was originally introduced to test that we transform
   125 +   to ns % 10000.  See the discussion of PR 32044 why we do not do
   126 +   that anymore.  */
   127 +/* { dg-final { scan-tree-dump-times "%" 0 "optimized" } } */
   128 +/* { dg-final { scan-tree-dump-times "/" 0 "optimized" } } */
   129  /* { dg-final { cleanup-tree-dump "optimized" } } */
   130 Index: gcc-4.3.2/gcc/testsuite/gcc.dg/tree-ssa/pr32044.c
   131 ===================================================================
   132 --- /dev/null	1970-01-01 00:00:00.000000000 +0000
   133 +++ gcc-4.3.2/gcc/testsuite/gcc.dg/tree-ssa/pr32044.c	2009-01-28 10:25:50.000000000 +0100
   134 @@ -0,0 +1,55 @@
   135 +/* { dg-do compile } */
   136 +/* { dg-options "-O2 -fdump-tree-empty -fdump-tree-final_cleanup" } */
   137 +
   138 +int foo (int n)
   139 +{
   140 +  while (n >= 45)
   141 +    n -= 45;
   142 +
   143 +  return n;
   144 +}
   145 +
   146 +int bar (int n)
   147 +{
   148 +  while (n >= 64)
   149 +    n -= 64;
   150 +
   151 +  return n;
   152 +}
   153 +
   154 +int bla (int n)
   155 +{
   156 +  int i = 0;
   157 +
   158 +  while (n >= 45)
   159 +    {
   160 +      i++;
   161 +      n -= 45;
   162 +    }
   163 +
   164 +  return i;
   165 +}
   166 +
   167 +int baz (int n)
   168 +{
   169 +  int i = 0;
   170 +
   171 +  while (n >= 64)
   172 +    {
   173 +      i++;
   174 +      n -= 64;
   175 +    }
   176 +
   177 +  return i;
   178 +}
   179 +
   180 +/* The loops computing division/modulo by 64 should be eliminated.  */
   181 +/* { dg-final { scan-tree-dump-times "Removing empty loop" 2 "empty" } } */
   182 +
   183 +/* There should be no division/modulo in the final dump (division and modulo
   184 +   by 64 are done using bit operations).  */
   185 +/* { dg-final { scan-tree-dump-times "/" 0 "final_cleanup" } } */
   186 +/* { dg-final { scan-tree-dump-times "%" 0 "final_cleanup" } } */
   187 +
   188 +/* { dg-final { cleanup-tree-dump "empty" } } */
   189 +/* { dg-final { cleanup-tree-dump "final_cleanup" } } */
   190 Index: gcc-4.3.2/gcc/tree-ssa-loop-ivopts.c
   191 ===================================================================
   192 --- gcc-4.3.2.orig/gcc/tree-ssa-loop-ivopts.c	2009-01-28 10:26:04.000000000 +0100
   193 +++ gcc-4.3.2/gcc/tree-ssa-loop-ivopts.c	2009-01-28 10:27:09.000000000 +0100
   194 @@ -3778,7 +3778,12 @@
   195      return false;
   196  
   197    cand_value_at (loop, cand, use->stmt, nit, &bnd);
   198 +
   199    *bound = aff_combination_to_tree (&bnd);
   200 +  /* It is unlikely that computing the number of iterations using division
   201 +     would be more profitable than keeping the original induction variable.  */
   202 +  if (expression_expensive_p (*bound))
   203 +    return false;
   204    return true;
   205  }
   206  
   207