]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
ddg.c (walk_mems_2): Moved from alias.c, use may_alias_p instead of alias_sets_confli...
authorBingfeng Mei <bmei@broadcom.com>
Mon, 9 Aug 2010 14:44:03 +0000 (14:44 +0000)
committerBingfeng Mei <meibf@gcc.gnu.org>
Mon, 9 Aug 2010 14:44:03 +0000 (14:44 +0000)
2010-08-09  Bingfeng Mei  <bmei@broadcom.com>

* ddg.c (walk_mems_2): Moved from alias.c, use may_alias_p instead of
alias_sets_conflict_p.
(walk_mems_1): Moved from alias.c.
(insns_may_alias_p): New function, originally insn_alias_sets_conflict_p
in alias.c.
        (add_inter_loop_mem_dep): Use insns_may_alias_p now.
        * cse.c (cse_insn): New argument in calling nonoverlapping_memrefs_p.
        * alias.c (walk_mems_2): Moved to ddg.c.
(walk_mems_1): Ditto.
(insn_alias_sets_conflict_p): Renamed to insns_may_alias_p and moved
to ddg.c.
(nonoverlapping_memrefs_p): Add flag to guard offset-based memory
disambiguation.
*(may_alias_p): New function to check whether two memory expression
may alias or not. Currently used in buidling inter-iteration memory
dependence.
*alias.h (nonoverlapping_memrefs_p): New flag as third argument.
(insn_alias_sets_conflict_p): Removed
*rtl.h (may_alias_p): New function prototype.

From-SVN: r163037

gcc/ChangeLog
gcc/alias.c
gcc/alias.h
gcc/cse.c
gcc/ddg.c
gcc/rtl.h

index 6c73664e85d370fbb3f23767aaf7b86551949120..ddae0798b46a48d9e7e295d6a6d9f1965b210357 100644 (file)
@@ -1,3 +1,25 @@
+2010-08-09  Bingfeng Mei  <bmei@broadcom.com>
+
+       * ddg.c (walk_mems_2): Moved from alias.c, use may_alias_p instead of
+       alias_sets_conflict_p.
+       (walk_mems_1): Moved from alias.c.
+       (insns_may_alias_p): New function, originally insn_alias_sets_conflict_p
+       in alias.c. 
+        (add_inter_loop_mem_dep): Use insns_may_alias_p now.
+        * cse.c (cse_insn): New argument in calling nonoverlapping_memrefs_p.
+        * alias.c (walk_mems_2): Moved to ddg.c.
+       (walk_mems_1): Ditto.
+       (insn_alias_sets_conflict_p): Renamed to insns_may_alias_p and moved
+       to ddg.c.
+       (nonoverlapping_memrefs_p): Add flag to guard offset-based memory
+       disambiguation.
+       *(may_alias_p): New function to check whether two memory expression
+       may alias or not. Currently used in buidling inter-iteration memory
+       dependence.
+       *alias.h (nonoverlapping_memrefs_p): New flag as third argument.
+       (insn_alias_sets_conflict_p): Removed
+       *rtl.h (may_alias_p): New function prototype.
+        
 2010-08-09  Nathan Froyd  <froydnj@codesourcery.com>
 
        * tree.c (nreverse): Assert that we don't have a BLOCK.
index f5de4db9d753f19d72aa85b1cbb3fa4f84846243..3f5f47a009a3861918f096d9d5c8bc400f3dfb0c 100644 (file)
@@ -452,43 +452,6 @@ alias_sets_conflict_p (alias_set_type set1, alias_set_type set2)
   return 0;
 }
 
-static int
-walk_mems_2 (rtx *x, rtx mem)
-{
-  if (MEM_P (*x))
-    {
-      if (alias_sets_conflict_p (MEM_ALIAS_SET(*x), MEM_ALIAS_SET(mem)))
-        return 1;
-
-      return -1;
-    }
-  return 0;
-}
-
-static int
-walk_mems_1 (rtx *x, rtx *pat)
-{
-  if (MEM_P (*x))
-    {
-      /* Visit all MEMs in *PAT and check indepedence.  */
-      if (for_each_rtx (pat, (rtx_function) walk_mems_2, *x))
-        /* Indicate that dependence was determined and stop traversal.  */
-        return 1;
-
-      return -1;
-    }
-  return 0;
-}
-
-/* Return 1 if two specified instructions have mem expr with conflict alias sets*/
-bool
-insn_alias_sets_conflict_p (rtx insn1, rtx insn2)
-{
-  /* For each pair of MEMs in INSN1 and INSN2 check their independence.  */
-  return  for_each_rtx (&PATTERN (insn1), (rtx_function) walk_mems_1,
-                        &PATTERN (insn2));
-}
-
 /* Return 1 if the two specified alias sets will always conflict.  */
 
 int
