]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: [multiple changes]
authorRichard Biener <rguenther@suse.de>
Thu, 5 Sep 2019 12:11:52 +0000 (12:11 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 5 Sep 2019 12:11:52 +0000 (12:11 +0000)
2019-09-05  Richard Biener  <rguenther@suse.de>

* lto-streamer.h (LTO_minor_version): Bump.

Backport from mainline
2019-05-06  Richard Biener  <rguenther@suse.de>

PR tree-optimization/90328
* tree-data-ref.h (dr_may_alias_p): Pass in the actual loop nest.
* tree-data-ref.c (dr_may_alias_p): Check whether the clique
is valid in the loop nest before using it.
(initialize_data_dependence_relation): Adjust.
* graphite-scop-detection.c (build_alias_set): Pass the SCOP enclosing
loop as loop-nest to dr_may_alias_p.

* gcc.dg/torture/pr90328.c: New testcase.

2019-03-08  Richard Biener  <rguenther@suse.de>

PR middle-end/89578
* cfgloop.h (struct loop): Add owned_clique field.
* cfgloopmanip.c (copy_loop_info): Copy it.
* tree-cfg.c (gimple_duplicate_bb): Do not remap owned_clique
cliques.
* tree-inline.c (copy_loops): Remap owned_clique.
* lto-streamer-in.c (input_cfg): Stream owned_clique.
* lto-streamer-out.c (output_cfg): Likewise.

2019-02-22  Richard Biener  <rguenther@suse.de>

PR tree-optimization/87609
* tree-cfg.c (gimple_duplicate_bb): Only remap inlined cliques.

2019-02-22  Richard Biener  <rguenther@suse.de>

PR middle-end/87609
* cfghooks.h (dependence_hash): New typedef.
(struct copy_bb_data): New type.
(cfg_hooks::duplicate_block): Adjust to take a copy_bb_data argument.
(duplicate_block): Likewise.
* cfghooks.c (duplicate_block): Pass down copy_bb_data.
(copy_bbs): Create and pass down copy_bb_data.
* cfgrtl.c (cfg_layout_duplicate_bb): Adjust.
(rtl_duplicate_bb): Likewise.
* tree-cfg.c (gimple_duplicate_bb): If the copy_bb_data arg is not NULL
remap dependence info.

* gcc.dg/torture/restrict-7.c: New testcase.

2019-02-22  Richard Biener  <rguenther@suse.de>

PR tree-optimization/87609
* tree-core.h (tree_base): Document special clique values.
* tree-inline.c (remap_dependence_clique): Do not use the
special clique value of one.
(maybe_set_dependence_info): Use clique one.
(clear_dependence_clique): New callback.
(compute_dependence_clique): Clear clique one from all refs
before assigning it (again).

From-SVN: r275405

19 files changed:
gcc/ChangeLog
gcc/cfghooks.c
gcc/cfghooks.h
gcc/cfgloop.h
gcc/cfgloopmanip.c
gcc/cfgrtl.c
gcc/graphite-scop-detection.c
gcc/lto-streamer-in.c
gcc/lto-streamer-out.c
gcc/lto-streamer.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr90328.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/restrict-7.c [new file with mode: 0644]
gcc/tree-cfg.c
gcc/tree-core.h
gcc/tree-data-ref.c
gcc/tree-data-ref.h
gcc/tree-inline.c
gcc/tree-ssa-structalias.c

index 06dfed12c377d6d2ab597bba42ff738bd0f2b7da..3e2ec917ab9687bce208d379d89f50d7b803ac9a 100644 (file)
@@ -1,3 +1,59 @@
+2019-09-05  Richard Biener  <rguenther@suse.de>
+
+       * lto-streamer.h (LTO_minor_version): Bump.
+
+       Backport from mainline
+       2019-05-06  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/90328
+       * tree-data-ref.h (dr_may_alias_p): Pass in the actual loop nest.
+       * tree-data-ref.c (dr_may_alias_p): Check whether the clique
+       is valid in the loop nest before using it.
+       (initialize_data_dependence_relation): Adjust.
+       * graphite-scop-detection.c (build_alias_set): Pass the SCOP enclosing
+       loop as loop-nest to dr_may_alias_p.
+
+       2019-03-08  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/89578
+       * cfgloop.h (struct loop): Add owned_clique field.
+       * cfgloopmanip.c (copy_loop_info): Copy it.
+       * tree-cfg.c (gimple_duplicate_bb): Do not remap owned_clique
+       cliques.
+       * tree-inline.c (copy_loops): Remap owned_clique.
+       * lto-streamer-in.c (input_cfg): Stream owned_clique.
+       * lto-streamer-out.c (output_cfg): Likewise.
+
+       2019-02-22  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/87609
+       * tree-cfg.c (gimple_duplicate_bb): Only remap inlined cliques.
+
+       2019-02-22  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/87609
+       * cfghooks.h (dependence_hash): New typedef.
+       (struct copy_bb_data): New type.
+       (cfg_hooks::duplicate_block): Adjust to take a copy_bb_data argument.
+       (duplicate_block): Likewise.
+       * cfghooks.c (duplicate_block): Pass down copy_bb_data.
+       (copy_bbs): Create and pass down copy_bb_data.
+       * cfgrtl.c (cfg_layout_duplicate_bb): Adjust.
+       (rtl_duplicate_bb): Likewise.
+       * tree-cfg.c (gimple_duplicate_bb): If the copy_bb_data arg is not NULL
+       remap dependence info.
+
+       2019-02-22  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/87609
+       * tree-core.h (tree_base): Document special clique values.
+       * tree-inline.c (remap_dependence_clique): Do not use the
+       special clique value of one.
+       (maybe_set_dependence_info): Use clique one.
+       (clear_dependence_clique): New callback.
+       (compute_dependence_clique): Clear clique one from all refs
+       before assigning it (again).
+
 2019-09-04  Iain Sandoe  <iain@sandoe.co.uk>
 
        Backport from mainline
index ce2da6a2f39c9cf5ec78a1178b46441c705299a3..83d6ea551f83dcbb8100d17294c1aaf5d4f8d4ee 100644 (file)
@@ -1067,7 +1067,7 @@ can_duplicate_block_p (const_basic_block bb)
    AFTER.  */
 
 basic_block
-duplicate_block (basic_block bb, edge e, basic_block after)
+duplicate_block (basic_block bb, edge e, basic_block after, copy_bb_data *id)
 {
   edge s, n;
   basic_block new_bb;
@@ -1083,7 +1083,7 @@ duplicate_block (basic_block bb, edge e, basic_block after)
 
   gcc_checking_assert (can_duplicate_block_p (bb));
 
-  new_bb = cfg_hooks->duplicate_block (bb);
+  new_bb = cfg_hooks->duplicate_block (bb, id);
   if (after)
     move_block_after (new_bb, after);
 
@@ -1355,13 +1355,14 @@ copy_bbs (basic_block *bbs, unsigned n, basic_block *new_bbs,
   unsigned i, j;
   basic_block bb, new_bb, dom_bb;
   edge e;
+  copy_bb_data id;
 
   /* Duplicate bbs, update dominators, assign bbs to loops.  */
   for (i = 0; i < n; i++)
     {
       /* Duplicate.  */
       bb = bbs[i];
-      new_bb = new_bbs[i] = duplicate_block (bb, NULL, after);
+      new_bb = new_bbs[i] = duplicate_block (bb, NULL, after, &id);
       after = new_bb;
       bb->flags |= BB_DUPLICATED;
       if (bb->loop_father)
index 4c1abe73623d7c768ffb01917f3ebca481286fcd..f0a874aa0d0cf9b266a8404dd795509e42230304 100644 (file)
@@ -54,6 +54,19 @@ struct profile_record
   bool run;
 };
 
+typedef int_hash <unsigned short, 0> dependence_hash;
+
+/* Optional data for duplicate_block.   */
+
+struct copy_bb_data
+{
+  copy_bb_data() : dependence_map (NULL) {}
+  ~copy_bb_data () { delete dependence_map; }
+
+  /* A map from the copied BBs dependence info cliques to
+     equivalents in the BBs duplicated to.  */
+  hash_map<dependence_hash, unsigned short> *dependence_map;
+};
 
 struct cfg_hooks
 {
@@ -112,7 +125,7 @@ struct cfg_hooks
   bool (*can_duplicate_block_p) (const_basic_block a);
 
   /* Duplicate block A.  */
-  basic_block (*duplicate_block) (basic_block a);
+  basic_block (*duplicate_block) (basic_block a, copy_bb_data *);
 
   /* Higher level functions representable by primitive operations above if
      we didn't have some oddities in RTL and Tree representations.  */
@@ -227,7 +240,8 @@ extern void tidy_fallthru_edges (void);
 extern void predict_edge (edge e, enum br_predictor predictor, int probability);
 extern bool predicted_by_p (const_basic_block bb, enum br_predictor predictor);
 extern bool can_duplicate_block_p (const_basic_block);
-extern basic_block duplicate_block (basic_block, edge, basic_block);
+extern basic_block duplicate_block (basic_block, edge, basic_block,
+                                   copy_bb_data * = NULL);
 extern bool block_ends_with_call_p (basic_block bb);
 extern bool empty_block_p (basic_block);
 extern basic_block split_block_before_cond_jump (basic_block);
index a8bec1d48af1e7acfcaf48c7518afca195abb7cf..4d7a491d032e590dd5c5ffd9e9c4dfb94d7aa035 100644 (file)
@@ -220,6 +220,10 @@ struct GTY ((chain_next ("%h.next"))) loop {
   /* True if the loop is part of an oacc kernels region.  */
   unsigned in_oacc_kernels_region : 1;
 
+  /* If this loop was inlined the main clique of the callee which does
+     not need remapping when copying the loop body.  */
+  unsigned short owned_clique;
+
   /* For SIMD loops, this is a unique identifier of the loop, referenced
      by IFN_GOMP_SIMD_VF, IFN_GOMP_SIMD_LANE and IFN_GOMP_SIMD_LAST_LANE
      builtins.  */
index 3e34aadd6911f781e558088b188f04074cccaf95..c520e5bc3dee36b189ee79a8adb3b67e9a4a5cff 100644 (file)
@@ -1023,6 +1023,7 @@ copy_loop_info (struct loop *loop, struct loop *target)
   target->warned_aggressive_loop_optimizations
     |= loop->warned_aggressive_loop_optimizations;
   target->in_oacc_kernels_region = loop->in_oacc_kernels_region;
+  target->owned_clique = loop->owned_clique;
 }
 
 /* Copies copy of LOOP as subloop of TARGET loop, placing newly
index 87783928bc4b7831d046558987e1b21c57cdf667..dcd31c14c43e1ed5cd4febc11fd7263e260fc470 100644 (file)
@@ -4204,7 +4204,7 @@ duplicate_insn_chain (rtx_insn *from, rtx_insn *to)
 /* Create a duplicate of the basic block BB.  */
 
 static basic_block
-cfg_layout_duplicate_bb (basic_block bb)
+cfg_layout_duplicate_bb (basic_block bb, copy_bb_data *)
 {
   rtx_insn *insn;
   basic_block new_bb;
@@ -5013,9 +5013,9 @@ rtl_can_remove_branch_p (const_edge e)
 }
 
 static basic_block
-rtl_duplicate_bb (basic_block bb)
+rtl_duplicate_bb (basic_block bb, copy_bb_data *id)
 {
-  bb = cfg_layout_duplicate_bb (bb);
+  bb = cfg_layout_duplicate_bb (bb, id);
   bb->aux = NULL;
   return bb;
 }
index 6b722b47965e92364e5e73206988fb08cc40a779..8b691ec77ab0f61e27bc2984b0b13cf063ce7985 100644 (file)
@@ -1864,9 +1864,13 @@ build_alias_set (scop_p scop)
   int i, j;
   int *all_vertices;
 
+  struct loop *nest
+    = find_common_loop (scop->scop_info->region.entry->dest->loop_father,
+                       scop->scop_info->region.exit->src->loop_father);
+
   FOR_EACH_VEC_ELT (scop->drs, i, dr1)
     for (j = i+1; scop->drs.iterate (j, &dr2); j++)
-      if (dr_may_alias_p (dr1->dr, dr2->dr, true))
+      if (dr_may_alias_p (dr1->dr, dr2->dr, nest))
        {
          add_edge (g, i, j);
          add_edge (g, j, i);
index 515aa532ce6ebebfb7b66b21eaac092a1230a61d..ed4955d3373f279f973067b86ded51501e04b8fe 100644 (file)
@@ -829,6 +829,7 @@ input_cfg (struct lto_input_block *ib, struct data_in *data_in,
 
       /* Read OMP SIMD related info.  */
       loop->safelen = streamer_read_hwi (ib);
+      loop->owned_clique = streamer_read_hwi (ib);
       loop->dont_vectorize = streamer_read_hwi (ib);
       loop->force_vectorize = streamer_read_hwi (ib);
       loop->simduid = stream_read_tree (ib, data_in);
index 893137270688bc9df8ec308570590888584e3314..6b74817c507102bdb930ed956ac977ac6e832b6a 100644 (file)
@@ -1914,6 +1914,7 @@ output_cfg (struct output_block *ob, struct function *fn)
 
       /* Write OMP SIMD related info.  */
       streamer_write_hwi (ob, loop->safelen);
+      streamer_write_hwi (ob, loop->owned_clique);
       streamer_write_hwi (ob, loop->dont_vectorize);
       streamer_write_hwi (ob, loop->force_vectorize);
       stream_write_tree (ob, loop->simduid, true);
index 15c7704ceb2e913dee0298c5753b37cc2e842e7b..689fbcf64ee6ff7d13f0b424dcddf1f14c9d1217 100644 (file)
@@ -129,7 +129,7 @@ along with GCC; see the file COPYING3.  If not see
      form followed by the data for the string.  */
 
 #define LTO_major_version 6
-#define LTO_minor_version 1
+#define LTO_minor_version 2
 
 typedef unsigned char  lto_decl_flags_t;
 
index ecc2fef037cc44a82f737baede8ab850b1cb5f60..ebc3a5be798e1a0fc69546b5d4e66612d2f68515 100644 (file)
@@ -1,3 +1,16 @@
+2019-09-05  Richard Biener  <rguenther@suse.de>
+
+       Backport from mainline
+       2019-05-06  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/90328
+       * gcc.dg/torture/pr90328.c: New testcase.
+
+       2019-02-22  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/87609
+       * gcc.dg/torture/restrict-7.c: New testcase.
+
 2019-09-04  Iain Sandoe  <iain@sandoe.co.uk>
 
        Backport from mainline.
diff --git a/gcc/testsuite/gcc.dg/torture/pr90328.c b/gcc/testsuite/gcc.dg/torture/pr90328.c
new file mode 100644 (file)
index 0000000..ccf8442
--- /dev/null
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+
+void g(int*__restrict x, int*y)
+{
+  *x = *y;
+}
+
+void __attribute__((noinline,noclone)) f(int* a,int* b)
+{
+  for(int i=0;i<1024;++i)
+    g(a+i,b+i);
+}
+
+int main()
+{
+  int x[1025];
+  for (int i = 0; i < 1025; ++i)
+    x[i] = i+1;
+  f(x+1, x);
+  for (int i = 0; i < 1025; ++i)
+    if (x[i] != 1)
+      __builtin_abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/restrict-7.c b/gcc/testsuite/gcc.dg/torture/restrict-7.c
new file mode 100644 (file)
index 0000000..1073710
--- /dev/null
@@ -0,0 +1,27 @@
+/* { dg-do run } */
+
+extern void abort (void);
+
+static inline __attribute__((always_inline)) void
+copy(int *restrict a, int *restrict b)
+{
+  *b = *a;
+  *a = 7;
+}
+
+void __attribute__((noinline))
+floppy(int mat[static 2], unsigned idxs[static 3])
+{
+  for (int i = 0; i < 3; i++)
+    copy(&mat[i%2], &mat[idxs[i]]);
+}
+
+int main()
+{
+  int mat[2] = {10, 20};
+  unsigned idxs[3] = {1, 0, 1};
+  floppy(mat, idxs);
+  if (mat[0] != 7 || mat[1] != 10)
+    abort ();
+  return 0;
+}
index db6c7fd84d940a486f45c1c90f6db75ba5008932..368b2e6427d1ff537872fb478617bfde7aa47a06 100644 (file)
@@ -5989,7 +5989,7 @@ gimple_can_duplicate_bb_p (const_basic_block bb ATTRIBUTE_UNUSED)
    preserve SSA form.  */
 
 static basic_block
-gimple_duplicate_bb (basic_block bb)
+gimple_duplicate_bb (basic_block bb, copy_bb_data *id)
 {
   basic_block new_bb;
   gimple_stmt_iterator gsi_tgt;
@@ -6053,6 +6053,39 @@ gimple_duplicate_bb (basic_block bb)
              && (!VAR_P (base) || !DECL_HAS_VALUE_EXPR_P (base)))
            DECL_NONSHAREABLE (base) = 1;
        }
+      /* If requested remap dependence info of cliques brought in
+         via inlining.  */
+      if (id)
+       for (unsigned i = 0; i < gimple_num_ops (copy); ++i)
+         {
+           tree op = gimple_op (copy, i);
+           if (!op)
+             continue;
+           if (TREE_CODE (op) == ADDR_EXPR
+               || TREE_CODE (op) == WITH_SIZE_EXPR)
+             op = TREE_OPERAND (op, 0);
+           while (handled_component_p (op))
+             op = TREE_OPERAND (op, 0);
+           if ((TREE_CODE (op) == MEM_REF
+                || TREE_CODE (op) == TARGET_MEM_REF)
+               && MR_DEPENDENCE_CLIQUE (op) > 1
+               && MR_DEPENDENCE_CLIQUE (op) != bb->loop_father->owned_clique)
+             {
+               if (!id->dependence_map)
+                 id->dependence_map = new hash_map<dependence_hash,
+                                                   unsigned short>;
+               bool existed;
+               unsigned short &newc = id->dependence_map->get_or_insert
+                   (MR_DEPENDENCE_CLIQUE (op), &existed);
+               if (!existed)
+                 {
+                   gcc_assert (MR_DEPENDENCE_CLIQUE (op) <= cfun->last_clique);
+                   newc = ++cfun->last_clique;
+                 }
+               MR_DEPENDENCE_CLIQUE (op) = newc;
+             }
+         }
 
       /* Create new names for all the definitions created by COPY and
         add replacement mappings for each new name.  */
index cb3b3de3e0471c078d53adf39094d06c6837fc42..27d2a95b6ac1d52a6e6e2baa983fdc7917aeaad8 100644 (file)
@@ -977,7 +977,9 @@ struct GTY(()) tree_base {
        expression trees and specify known data non-dependences.  For
        two memory references in a function they are known to not
        alias if dependence_info.clique are equal and dependence_info.base
-       are distinct.  */
+       are distinct.  Clique number zero means there is no information,
+       clique number one is populated from function global information
+       and thus needs no remapping on transforms like loop unrolling.  */
     struct {
       unsigned short clique;
       unsigned short base;
index a349e3ec5f12731f9b9618baecd99728cfaa623b..c942c0a38188b4405186be2b0b8be029711fae1f 100644 (file)
@@ -1396,7 +1396,7 @@ object_address_invariant_in_loop_p (const struct loop *loop, const_tree obj)
 
 bool
 dr_may_alias_p (const struct data_reference *a, const struct data_reference *b,
-               bool loop_nest)
+               struct loop *loop_nest)
 {
   tree addr_a = DR_BASE_OBJECT (a);
   tree addr_b = DR_BASE_OBJECT (b);
@@ -1420,6 +1420,11 @@ dr_may_alias_p (const struct data_reference *a, const struct data_reference *b,
 
   if ((TREE_CODE (addr_a) == MEM_REF || TREE_CODE (addr_a) == TARGET_MEM_REF)
       && (TREE_CODE (addr_b) == MEM_REF || TREE_CODE (addr_b) == TARGET_MEM_REF)
+      /* For cross-iteration dependences the cliques must be valid for the
+        whole loop, not just individual iterations.  */
+      && (!loop_nest
+         || MR_DEPENDENCE_CLIQUE (addr_a) == 1
+         || MR_DEPENDENCE_CLIQUE (addr_a) == loop_nest->owned_clique)
       && MR_DEPENDENCE_CLIQUE (addr_a) == MR_DEPENDENCE_CLIQUE (addr_b)
       && MR_DEPENDENCE_BASE (addr_a) != MR_DEPENDENCE_BASE (addr_b))
     return false;
@@ -1500,7 +1505,7 @@ initialize_data_dependence_relation (struct data_reference *a,
     }
 
   /* If the data references do not alias, then they are independent.  */
-  if (!dr_may_alias_p (a, b, loop_nest.exists ()))
+  if (!dr_may_alias_p (a, b, loop_nest.exists () ? loop_nest[0] : NULL))
     {
       DDR_ARE_DEPENDENT (res) = chrec_known;
       return res;
index 9003ea54a2d75cd7b1939d253f8457984213a54c..18d0027500a920db755d0b5a663c9370f9dd5900 100644 (file)
@@ -338,7 +338,7 @@ extern tree find_data_references_in_bb (struct loop *, basic_block,
                                         vec<data_reference_p> *);
 
 extern bool dr_may_alias_p (const struct data_reference *,
-                           const struct data_reference *, bool);
+                           const struct data_reference *, struct loop *);
 extern bool dr_equal_offsets_p (struct data_reference *,
                                 struct data_reference *);
 
index cf87409baa2e9a048867c4a66c4e1f7f909d3182..151c1d477e2d6224428363fc591bf89eb4bc552f 100644 (file)
@@ -948,7 +948,12 @@ remap_dependence_clique (copy_body_data *id, unsigned short clique)
   bool existed;
   unsigned short &newc = id->dependence_map->get_or_insert (clique, &existed);
   if (!existed)
-    newc = ++cfun->last_clique;
+    {
+      /* Clique 1 is reserved for local ones set by PTA.  */
+      if (cfun->last_clique == 0)
+       cfun->last_clique = 1;
+      newc = ++cfun->last_clique;
+    }
   return newc;
 }
 
@@ -2718,7 +2723,11 @@ copy_loops (copy_body_data *id,
              dest_loop->simduid = remap_decl (src_loop->simduid, id);
              cfun->has_simduid_loops = true;
            }
-
+         if (id->src_cfun->last_clique != 0)
+           dest_loop->owned_clique
+             = remap_dependence_clique (id,
+                                        src_loop->owned_clique
+                                        ? src_loop->owned_clique : 1);
          /* Recurse.  */
          copy_loops (id, dest_loop, src_loop);
        }
index afe26979fbf81ab8bcf8f4fcea0dd974d5dfbf41..148afd4fcec06bfd730653c4d2e4391ff70a316a 100644 (file)
@@ -7365,7 +7365,11 @@ maybe_set_dependence_info (tree ref, tree ptr,
       if (MR_DEPENDENCE_CLIQUE (ref) == 0)
        {
          if (clique == 0)
-           clique = ++cfun->last_clique;
+           {
+             if (cfun->last_clique == 0)
+               cfun->last_clique = 1;
+             clique = 1;
+           }
          if (restrict_var->ruid == 0)
            restrict_var->ruid = ++last_ruid;
          MR_DEPENDENCE_CLIQUE (ref) = clique;
@@ -7376,12 +7380,42 @@ maybe_set_dependence_info (tree ref, tree ptr,
   return false;
 }
 
+/* Clear dependence info for the clique DATA.  */
+
+static bool
+clear_dependence_clique (gimple *, tree base, tree, void *data)
+{
+  unsigned short clique = (uintptr_t)data;
+  if ((TREE_CODE (base) == MEM_REF
+       || TREE_CODE (base) == TARGET_MEM_REF)
+      && MR_DEPENDENCE_CLIQUE (base) == clique)
+    {
+      MR_DEPENDENCE_CLIQUE (base) = 0;
+      MR_DEPENDENCE_BASE (base) = 0;
+    }
+
+  return false;
+}
+
 /* Compute the set of independend memory references based on restrict
    tags and their conservative propagation to the points-to sets.  */
 
 static void
 compute_dependence_clique (void)
 {
+  /* First clear the special "local" clique.  */
+  basic_block bb;
+  if (cfun->last_clique != 0)
+    FOR_EACH_BB_FN (bb, cfun)
+      for (gimple_stmt_iterator gsi = gsi_start_bb (bb);
+          !gsi_end_p (gsi); gsi_next (&gsi))
+       {
+         gimple *stmt = gsi_stmt (gsi);
+         walk_stmt_load_store_ops (stmt, (void *)(uintptr_t) 1,
+                                   clear_dependence_clique,
+                                   clear_dependence_clique);
+       }
+
   unsigned short clique = 0;
   unsigned short last_ruid = 0;
   bitmap rvars = BITMAP_ALLOC (NULL);