Re: [pushed] [PR103541] RA: Implement reuse of equivalent memory for caller saves optimization (version 2)

2023-02-10 Thread Hans-Peter Nilsson via Gcc-patches
> From: Vladimir Makarov via Gcc-patches 
> Date: Thu, 9 Feb 2023 22:49:34 +0100

> The patch was successfully bootstrapped (--enable-languages=all) and 
> tested on x86, x86-64, aarch64

Sorry, but this (also) caused test-suite regressions,
perhaps just for cris-elf.  I've opened 108754 and will
assist, looking closer.

brgds, H-P


[pushed] [PR103541] RA: Implement reuse of equivalent memory for caller saves optimization (version 2)

2023-02-09 Thread Vladimir Makarov via Gcc-patches

This is another try to solve

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103541

The patch was successfully bootstrapped (--enable-languages=all) and 
tested on x86, x86-64, aarch64
commit 1ad898d18904ac68432ba9b8ffa2b083d007cc2d
Author: Vladimir N. Makarov 
Date:   Thu Feb 9 15:18:48 2023 -0500

RA: Implement reuse of equivalent memory for caller saves optimization (2nd version)

The test pr103541.c shows opportunity to reuse memory with constant address for
caller saves optimization for constant or pure function call.  The patch
implements the memory reuse.

PR rtl-optimization/103541
PR rtl-optimization/108711

gcc/ChangeLog:

* ira.h (struct ira_reg_equiv_s): Add new field caller_save_p.
* ira.cc (validate_equiv_mem): Check memref address variance.
(no_equiv): Clear caller_save_p flag.
(update_equiv_regs): Define caller save equivalence for
valid_combine.
(setup_reg_equiv): Clear defined_p flag for caller save equivalence.
* lra-constraints.cc (lra_copy_reg_equiv): Add new arg
call_save_p.  Use caller save equivalence depending on the arg.
(split_reg): Adjust the call.

gcc/testsuite/ChangeLog:

* gcc.target/i386/pr103541.c: New.
* g++.target/i386/pr108711.C: New.

diff --git a/gcc/ira.cc b/gcc/ira.cc
index 66df03e8a59..6143db06c52 100644
--- a/gcc/ira.cc
+++ b/gcc/ira.cc
@@ -3070,6 +3070,8 @@ validate_equiv_mem_from_store (rtx dest, const_rtx set ATTRIBUTE_UNUSED,
 info->equiv_mem_modified = true;
 }
 
