diff mbox series

[2/2] Fix PR87609

Message ID alpine.LSU.2.20.1902220935110.23386@zhemvz.fhfr.qr
State New
Headers show
Series [1/2] Fix PR87609 | expand

Commit Message

Richard Biener Feb. 22, 2019, 8:36 a.m. UTC
This is the original patch adjusted to not remap clique == 1.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

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.
diff mbox series

Patch

Index: gcc/cfghooks.c
===================================================================
--- gcc/cfghooks.c	(revision 269067)
+++ gcc/cfghooks.c	(working copy)
@@ -1066,7 +1066,7 @@  can_duplicate_block_p (const_basic_block
    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;
@@ -1082,7 +1082,7 @@  duplicate_block (basic_block bb, edge e,
 
   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);
 
@@ -1337,6 +1337,7 @@  copy_bbs (basic_block *bbs, unsigned n,
   unsigned i, j;
   basic_block bb, new_bb, dom_bb;
   edge e;
+  copy_bb_data id;
 
   /* Mark the blocks to be copied.  This is used by edge creation hooks
      to decide whether to reallocate PHI nodes capacity to avoid reallocating
@@ -1349,7 +1350,7 @@  copy_bbs (basic_block *bbs, unsigned n,
     {
       /* 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;
       if (bb->loop_father)
 	{
Index: gcc/cfghooks.h
===================================================================
--- gcc/cfghooks.h	(revision 269067)
+++ gcc/cfghooks.h	(working copy)
@@ -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: gcc/cfgrtl.c
===================================================================
--- gcc/cfgrtl.c	(revision 269067)
+++ gcc/cfgrtl.c	(working copy)
@@ -4250,7 +4250,7 @@  duplicate_insn_chain (rtx_insn *from, rt
 /* 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;
@@ -5080,9 +5080,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: gcc/testsuite/gcc.dg/torture/restrict-7.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/restrict-7.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/torture/restrict-7.c	(working copy)
@@ -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: gcc/tree-cfg.c
===================================================================
--- gcc/tree-cfg.c	(revision 269067)
+++ gcc/tree-cfg.c	(working copy)
@@ -6164,7 +6164,7 @@  gimple_can_duplicate_bb_p (const_basic_b
    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;
@@ -6228,6 +6228,36 @@  gimple_duplicate_bb (basic_block bb)
 	      && (!VAR_P (base) || !DECL_HAS_VALUE_EXPR_P (base)))
 	    DECL_NONSHAREABLE (base) = 1;
 	}
+ 
+      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) != 0)
+	      {
+		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.  */