OSDN Git Service

PR c++/39786
[pf3gnuchains/gcc-fork.git] / gcc / tree-scalar-evolution.c
index bac6e59..70af0fd 100644 (file)
@@ -466,7 +466,7 @@ loop_phi_node_p (gimple phi)
    EVOLUTION_FN = {i_0, +, 2}_1.
 */
  
-static tree 
+tree
 compute_overall_effect_of_inner_loop (struct loop *loop, tree evolution_fn)
 {
   bool val = false;
@@ -492,7 +492,10 @@ compute_overall_effect_of_inner_loop (struct loop *loop, tree evolution_fn)
              /* evolution_fn is the evolution function in LOOP.  Get
                 its value in the nb_iter-th iteration.  */
              res = chrec_apply (inner_loop->num, evolution_fn, nb_iter);
-             
+
+             if (chrec_contains_symbols_defined_in_loop (res, loop->num))
+               res = instantiate_parameters (loop, res);
+
              /* Continue the computation until ending on a parent of LOOP.  */
              return compute_overall_effect_of_inner_loop (loop, res);
            }
@@ -1489,18 +1492,29 @@ analyze_evolution_in_loop (gimple loop_phi_node,
       bb = gimple_phi_arg_edge (loop_phi_node, i)->src;
       if (!flow_bb_inside_loop_p (loop, bb))
        continue;
-      
+
       if (TREE_CODE (arg) == SSA_NAME)
        {
+         bool val = false;
+
          ssa_chain = SSA_NAME_DEF_STMT (arg);
 
          /* Pass in the initial condition to the follow edge function.  */
          ev_fn = init_cond;
          res = follow_ssa_edge (loop, ssa_chain, loop_phi_node, &ev_fn, 0);
+
+         /* If ev_fn has no evolution in the inner loop, and the
+            init_cond is not equal to ev_fn, then we have an
+            ambiguity between two possible values, as we cannot know
+            the number of iterations at this point.  */
+         if (TREE_CODE (ev_fn) != POLYNOMIAL_CHREC
+             && no_evolution_in_loop_p (ev_fn, loop->num, &val) && val
+             && !operand_equal_p (init_cond, ev_fn, 0))
+           ev_fn = chrec_dont_know;
        }
       else
        res = t_false;
-             
+
       /* When it is impossible to go back on the same
         loop_phi_node by following the ssa edges, the
         evolution is represented by a peeled chrec, i.e. the
@@ -1890,18 +1904,16 @@ analyze_scalar_evolution_1 (struct loop *loop, tree var, tree res)
   return res;
 }
 
-/* Entry point for the scalar evolution analyzer.
-   Analyzes and returns the scalar evolution of the ssa_name VAR.
-   LOOP_NB is the identifier number of the loop in which the variable
-   is used.
+/* Analyzes and returns the scalar evolution of the ssa_name VAR in
+   LOOP.  LOOP is the loop in which the variable is used.
    
    Example of use: having a pointer VAR to a SSA_NAME node, STMT a
    pointer to the statement that uses this variable, in order to
    determine the evolution function of the variable, use the following
    calls:
    
-   unsigned loop_nb = loop_containing_stmt (stmt)->num;
-   tree chrec_with_symbols = analyze_scalar_evolution (loop_nb, var);
+   loop_p loop = loop_containing_stmt (stmt);
+   tree chrec_with_symbols = analyze_scalar_evolution (loop, var);
    tree chrec_instantiated = instantiate_parameters (loop, chrec_with_symbols);
 */
 
@@ -2174,7 +2186,9 @@ instantiate_scev_1 (basic_block instantiate_below,
          else
            res = chrec;
 
-         if (res == NULL_TREE)
+         if (res == NULL_TREE
+             || !dominated_by_p (CDI_DOMINATORS, instantiate_below,
+                                 gimple_bb (SSA_NAME_DEF_STMT (res))))
            res = chrec_dont_know;
        }