+static int equiv_init_varies_p (rtx x);
+
 enum valid_equiv { valid_none, valid_combine, valid_reload };
 
 /* Verify that no store between START and the death of REG invalidates
@@ -3113,7 +3115,8 @@ validate_equiv_mem (rtx_insn *start, rtx reg, rtx memref)
 	 been changed and all hell breaks loose.  */
 	  ret = valid_combine;
 	  if (!MEM_READONLY_P (memref)
-	  && !RTL_CONST_OR_PURE_CALL_P (insn))
+	  && (!RTL_CONST_OR_PURE_CALL_P (insn)
+		  || equiv_init_varies_p (XEXP (memref, 0
 	return valid_none;
 	}
 
@@ -3414,6 +3417,7 @@ no_equiv (rtx reg, const_rtx store ATTRIBUTE_UNUSED,
   if (reg_equiv[regno].is_arg_equivalence)
 return;
   ira_reg_equiv[regno].defined_p = false;
+  ira_reg_equiv[regno].caller_save_p = false;
   ira_reg_equiv[regno].init_insns = NULL;
   for (; list; list = list->next ())
 {
@@ -3766,7 +3770,18 @@ update_equiv_regs (void)
 		{
 		  replacement = copy_rtx (SET_SRC (set));
 		  if (validity == valid_reload)
-		note = set_unique_reg_note (insn, REG_EQUIV, replacement);
+		{
+		  note = set_unique_reg_note (insn, REG_EQUIV, replacement);
+		}
+		  else
+		{
+		  /* We still can use this equivalence for caller save
+			 optimization in LRA.  Mark this.  */
+		  ira_reg_equiv[regno].caller_save_p = true;
+		  ira_reg_equiv[regno].init_insns
+			= gen_rtx_INSN_LIST (VOIDmode, insn,
+	 ira_reg_equiv[regno].init_insns);
+		}
 		}
 	}
 
@@ -4156,7 +4171,7 @@ setup_reg_equiv (void)
 		   legitimate, we ignore such REG_EQUIV notes.  */
 		if (memory_operand (x, VOIDmode))
 		  {
-		ira_reg_equiv[i].defined_p = true;
+		ira_reg_equiv[i].defined_p = !ira_reg_equiv[i].caller_save_p;
 		ira_reg_equiv[i].memory = x;
 		continue;
 		  }
diff --git a/gcc/ira.h b/gcc/ira.h
index 58b50dbe8a2..3d35025a46e 100644
--- a/gcc/ira.h
+++ b/gcc/ira.h
@@ -175,8 +175,11 @@ extern struct target_ira *this_target_ira;
 /* Major structure describing equivalence info for a pseudo.  */
 struct ira_reg_equiv_s
 {
-  /* True if we can use this equivalence.  */
+  /* True if we can use this as a general equivalence.  */
   bool defined_p;
+  /* True if we can use this equivalence only for caller save/restore
+ location.  */
+  bool caller_save_p;
   /* True if the usage of the equivalence is profitable.  */
   bool profitable_p;
   /* Equiv. memory, constant, invariant, and initializing insns of
diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc
index 7bffbc07ee2..dd4f68bbfc0 100644
--- a/gcc/lra-constraints.cc
+++ b/gcc/lra-constraints.cc
@@ -5771,14 +5771,17 @@ choose_split_class (enum reg_class allocno_class,
   return best_cl;
 }
 
-/* Copy any equivalence information from ORIGINAL_REGNO to NEW_REGNO.
-   It only makes sense to call this function if NEW_REGNO is always
-   equal to ORIGINAL_REGNO.  */
+/* Copy any equivalence information from ORIGINAL_REGNO to NEW_REGNO.  It only
+   makes sense to call this function if NEW_REGNO is always equal to
+   ORIGINAL_REGNO.  Set up defined_p flag when caller_save_p flag is set up and
+   CALL_SAVE_P is true.  */
 
 static void
-lra_copy_reg_equiv (unsigned int new_regno, unsigned int original_regno)
+lra_copy_reg_equiv (unsigned int new_regno, unsigned int original_regno,
+		bool call_save_p)
 {
-  if (!ira_reg_equiv[original_regno].defined_p)

Re: [pushed] [PR103541] RA: Implement reuse of equivalent memory for caller saves optimization

2023-02-08 Thread Vladimir Makarov via Gcc-patches



On 2/7/23 22:48, Andrew Pinski wrote:

On Tue, Feb 7, 2023 at 6:08 AM Vladimir Makarov via Gcc-patches
 wrote:

The following patch solves

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103541

The patch was successfully bootstrapped and tested on x86-64, aarch64,
and ppc64le.

What languages did you test? Because I think I am getting a bootstrap
failure while building libgo in 32bit x86 due to this patch.
I used c and c++ only.  Sorry for all the troubles with the patch. I've 
just reverted the patch and I will try to resolve the issue with it.




Re: [pushed] [PR103541] RA: Implement reuse of equivalent memory for caller saves optimization

2023-02-07 Thread Andrew Pinski via Gcc-patches
On Tue, Feb 7, 2023 at 6:08 AM Vladimir Makarov via Gcc-patches
 wrote:
>
> The following patch solves
>
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103541
>
> The patch was successfully bootstrapped and tested on x86-64, aarch64,
> and ppc64le.

What languages did you test? Because I think I am getting a bootstrap
failure while building libgo in 32bit x86 due to this patch.

libtool: compile:
/home/apinski/src/upstream-gcc-git/gcc/objdir/./gcc/gccgo
-B/home/apinski/src/upstream-gcc-git/gcc/objdir/./gcc/
-B/home/apinski/upstream-gcc/x86_64-pc-linux-gnu/bin/
-B/home/apinski/upstream-gcc/x86_64-pc-linux-gnu/lib/ -isystem
/home/apinski/upstream-gcc/x86_64-pc-linux-gnu/include -isystem
/home/apinski/upstream-gcc/x86_64-pc-linux-gnu/sys-include
-minline-all-stringops -O2 -g -m32 -I . -c -fgo-pkgpath=reflect
/home/apinski/src/upstream-gcc-git/gcc/libgo/go/reflect/deepequal.go
/home/apinski/src/upstream-gcc-git/gcc/libgo/go/reflect/eqtype.go
/home/apinski/src/upstream-gcc-git/gcc/libgo/go/reflect/makefunc.go
/home/apinski/src/upstream-gcc-git/gcc/libgo/go/reflect/makefunc_ffi.go
/home/apinski/src/upstream-gcc-git/gcc/libgo/go/reflect/swapper.go
/home/apinski/src/upstream-gcc-git/gcc/libgo/go/reflect/type.go
/home/apinski/src/upstream-gcc-git/gcc/libgo/go/reflect/value.go
/home/apinski/src/upstream-gcc-git/gcc/libgo/go/reflect/visiblefields.go
 -fPIC -o .libs/reflect.o
during RTL pass: reload
/home/apinski/src/upstream-gcc-git/gcc/libgo/go/reflect/type.go: In
function ‘reflect.rtype.Method’:
/home/apinski/src/upstream-gcc-git/gcc/libgo/go/reflect/type.go:604:1:
internal compiler error: in get_equiv, at lra-constraints.cc:534
  604 | func (t *rtype) Method(i int) (m Method) {
  | ^
0x7f9cfb get_equiv
/home/apinski/src/upstream-gcc-git/gcc/gcc/lra-constraints.cc:534
0xde58d4 lra_constraints(bool)
/home/apinski/src/upstream-gcc-git/gcc/gcc/lra-constraints.cc:5052
0xdd2532 lra(_IO_FILE*)
/home/apinski/src/upstream-gcc-git/gcc/gcc/lra.cc:2375
0xd8a101 do_reload
/home/apinski/src/upstream-gcc-git/gcc/gcc/ira.cc:5955
0xd8a101 execute
/home/apinski/src/upstream-gcc-git/gcc/gcc/ira.cc:6141
Please submit a full bug report, with preprocessed source (by using
-freport-bug).
Please include the complete backtrace with any bug report.
See  for instructions.
Makefile:3043: recipe for target 'reflect.lo' failed
make[7]: *** [reflect.lo] Error 1


Thanks,
Andrew Pinski


[pushed] [PR103541] RA: Implement reuse of equivalent memory for caller saves optimization

2023-02-07 Thread Vladimir Makarov via Gcc-patches

The following patch solves

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103541

The patch was successfully bootstrapped and tested on x86-64, aarch64, 
and ppc64le.
commit f661c0bb6371f355966a67b5ce71398e80792948
Author: Vladimir N. Makarov 
Date:   Tue Feb 7 08:27:36 2023 -0500

RA: Implement reuse of equivalent memory for caller saves optimization

The test case shows opportunity to reuse memory with constant address for
caller saves optimization for constant or pure function call.  The patch
implements the memory reuse.

PR rtl-optimization/103541

gcc/ChangeLog:

* ira.h (struct ira_reg_equiv_s): Add new field caller_save_p.
* ira.cc (validate_equiv_mem): Check memref address variance.
(update_equiv_regs): Define caller save equivalence for
valid_combine.
(setup_reg_equiv): Clear defined_p flag for caller save equivalence.
* lra-constraints.cc (lra_copy_reg_equiv): Add new arg
call_save_p.  Use caller save equivalence depending on the arg.
(split_reg): Adjust the call.

gcc/testsuite/ChangeLog:

* gcc.target/i386/pr103541.c: New.

diff --git a/gcc/ira.cc b/gcc/ira.cc
index 66df03e8a59..c6ee46286bc 100644
--- a/gcc/ira.cc
+++ b/gcc/ira.cc
@@ -3070,6 +3070,8 @@ validate_equiv_mem_from_store (rtx dest, const_rtx set ATTRIBUTE_UNUSED,
 info->equiv_mem_modified = true;
 }
 
+static int equiv_init_varies_p (rtx x);
+
 enum valid_equiv { valid_none, valid_combine, valid_reload };
 
 /* Verify that no store between START and the death of REG invalidates
@@ -3113,7 +3115,8 @@ validate_equiv_mem (rtx_insn *start, rtx reg, rtx memref)
 	 been changed and all hell breaks loose.  */
 	  ret = valid_combine;
 	  if (!MEM_READONLY_P (memref)
-	  && !RTL_CONST_OR_PURE_CALL_P (insn))
+	  && (!RTL_CONST_OR_PURE_CALL_P (insn)
+		  || equiv_init_varies_p (XEXP (memref, 0
 	return valid_none;
 	}
 
@@ -3766,7 +3769,18 @@ update_equiv_regs (void)
 		{
 		  replacement = copy_rtx (SET_SRC (set));
 		  if (validity == valid_reload)
-		note = set_unique_reg_note (insn, REG_EQUIV, replacement);
+		{
+		  note = set_unique_reg_note (insn, REG_EQUIV, replacement);
+		}
+		  else
+		{
+		  /* We still can use this equivalence for caller save
+			 optimization in LRA.  Mark this.  */
+		  ira_reg_equiv[regno].caller_save_p = true;
+		  ira_reg_equiv[regno].init_insns
+			= gen_rtx_INSN_LIST (VOIDmode, insn,
+	 ira_reg_equiv[regno].init_insns);
+		}
 		}
 	}
 
@@ -4156,7 +4170,7 @@ setup_reg_equiv (void)
 		   legitimate, we ignore such REG_EQUIV notes.  */
 		if (memory_operand (x, VOIDmode))
 		  {
-		ira_reg_equiv[i].defined_p = true;
+		ira_reg_equiv[i].defined_p = !ira_reg_equiv[i].caller_save_p;
 		ira_reg_equiv[i].memory = x;
 		continue;
 		  }
diff --git a/gcc/ira.h b/gcc/ira.h
index 58b50dbe8a2..3d35025a46e 100644
--- a/gcc/ira.h
+++ b/gcc/ira.h
@@ -175,8 +175,11 @@ extern struct target_ira *this_target_ira;
 /* Major structure describing equivalence info for a pseudo.  */
 struct ira_reg_equiv_s
 {
-  /* True if we can use this equivalence.  */
+  /* True if we can use this as a general equivalence.  */
   bool defined_p;
+  /* True if we can use this equivalence only for caller save/restore
+ location.  */
+  bool caller_save_p;
   /* True if the usage of the equivalence is profitable.  */
   bool profitable_p;
   /* Equiv. memory, constant, invariant, and initializing insns of
diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc
index 7bffbc07ee2..dd4f68bbfc0 100644
--- a/gcc/lra-constraints.cc
+++ b/gcc/lra-constraints.cc
@@ -5771,14 +5771,17 @@ choose_split_class (enum reg_class allocno_class,
   return best_cl;
 }
 
-/* Copy any equivalence information from ORIGINAL_REGNO to NEW_REGNO.
-   It only makes sense to call this function if NEW_REGNO is always
-   equal to ORIGINAL_REGNO.  */
+/* Copy any equivalence information from ORIGINAL_REGNO to NEW_REGNO.  It only
+   makes sense to call this function if NEW_REGNO is always equal to
+   ORIGINAL_REGNO.  Set up defined_p flag when caller_save_p flag is set up and
+   CALL_SAVE_P is true.  */
 
 static void
-lra_copy_reg_equiv (unsigned int new_regno, unsigned int original_regno)
+lra_copy_reg_equiv (unsigned int new_regno, unsigned int original_regno,
+		bool call_save_p)
 {
-  if (!ira_reg_equiv[original_regno].defined_p)
+  if (!ira_reg_equiv[original_regno].defined_p
+  && !(call_save_p && ira_reg_equiv[original_regno].caller_save_p))
 return;
 
   ira_expand_reg_equiv ();
@@ -5958,7 +5961,7 @@ split_reg (bool before_p, int original_regno, rtx_insn *insn,
  rematerializing the original value instead of spilling to the stack.  */
   if (!HARD_REGISTER_NUM_P (original_regno)
   && mode == PSEUDO_REGNO_MODE (original_regno))
-lra_copy_reg_equiv (new_regno, original_regno);
+