diff mbox

Fix PR78348

Message ID alpine.LSU.2.11.1611160936360.5294@t29.fhfr.qr
State New
Headers show

Commit Message

Richard Biener Nov. 16, 2016, 8:38 a.m. UTC
This should fix a performance regression caused by recent loop 
distribution improvements.  It trivially uses dependence analysis
(in addition to the existing alias oracle query) to determine
if we can use memcpy instead of memmove (no attempt is made yet to
cover the case where the dependence distance is greater than
the copied region).

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

Richard.

2016-11-16  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/78348
	* tree-loop-distribution.c (enum partition_kind): Add PKIND_MEMMOVE.
	(generate_memcpy_builtin): Honor PKIND_MEMCPY on the partition.
	(classify_partition): Set PKIND_MEMCPY if dependence analysis
	revealed no dependency, PKIND_MEMMOVE otherwise.

	* gcc.dg/tree-ssa/ldist-24.c: New testcase.
diff mbox

Patch

Index: gcc/tree-loop-distribution.c
===================================================================
--- gcc/tree-loop-distribution.c	(revision 242408)
+++ gcc/tree-loop-distribution.c	(working copy)
@@ -466,7 +466,7 @@  build_rdg (vec<loop_p> loop_nest, contro
 
 
 enum partition_kind {
-    PKIND_NORMAL, PKIND_MEMSET, PKIND_MEMCPY
+    PKIND_NORMAL, PKIND_MEMSET, PKIND_MEMCPY, PKIND_MEMMOVE
 };
 
 struct partition
@@ -875,10 +875,11 @@  generate_memcpy_builtin (struct loop *lo
 				       false, GSI_CONTINUE_LINKING);
   dest = build_addr_arg_loc (loc, partition->main_dr, nb_bytes);
   src = build_addr_arg_loc (loc, partition->secondary_dr, nb_bytes);
-  if (ptr_derefs_may_alias_p (dest, src))
-    kind = BUILT_IN_MEMMOVE;
-  else
+  if (partition->kind == PKIND_MEMCPY
+      || ! ptr_derefs_may_alias_p (dest, src))
     kind = BUILT_IN_MEMCPY;
+  else
+    kind = BUILT_IN_MEMMOVE;
 
   dest = force_gimple_operand_gsi (&gsi, dest, true, NULL_TREE,
 				   false, GSI_CONTINUE_LINKING);
@@ -970,6 +971,7 @@  generate_code_for_partition (struct loop
       break;
 
     case PKIND_MEMCPY:
+    case PKIND_MEMMOVE:
       generate_memcpy_builtin (loop, partition);
       break;
 
@@ -1166,10 +1168,12 @@  classify_partition (loop_p loop, struct
 		  return;
 		}
 	    }
+	  partition->kind = PKIND_MEMMOVE;
 	}
+      else
+	partition->kind = PKIND_MEMCPY;
       free_dependence_relation (ddr);
       loops.release ();
-      partition->kind = PKIND_MEMCPY;
       partition->main_dr = single_store;
       partition->secondary_dr = single_load;
       partition->niter = nb_iter;
Index: gcc/testsuite/gcc.dg/tree-ssa/ldist-24.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/ldist-24.c	(revision 0)
+++ gcc/testsuite/gcc.dg/tree-ssa/ldist-24.c	(revision 0)
@@ -0,0 +1,24 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-ldist-details" } */
+
+typedef struct S {
+    double z[8][25];
+    double x1[8][40];
+    double x2[8][40];
+    double y[8][35];
+} S;
+
+S * par;
+void foo ()
+{
+  int i, j;
+  for (i = 0; i<8; i++)
+    for (j = 0; j<35; j++)
+      {
+	par->x1[i][j] = par->x2[i][j];
+	par->x2[i][j] = 0.0;
+      }
+}
+
+/* { dg-final { scan-tree-dump "generated memcpy" "ldist" } } */
+/* { dg-final { scan-tree-dump "generated memset zero" "ldist" } } */