@@ -2187,10 +2150,11 @@ adjust_offset_for_component_ref (tree x, rtx offset)
 }
 
 /* Return nonzero if we can determine the exprs corresponding to memrefs
-   X and Y and they do not overlap.  */
+   X and Y and they do not overlap. 
+   If LOOP_VARIANT is set, skip offset-based disambiguation */
 
 int
-nonoverlapping_memrefs_p (const_rtx x, const_rtx y)
+nonoverlapping_memrefs_p (const_rtx x, const_rtx y, bool loop_invariant)
 {
   tree exprx = MEM_EXPR (x), expry = MEM_EXPR (y);
   rtx rtlx, rtly;
@@ -2287,6 +2251,10 @@ nonoverlapping_memrefs_p (const_rtx x, const_rtx y)
            || (CONSTANT_P (basey) && REG_P (basex)
                && REGNO_PTR_FRAME_P (REGNO (basex))));
 
+  /* Offset based disambiguation not appropriate for loop invariant */
+  if (loop_invariant)
+    return 0;              
+
   sizex = (!MEM_P (rtlx) ? (int) GET_MODE_SIZE (GET_MODE (rtlx))
           : MEM_SIZE (rtlx) ? INTVAL (MEM_SIZE (rtlx))
           : -1);
@@ -2413,7 +2381,7 @@ true_dependence_1 (const_rtx mem, enum machine_mode mem_mode, rtx mem_addr,
   if (DIFFERENT_ALIAS_SETS_P (x, mem))
     return 0;
 
-  if (nonoverlapping_memrefs_p (mem, x))
+  if (nonoverlapping_memrefs_p (mem, x, false))
     return 0;
 
   if (aliases_everything_p (x))
@@ -2528,7 +2496,7 @@ write_dependence_p (const_rtx mem, const_rtx x, int writep)
                                 SIZE_FOR_MODE (x), x_addr, 0)) != -1)
     return ret;
 
-  if (nonoverlapping_memrefs_p (x, mem))
+  if (nonoverlapping_memrefs_p (x, mem, false))
     return 0;
 
   fixed_scalar
@@ -2559,6 +2527,76 @@ output_dependence (const_rtx mem, const_rtx x)
 }
 \f
 
