Improve ivopts handling of forced scales
authorRichard Sandiford <richard.sandiford@linaro.org>
Thu, 9 Nov 2017 14:51:57 +0000 (14:51 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Thu, 9 Nov 2017 14:51:57 +0000 (14:51 +0000)
This patch improves the ivopts address cost calculation for modes
in which an index must be scaled rather than unscaled.  Previously
we would only try the scaled form if the unscaled form was valid.

Many of the SVE tests rely on this when matching scaled indices.

2017-11-09  Richard Sandiford  <richard.sandiford@linaro.org>
    Alan Hayward  <alan.hayward@arm.com>
    David Sherwood  <david.sherwood@arm.com>

gcc/
* tree-ssa-loop-ivopts.c (get_address_cost): Try using a
scaled index even if the unscaled address was invalid.
Don't increase the complexity of using a scale in that case.

Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>
From-SVN: r254585

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

index c4e9444b51024b79699e3d7c362029abacaf686a..eb0e6c2d51d95fb33ac8f51dc0e72979324875d5 100644 (file)
@@ -1,3 +1,11 @@
+2017-11-09  Richard Sandiford  <richard.sandiford@linaro.org>
+           Alan Hayward  <alan.hayward@arm.com>
+           David Sherwood  <david.sherwood@arm.com>
+
+       * tree-ssa-loop-ivopts.c (get_address_cost): Try using a
+       scaled index even if the unscaled address was invalid.
+       Don't increase the complexity of using a scale in that case.
+
 2017-11-09  Richard Sandiford  <richard.sandiford@linaro.org>
            Alan Hayward  <alan.hayward@arm.com>
            David Sherwood  <david.sherwood@arm.com>
index e16a4820784ed97a10fe1f9a63a7a68a6ddf28a3..65794b2b777e8d660d062df1fda2bec73cc7b895 100644 (file)
@@ -4331,18 +4331,25 @@ get_address_cost (struct ivopts_data *data, struct iv_use *use,
   machine_mode addr_mode = TYPE_MODE (type);
   machine_mode mem_mode = TYPE_MODE (TREE_TYPE (*use->op_p));
   addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (use->iv->base));
+  /* Only true if ratio != 1.  */
+  bool ok_with_ratio_p = false;
+  bool ok_without_ratio_p = false;
 
   if (!aff_combination_const_p (aff_inv))
     {
       parts.index = integer_one_node;
       /* Addressing mode "base + index".  */
-      if (valid_mem_ref_p (mem_mode, as, &parts))
+      ok_without_ratio_p = valid_mem_ref_p (mem_mode, as, &parts);
+      if (ratio != 1)
        {
          parts.step = wide_int_to_tree (type, ratio);
          /* Addressing mode "base + index << scale".  */
-         if (ratio != 1 && !valid_mem_ref_p (mem_mode, as, &parts))
+         ok_with_ratio_p = valid_mem_ref_p (mem_mode, as, &parts);
+         if (!ok_with_ratio_p)
            parts.step = NULL_TREE;
-
+       }
+      if (ok_with_ratio_p || ok_without_ratio_p)
+       {
          if (aff_inv->offset != 0)
            {
              parts.offset = wide_int_to_tree (sizetype, aff_inv->offset);
@@ -4440,7 +4447,9 @@ get_address_cost (struct ivopts_data *data, struct iv_use *use,
 
   if (parts.symbol != NULL_TREE)
     cost.complexity += 1;
-  if (parts.step != NULL_TREE && !integer_onep (parts.step))
+  /* Don't increase the complexity of adding a scaled index if it's
+     the only kind of index that the target allows.  */
+  if (parts.step != NULL_TREE && ok_without_ratio_p)
     cost.complexity += 1;
   if (parts.base != NULL_TREE && parts.index != NULL_TREE)
     cost.complexity += 1;