This patch makes pass_store_merging::execute track polynomial sizes
and offsets.


2017-10-23  Richard Sandiford  <richard.sandif...@linaro.org>
            Alan Hayward  <alan.hayw...@arm.com>
            David Sherwood  <david.sherw...@arm.com>

gcc/
        * gimple-ssa-store-merging.c (pass_store_merging::execute): Track
        polynomial sizes and offsets.

Index: gcc/gimple-ssa-store-merging.c
===================================================================
--- gcc/gimple-ssa-store-merging.c      2017-10-23 17:11:39.971422491 +0100
+++ gcc/gimple-ssa-store-merging.c      2017-10-23 17:18:46.178187802 +0100
@@ -1389,7 +1389,7 @@ pass_store_merging::execute (function *f
              tree lhs = gimple_assign_lhs (stmt);
              tree rhs = gimple_assign_rhs1 (stmt);
 
-             HOST_WIDE_INT bitsize, bitpos;
+             poly_int64 bitsize, bitpos;
              machine_mode mode;
              int unsignedp = 0, reversep = 0, volatilep = 0;
              tree offset, base_addr;
@@ -1399,8 +1399,6 @@ pass_store_merging::execute (function *f
              /* As a future enhancement we could handle stores with the same
                 base and offset.  */
              bool invalid = reversep
-                            || ((bitsize > MAX_BITSIZE_MODE_ANY_INT)
-                                 && (TREE_CODE (rhs) != INTEGER_CST))
                             || !rhs_valid_for_store_merging_p (rhs);
 
              /* We do not want to rewrite TARGET_MEM_REFs.  */
@@ -1413,23 +1411,17 @@ pass_store_merging::execute (function *f
                 PR 23684 and this way we can catch more chains.  */
              else if (TREE_CODE (base_addr) == MEM_REF)
                {
-                 offset_int bit_off, byte_off = mem_ref_offset (base_addr);
-                 bit_off = byte_off << LOG2_BITS_PER_UNIT;
+                 poly_offset_int byte_off = mem_ref_offset (base_addr);
+                 poly_offset_int bit_off = byte_off << LOG2_BITS_PER_UNIT;
                  bit_off += bitpos;
-                 if (!wi::neg_p (bit_off) && wi::fits_shwi_p (bit_off))
-                   bitpos = bit_off.to_shwi ();
-                 else
+                 if (!bit_off.to_shwi (&bitpos))
                    invalid = true;
                  base_addr = TREE_OPERAND (base_addr, 0);
                }
              /* get_inner_reference returns the base object, get at its
                 address now.  */
              else
-               {
-                 if (bitpos < 0)
-                   invalid = true;
-                 base_addr = build_fold_addr_expr (base_addr);
-               }
+               base_addr = build_fold_addr_expr (base_addr);
 
              if (! invalid
                  && offset != NULL_TREE)
@@ -1455,13 +1447,19 @@ pass_store_merging::execute (function *f
              struct imm_store_chain_info **chain_info
                = m_stores.get (base_addr);
 
-             if (!invalid)
+             HOST_WIDE_INT const_bitsize, const_bitpos;
+             if (!invalid
+                 && bitsize.is_constant (&const_bitsize)
+                 && bitpos.is_constant (&const_bitpos)
+                 && (const_bitsize <= MAX_BITSIZE_MODE_ANY_INT
+                     || TREE_CODE (rhs) == INTEGER_CST)
+                 && const_bitpos >= 0)
                {
                  store_immediate_info *info;
                  if (chain_info)
                    {
                      info = new store_immediate_info (
-                       bitsize, bitpos, stmt,
+                       const_bitsize, const_bitpos, stmt,
                        (*chain_info)->m_store_info.length ());
                      if (dump_file && (dump_flags & TDF_DETAILS))
                        {
@@ -1490,7 +1488,7 @@ pass_store_merging::execute (function *f
                  /* Start a new chain.  */
                  struct imm_store_chain_info *new_chain
                    = new imm_store_chain_info (m_stores_head, base_addr);
-                 info = new store_immediate_info (bitsize, bitpos,
+                 info = new store_immediate_info (const_bitsize, const_bitpos,
                                                   stmt, 0);
                  new_chain->m_store_info.safe_push (info);
                  m_stores.put (base_addr, new_chain);

Reply via email to