+
+/* Check whether X may be aliased with MEM.  Don't do offset-based
+  memory disambiguation & TBAA.  */
+int
+may_alias_p (const_rtx mem, const_rtx x)
+{
+  rtx x_addr, mem_addr;
+  int ret;
+
+  if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
+    return 1;
+
+  /* ??? In true_dependence we also allow BLKmode to alias anything. */
+  if (GET_MODE (mem) == BLKmode || GET_MODE (x) == BLKmode)
+    return 1;
+    
+  if (MEM_ALIAS_SET (x) == ALIAS_SET_MEMORY_BARRIER
+      || MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER)
+    return 1;
+
+  /* Read-only memory is by definition never modified, and therefore can't
+     conflict with anything.  We don't expect to find read-only set on MEM,
+     but stupid user tricks can produce them, so don't die.  */
+  if (MEM_READONLY_P (x))
+    return 0;
+
+  /* If we have MEMs refering to different address spaces (which can
+     potentially overlap), we cannot easily tell from the addresses
+     whether the references overlap.  */
+  if (MEM_ADDR_SPACE (mem) != MEM_ADDR_SPACE (x))
+    return 1;
+
+  x_addr = XEXP (x, 0);
+  mem_addr = XEXP (mem, 0);
+  if (!((GET_CODE (x_addr) == VALUE
+        && GET_CODE (mem_addr) != VALUE
+        && reg_mentioned_p (x_addr, mem_addr))
+       || (GET_CODE (x_addr) != VALUE
+           && GET_CODE (mem_addr) == VALUE
+           && reg_mentioned_p (mem_addr, x_addr))))
+    {
+      x_addr = get_addr (x_addr);
+      mem_addr = get_addr (mem_addr);
+    }
+
+  if (! base_alias_check (x_addr, mem_addr, GET_MODE (x), GET_MODE (mem_addr)))
+    return 0;
+
+  x_addr = canon_rtx (x_addr);
+  mem_addr = canon_rtx (mem_addr);
+
+  if (nonoverlapping_memrefs_p (mem, x, true))
+    return 0;
+
+  if (aliases_everything_p (x))
+    return 1;
+
+  /* We cannot use aliases_everything_p to test MEM, since we must look
+     at MEM_ADDR, rather than XEXP (mem, 0).  */
+  if (GET_MODE (mem) == QImode || GET_CODE (mem_addr) == AND)
+    return 1;
+
+  if (fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr,
+                                         rtx_addr_varies_p))
+    return 0;
+
+  /* TBAA not valid for loop_invarint */
+  return rtx_refs_may_alias_p (x, mem, false);
+}
+
 void
 init_alias_target (void)
 {
index 5907215824d666fba3947e22994af1e67e162e2f..58945524e9ac1f0480bf2513ec321deb444b9b85 100644 (file)
@@ -42,8 +42,7 @@ extern void record_component_aliases (tree);
 extern int alias_sets_conflict_p (alias_set_type, alias_set_type);
 extern int alias_sets_must_conflict_p (alias_set_type, alias_set_type);
 extern int objects_must_conflict_p (tree, tree);
-extern int nonoverlapping_memrefs_p (const_rtx, const_rtx);
-extern bool insn_alias_sets_conflict_p (rtx, rtx);
+extern int nonoverlapping_memrefs_p (const_rtx, const_rtx, bool);
 
 /* This alias set can be used to force a memory to conflict with all
    other memories, creating a barrier across which no memory reference
index ae513eb2a16ebb260395cf1aacfdcbf8764c2ce9..dcba6bc3bb35cf4f56b51bf3f2432239c65fe695 100644 (file)
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -5015,7 +5015,7 @@ cse_insn (rtx insn)
              dest = canon_rtx (SET_DEST (sets[i].rtl));
 
              if (!MEM_P (src) || !MEM_P (dest)
-                 || !nonoverlapping_memrefs_p (src, dest))
+                 || !nonoverlapping_memrefs_p (src, dest, false))
                break;
            }
 
index 0a20ed612914a73f3c9c8e8cbca5ecfb045fc021..88aaf9bb2e4e92c9f456831bfda68f7a21e9e46b 100644 (file)
--- a/gcc/ddg.c
+++ b/gcc/ddg.c
@@ -348,12 +348,49 @@ build_inter_loop_deps (ddg_ptr g)
 }
 
 
+static int
+walk_mems_2 (rtx *x, rtx mem)
+{
+  if (MEM_P (*x))
+    {
+      if (may_alias_p (*x, mem))
+        return 1;
+
+      return -1;
+    }
+  return 0;
+}
+
+static int
+walk_mems_1 (rtx *x, rtx *pat)
+{
+  if (MEM_P (*x))
+    {
+      /* Visit all MEMs in *PAT and check indepedence.  */
+      if (for_each_rtx (pat, (rtx_function) walk_mems_2, *x))
+        /* Indicate that dependence was determined and stop traversal.  */
+        return 1;
+
+      return -1;
+    }
+  return 0;
+}
+
+/* Return 1 if two specified instructions have mem expr with conflict alias sets*/
+static int
+insns_may_alias_p (rtx insn1, rtx insn2)
+{
+  /* For each pair of MEMs in INSN1 and INSN2 check their independence.  */
+  return  for_each_rtx (&PATTERN (insn1), (rtx_function) walk_mems_1,
+                        &PATTERN (insn2));
+}
+
 /* Given two nodes, analyze their RTL insns and add inter-loop mem deps
    to ddg G.  */
 static void
 add_inter_loop_mem_dep (ddg_ptr g, ddg_node_ptr from, ddg_node_ptr to)
 {
-  if (!insn_alias_sets_conflict_p (from->insn, to->insn))
+  if (!insns_may_alias_p (from->insn, to->insn))
     /* Do not create edge if memory references have disjoint alias sets.  */
     return;
 
index 710e3caa1444d01dbe826b8053a0535ea85e7f0d..bb873584057492b7e7e25a610dd15ea70b655ad6 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -2424,6 +2424,7 @@ extern int canon_true_dependence (const_rtx, enum machine_mode, rtx, const_rtx,
 extern int read_dependence (const_rtx, const_rtx);
 extern int anti_dependence (const_rtx, const_rtx);
 extern int output_dependence (const_rtx, const_rtx);
+extern int may_alias_p (const_rtx, const_rtx);
 extern void init_alias_target (void);
 extern void init_alias_analysis (void);
 extern void end_alias_analysis (void);