This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] Fix minor SLSR pessimization


Hi,

an user reported that, for pairs of consecutive memory accesses, the SLSR pass 
can slightly pessimize the generated code at -O2 on the x86 architecture:

struct x
{
  int a[16];
  int b[16];
};

void
set (struct x *p, unsigned int n, int i)
{
  p->a[n] = i;
  p->b[n] = i;
}

is compiled with SLSR enabled into:

        leaq    (%rdi,%rsi,4), %rax
        movl    %edx, (%rax)
        movl    %edx, 64(%rax)

which is slightly worse than the expected:

        movl    %edx, (%rdi,%rsi,4)
        movl    %edx, 64(%rdi,%rsi,4)

The attached patch is a tentative fix which doesn't seem to break anything.

Tested on x86_64-suse-linux, OK for the mainline?


2019-08-02  Eric Botcazou  <ebotcazou@adacore.com>

	* gimple-ssa-strength-reduction.c (valid_mem_ref_cand_p): New function.
	(replace_ref): Do not replace a chain of only two candidates which are
	valid memory references.


2019-08-02  Eric Botcazou  <ebotcazou@adacore.com>

	* gcc.dg/tree-ssa/slsr-42.c: New test.

-- 
Eric Botcazou
Index: gimple-ssa-strength-reduction.c
===================================================================
--- gimple-ssa-strength-reduction.c	(revision 273907)
+++ gimple-ssa-strength-reduction.c	(working copy)
@@ -1999,6 +1999,23 @@ replace_ref (tree *expr, slsr_cand_t c)
   update_stmt (c->cand_stmt);
 }
 
+/* Return true if CAND_REF candidate C is a valid memory reference.  */
+
+static bool
+valid_mem_ref_cand_p (slsr_cand_t c)
+{
+  if (TREE_CODE (TREE_OPERAND (c->stride, 1)) != INTEGER_CST)
+    return false;
+
+  struct mem_address addr
+    = { NULL_TREE, c->base_expr, TREE_OPERAND (c->stride, 0),
+	TREE_OPERAND (c->stride, 1), wide_int_to_tree (sizetype, c->index) };
+
+  return
+    valid_mem_ref_p (TYPE_MODE (c->cand_type), TYPE_ADDR_SPACE (c->cand_type),
+		     &addr);
+}
+
 /* Replace CAND_REF candidate C, each sibling of candidate C, and each
    dependent of candidate C with an equivalent strength-reduced data
    reference.  */
@@ -2006,6 +2023,16 @@ replace_ref (tree *expr, slsr_cand_t c)
 static void
 replace_refs (slsr_cand_t c)
 {
+  /* Replacing a chain of only 2 candidates which are valid memory references
+     is generally counter-productive because you cannot recoup the additional
+     calculation added in front of them.  */
+  if (c->basis == 0
+      && c->dependent
+      && !lookup_cand (c->dependent)->dependent
+      && valid_mem_ref_cand_p (c)
+      && valid_mem_ref_cand_p (lookup_cand (c->dependent)))
+    return;
+
   if (dump_file && (dump_flags & TDF_DETAILS))
     {
       fputs ("Replacing reference: ", dump_file);
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-slsr-details" } */

struct x
{
  int a[16];
  int b[16];
};

void
set (struct x *p, unsigned int n, int i)
{
  p->a[n] = i;
  p->b[n] = i;
}

/* { dg-final { scan-tree-dump-not "Replacing reference: " "slsr"  { target i?86-*-* x86_64-*-* } } } */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]