]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-optimization: Clarify LIM memory ref equality master trunk
authorXin Wang <yw987194828@gmail.com>
Wed, 20 May 2026 08:17:15 +0000 (16:17 +0800)
committerRichard Biener <rguenther@suse.de>
Fri, 19 Jun 2026 11:49:27 +0000 (13:49 +0200)
Restructure mem_ref_hasher::equal so the non-decomposed fallback
and the decomposed comparison path are explicit. The non-decomposed
lookup still compares the original refs with operand_equal_p, while
the decomposed path keeps the same base, offset, size, max_size,
volatile, alias-set, and type checks as before. This matches the split
in gather_mem_refs_stmt, where non-decomposed references are marked
with an unknown max_size and decomposed references are hashed from
base, offset, and size.

* tree-ssa-loop-im.cc (mem_ref_hasher::equal): Refactor
for clarity.

Signed-off-by: Xin Wang <wangxinw@hygon.cn>
gcc/tree-ssa-loop-im.cc

index c207a96f5c3987499a2737ffc78f54c4dca753a3..592a37da5dc71705649f6987d9645e2ca560171a 100644 (file)
@@ -202,34 +202,43 @@ mem_ref_hasher::hash (const im_mem_ref *mem)
 inline bool
 mem_ref_hasher::equal (const im_mem_ref *mem1, const ao_ref *obj2)
 {
 inline bool
 mem_ref_hasher::equal (const im_mem_ref *mem1, const ao_ref *obj2)
 {
-  if (obj2->max_size_known_p ())
-    return (mem1->ref_decomposed
-           && ((TREE_CODE (mem1->mem.base) == MEM_REF
-                && TREE_CODE (obj2->base) == MEM_REF
-                && operand_equal_p (TREE_OPERAND (mem1->mem.base, 0),
-                                    TREE_OPERAND (obj2->base, 0), 0)
-                && known_eq (mem_ref_offset (mem1->mem.base) * BITS_PER_UNIT + mem1->mem.offset,
-                             mem_ref_offset (obj2->base) * BITS_PER_UNIT + obj2->offset))
-               || (operand_equal_p (mem1->mem.base, obj2->base, 0)
-                   && known_eq (mem1->mem.offset, obj2->offset)))
-           && known_eq (mem1->mem.size, obj2->size)
-           && known_eq (mem1->mem.max_size, obj2->max_size)
-           && mem1->mem.volatile_p == obj2->volatile_p
-           && (mem1->mem.ref_alias_set == obj2->ref_alias_set
-               /* We are not canonicalizing alias-sets but for the
-                  special-case we didn't canonicalize yet and the
-                  incoming ref is a alias-set zero MEM we pick
-                  the correct one already.  */
-               || (!mem1->ref_canonical
-                   && (TREE_CODE (obj2->ref) == MEM_REF
-                       || TREE_CODE (obj2->ref) == TARGET_MEM_REF)
-                   && obj2->ref_alias_set == 0)
-               /* Likewise if there's a canonical ref with alias-set zero.  */
-               || (mem1->ref_canonical && mem1->mem.ref_alias_set == 0))
-           && types_compatible_p (TREE_TYPE (mem1->mem.ref),
-                                  TREE_TYPE (obj2->ref)));
-  else
+  if (!obj2->max_size_known_p ())
     return operand_equal_p (mem1->mem.ref, obj2->ref, 0);
     return operand_equal_p (mem1->mem.ref, obj2->ref, 0);
+
+  if (!mem1->ref_decomposed)
+    return false;
+
+  /* obj2 is now known decomposable and the hash is based on offset,
+     size and base, matching gather_mem_refs_stmt.  */
+  bool refs_equal
+    = ((TREE_CODE (mem1->mem.base) == MEM_REF
+       && TREE_CODE (obj2->base) == MEM_REF
+       && operand_equal_p (TREE_OPERAND (mem1->mem.base, 0),
+                           TREE_OPERAND (obj2->base, 0), 0)
+       && known_eq (mem_ref_offset (mem1->mem.base) * BITS_PER_UNIT
+                    + mem1->mem.offset,
+                    mem_ref_offset (obj2->base) * BITS_PER_UNIT
+                    + obj2->offset))
+       || (operand_equal_p (mem1->mem.base, obj2->base, 0)
+          && known_eq (mem1->mem.offset, obj2->offset)));
+
+  return (refs_equal
+         && known_eq (mem1->mem.size, obj2->size)
+         && known_eq (mem1->mem.max_size, obj2->max_size)
+         && mem1->mem.volatile_p == obj2->volatile_p
+         && (mem1->mem.ref_alias_set == obj2->ref_alias_set
+             /* We are not canonicalizing alias-sets but for the
+                special-case we didn't canonicalize yet and the
+                incoming ref is a alias-set zero MEM we pick
+                the correct one already.  */
+             || (!mem1->ref_canonical
+                 && (TREE_CODE (obj2->ref) == MEM_REF
+                     || TREE_CODE (obj2->ref) == TARGET_MEM_REF)
+                 && obj2->ref_alias_set == 0)
+             /* Likewise if there's a canonical ref with alias-set zero.  */
+             || (mem1->ref_canonical && mem1->mem.ref_alias_set == 0))
+         && types_compatible_p (TREE_TYPE (mem1->mem.ref),
+                                TREE_TYPE (obj2->ref)));
 }
 
 
 }
 
 
@@ -3866,4 +3875,3 @@ make_pass_lim (gcc::context *ctxt)
   return new pass_lim (ctxt);
 }
 
   return new pass_lim (ctxt);
 }
 
-