tree-ssa-loop-ivopts.c (struct iv_cand): New field inv_exprs.
authorBin Cheng <bin.cheng@arm.com>
Thu, 11 May 2017 09:40:48 +0000 (09:40 +0000)
committerBin Cheng <amker@gcc.gnu.org>
Thu, 11 May 2017 09:40:48 +0000 (09:40 +0000)
* tree-ssa-loop-ivopts.c (struct iv_cand): New field inv_exprs.
(dump_cand): Support iv_cand.inv_exprs.
(add_candidate_1): Record invariant exprs in iv_cand.inv_exprs
for candidates.
(iv_ca_set_no_cp, iv_ca_set_cp, free_loop_data): Support
iv_cand.inv_exprs.

From-SVN: r247889

gcc/ChangeLog
gcc/tree-ssa-loop-ivopts.c

index 262b25aa2f90d61b5e61da0fc3ff2695a08108e1..ea4912bfa1b8b022fc7398ccb898b58ed2d290d6 100644 (file)
@@ -1,3 +1,12 @@
+2017-05-11  Bin Cheng  <bin.cheng@arm.com>
+
+       * tree-ssa-loop-ivopts.c (struct iv_cand): New field inv_exprs.
+       (dump_cand): Support iv_cand.inv_exprs.
+       (add_candidate_1): Record invariant exprs in iv_cand.inv_exprs
+       for candidates.
+       (iv_ca_set_no_cp, iv_ca_set_cp, free_loop_data): Support
+       iv_cand.inv_exprs.
+
 2017-05-11  Bin Cheng  <bin.cheng@arm.com>
 
        * tree-ssa-loop-ivopts.c (multiplier_allowed_in_address_p): Move
index 436538229c1dc0d1425216de7c24f73cc12b07c9..5d7391631d643fbae95aa12fc0dbecdf49ed7ac5 100644 (file)
@@ -347,9 +347,10 @@ struct cost_pair
   struct iv_cand *cand;        /* The candidate.  */
   comp_cost cost;      /* The cost.  */
   enum tree_code comp; /* For iv elimination, the comparison.  */
-  bitmap inv_vars;     /* The list of invariants that have to be
-                          preserved.  */
-  bitmap inv_exprs;    /* Loop invariant expressions.  */
+  bitmap inv_vars;     /* The list of invariant ssa_vars that have to be
+                          preserved when representing iv_use with iv_cand.  */
+  bitmap inv_exprs;    /* The list of newly created invariant expressions
+                          when representing iv_use with iv_cand.  */
   tree value;          /* For final value elimination, the expression for
                           the final value of the iv.  For iv elimination,
                           the new bound to compare with.  */
@@ -418,8 +419,11 @@ struct iv_cand
   unsigned cost_step;  /* Cost of the candidate's increment operation.  */
   struct iv_use *ainc_use; /* For IP_{BEFORE,AFTER}_USE candidates, the place
                              where it is incremented.  */
-  bitmap inv_vars;     /* The list of invariants that are used in step of the
-                          biv.  */
+  bitmap inv_vars;     /* The list of invariant ssa_vars used in step of the
+                          iv_cand.  */
+  bitmap inv_exprs;    /* If step is more complicated than a single ssa_var,
+                          hanlde it as a new invariant expression which will
+                          be hoisted out of loop.  */
   struct iv *orig_iv;  /* The original iv if this cand is added from biv with
                           smaller type.  */
 };
@@ -789,6 +793,11 @@ dump_cand (FILE *file, struct iv_cand *cand)
       fprintf (file, "  Depend on inv.vars: ");
       dump_bitmap (file, cand->inv_vars);
     }
+  if (cand->inv_exprs)
+    {
+      fprintf (file, "  Depend on inv.exprs: ");
+      dump_bitmap (file, cand->inv_exprs);
+    }
 
   if (cand->var_before)
     {
@@ -3025,7 +3034,23 @@ add_candidate_1 (struct ivopts_data *data,
       data->vcands.safe_push (cand);
 
       if (TREE_CODE (step) != INTEGER_CST)
-       find_inv_vars (data, &step, &cand->inv_vars);
+       {
+         find_inv_vars (data, &step, &cand->inv_vars);
+
+         iv_inv_expr_ent *inv_expr = get_loop_invariant_expr (data, step);
+         /* Share bitmap between inv_vars and inv_exprs for cand.  */
+         if (inv_expr != NULL)
+           {
+             cand->inv_exprs = cand->inv_vars;
+             cand->inv_vars = NULL;
+             if (cand->inv_exprs)
+               bitmap_clear (cand->inv_exprs);
+             else
+               cand->inv_exprs = BITMAP_ALLOC (NULL);
+
+             bitmap_set_bit (cand->inv_exprs, inv_expr->id);
+           }
+       }
 
       if (pos == IP_AFTER_USE || pos == IP_BEFORE_USE)
        cand->ainc_use = use;
@@ -5603,6 +5628,7 @@ iv_ca_set_no_cp (struct ivopts_data *data, struct iv_ca *ivs,
       ivs->n_cands--;
       ivs->cand_cost -= cp->cand->cost;
       iv_ca_set_remove_invs (ivs, cp->cand->inv_vars, ivs->n_inv_var_uses);
+      iv_ca_set_remove_invs (ivs, cp->cand->inv_exprs, ivs->n_inv_expr_uses);
     }
 
   ivs->cand_use_cost -= cp->cost;
@@ -5659,6 +5685,7 @@ iv_ca_set_cp (struct ivopts_data *data, struct iv_ca *ivs,
          ivs->n_cands++;
          ivs->cand_cost += cp->cand->cost;
          iv_ca_set_add_invs (ivs, cp->cand->inv_vars, ivs->n_inv_var_uses);
+         iv_ca_set_add_invs (ivs, cp->cand->inv_exprs, ivs->n_inv_expr_uses);
        }
 
       ivs->cand_use_cost += cp->cost;
@@ -7140,6 +7167,8 @@ free_loop_data (struct ivopts_data *data)
 
       if (cand->inv_vars)
        BITMAP_FREE (cand->inv_vars);
+      if (cand->inv_exprs)
+       BITMAP_FREE (cand->inv_exprs);
       free (cand);
     }
   data->vcands.truncate (0);