public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Store complicated const into pool
@ 2022-05-10  9:28 Jiufu Guo
  2022-05-23  1:39 ` [PATCH V2]rs6000: Store complicated constant " Jiufu Guo
  0 siblings, 1 reply; 2+ messages in thread
From: Jiufu Guo @ 2022-05-10  9:28 UTC (permalink / raw)
  To: gcc-patches; +Cc: segher, dje.gcc, linkw, guojiufu

Hi,

To set a constant to a reg, one way is building the constant through
instructions, like lis/ori/sldi...  Another way is loading it from
the constant pool through instruction 'ld'(or 'pld' for P10).

Loading a constant may need 2 instructions (or just 'pld' on P10),
and according to testing, if building the constant needs more than 2
instructions (or more than 1 instruction on P10), it is faster to load
it from constant pool.

This patch reduces the threshold of instruction number for storing
constant to pool.

And after some discussions in the previous review:
https://gcc.gnu.org/pipermail/gcc-patches/2022-March/591509.html
This patch simply updates the rtx_cost hook to accurate cost on
constant by using 'COSTS_N_INSNS' with 'num_insns_constant'.  This
could avoid CSE eliminate constant loading.


Bootstrap and regtest pass on ppc64le and ppc64.
Is this ok for trunk?


BR,
Jiufu


	PR target/63281

gcc/ChangeLog:

	* config/rs6000/rs6000.cc (rs6000_cannot_force_const_mem):
	Exclude rtx with code 'HIGH'.
	(rs6000_emit_move): Update insn num threshold for constant
	pool storing.
	(rs6000_rtx_costs): Update insn number for constant building.

gcc/testsuite/ChangeLog:

	* gcc.target/powerpc/medium_offset.c: Update.
	* gcc.target/powerpc/pr93012.c: Update.
	* gcc.target/powerpc/pr63281.c: New test.

---
 gcc/config/rs6000/rs6000.cc                      | 15 ++++++++++++---
 gcc/testsuite/gcc.target/powerpc/medium_offset.c |  2 +-
 gcc/testsuite/gcc.target/powerpc/pr63281.c       | 11 +++++++++++
 gcc/testsuite/gcc.target/powerpc/pr93012.c       |  2 +-
 4 files changed, 25 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/powerpc/pr63281.c

diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index 4030864aa1a..e51a2242fe1 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -9714,8 +9714,9 @@ rs6000_init_stack_protect_guard (void)
 static bool
 rs6000_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
 {
-  if (GET_CODE (x) == HIGH
-      && GET_CODE (XEXP (x, 0)) == UNSPEC)
+  /* Exclude CONSTANT HIGH part.  e.g.
+     (high:DI (symbol_ref:DI ("var") [flags 0xc0] <var_decl>)).  */
+  if (GET_CODE (x) == HIGH)
     return true;
 
   /* A TLS symbol in the TOC cannot contain a sum.  */
@@ -10895,7 +10896,7 @@ rs6000_emit_move (rtx dest, rtx source, machine_mode mode)
 		    && FP_REGNO_P (REGNO (operands[0])))
 		   || !CONST_INT_P (operands[1])
 		   || (num_insns_constant (operands[1], mode)
-		       > (TARGET_CMODEL != CMODEL_SMALL ? 3 : 2)))
+		       > (TARGET_PREFIXED ? 1 : 2)))
 	       && !toc_relative_expr_p (operands[1], false, NULL, NULL)
 	       && (TARGET_CMODEL == CMODEL_SMALL
 		   || can_create_pseudo_p ()
@@ -21857,6 +21858,14 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code,
 
     case CONST_DOUBLE:
     case CONST_WIDE_INT:
+      /* Set a const to reg, it may needs a few insns.  */
+      if (outer_code == SET)
+	{
+	  *total = COSTS_N_INSNS (num_insns_constant (x, mode));
+	  return true;
+	}
+      /* FALLTHRU */
+
     case CONST:
     case HIGH:
     case SYMBOL_REF:
diff --git a/gcc/testsuite/gcc.target/powerpc/medium_offset.c b/gcc/testsuite/gcc.target/powerpc/medium_offset.c
index f29eba08c38..4889e8fa8ec 100644
--- a/gcc/testsuite/gcc.target/powerpc/medium_offset.c
+++ b/gcc/testsuite/gcc.target/powerpc/medium_offset.c
@@ -1,7 +1,7 @@
 /* { dg-do compile { target { powerpc*-*-* } } } */
 /* { dg-require-effective-target lp64 } */
 /* { dg-options "-O" } */
-/* { dg-final { scan-assembler-not "\\+4611686018427387904" } } */
+/* { dg-final { scan-assembler-times {\msldi|pld\M} 1 } } */
 
 static int x;
 
diff --git a/gcc/testsuite/gcc.target/powerpc/pr63281.c b/gcc/testsuite/gcc.target/powerpc/pr63281.c
new file mode 100644
index 00000000000..469a8f64400
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr63281.c
@@ -0,0 +1,11 @@
+/* PR target/63281 */
+/* { dg-do compile { target lp64 } } */
+/* { dg-options "-O2 -std=c99" } */
+
+void
+foo (unsigned long long *a)
+{
+  *a = 0x020805006106003;
+}
+
+/* { dg-final { scan-assembler-times {\mp?ld\M} 1 } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/pr93012.c b/gcc/testsuite/gcc.target/powerpc/pr93012.c
index 4f764d0576f..5afb4f79c45 100644
--- a/gcc/testsuite/gcc.target/powerpc/pr93012.c
+++ b/gcc/testsuite/gcc.target/powerpc/pr93012.c
@@ -10,4 +10,4 @@ unsigned long long mskh1() { return 0xffff9234ffff9234ULL; }
 unsigned long long mskl1() { return 0x2bcdffff2bcdffffULL; }
 unsigned long long mskse() { return 0xffff1234ffff1234ULL; }
 
-/* { dg-final { scan-assembler-times {\mrldimi\M} 7 } } */
+/* { dg-final { scan-assembler-times {\mrldimi|ld|pld\M} 7 } } */
-- 
2.25.1


^ permalink raw reply	[flat|nested] 2+ messages in thread

* [PATCH V2]rs6000: Store complicated constant into pool
  2022-05-10  9:28 [PATCH] Store complicated const into pool Jiufu Guo
@ 2022-05-23  1:39 ` Jiufu Guo
  0 siblings, 0 replies; 2+ messages in thread
From: Jiufu Guo @ 2022-05-23  1:39 UTC (permalink / raw)
  To: gcc-patches; +Cc: segher, dje.gcc, linkw


Hi,

And after some discussions in the previous review:
https://gcc.gnu.org/pipermail/gcc-patches/2022-March/591509.html
This patch simply updates the rtx_cost hook to accurate cost on
constant by using 'COSTS_N_INSNS' with 'num_insns_constant'.  This
could avoid CSE eliminate constant loading.

Compare with previous patch, this patch update cost for prefixed
load('pld') slightly faster.

To set a constant to a reg, one way is building the constant through
instructions, like lis/ori/sldi...  Another way is loading it from
the constant pool through instruction 'ld'(or 'pld' for P10).

Loading a constant may need 2 instructions (or just 'pld' on P10),
and according to testing, if building the constant needs more than 2
instructions (or more than 1 instruction on P10), it is faster to load
it from constant pool.

This patch reduces the threshold of instruction number for storing
constant to pool and update cost for constant and mem accessing.

Bootstrap and regtest pass on ppc64le and ppc64.
Is this ok for trunk?


BR,
Jiufu


	PR target/63281

gcc/ChangeLog:

	* config/rs6000/rs6000.cc (rs6000_cannot_force_const_mem):
	Exclude rtx with code 'HIGH'.
	(rs6000_emit_move): Update threshold of const insn.
	(rs6000_rtx_costs): Update cost of constant and mem.

gcc/testsuite/ChangeLog:

	* gcc.target/powerpc/medium_offset.c: Update.
	* gcc.target/powerpc/pr93012.c: Update.
	* gcc.target/powerpc/pr63281.c: New test.


---
 gcc/config/rs6000/rs6000.cc                   | 23 +++++++++++++++----
 .../gcc.target/powerpc/medium_offset.c        |  2 +-
 gcc/testsuite/gcc.target/powerpc/pr63281.c    | 11 +++++++++
 gcc/testsuite/gcc.target/powerpc/pr93012.c    |  2 +-
 4 files changed, 31 insertions(+), 7 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/powerpc/pr63281.c

diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index cd291f93019..90c91a8e1ea 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -9706,8 +9706,9 @@ rs6000_init_stack_protect_guard (void)
 static bool
 rs6000_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
 {
-  if (GET_CODE (x) == HIGH
-      && GET_CODE (XEXP (x, 0)) == UNSPEC)
+  /* Exclude CONSTANT HIGH part.  e.g.
+     (high:DI (symbol_ref:DI ("var") [flags 0xc0] <var_decl>)).  */
+  if (GET_CODE (x) == HIGH)
     return true;
 
   /* A TLS symbol in the TOC cannot contain a sum.  */
@@ -11139,7 +11140,7 @@ rs6000_emit_move (rtx dest, rtx source, machine_mode mode)
 		    && FP_REGNO_P (REGNO (operands[0])))
 		   || !CONST_INT_P (operands[1])
 		   || (num_insns_constant (operands[1], mode)
-		       > (TARGET_CMODEL != CMODEL_SMALL ? 3 : 2)))
+		       > (TARGET_PREFIXED ? 1 : 2)))
 	       && !toc_relative_expr_p (operands[1], false, NULL, NULL)
 	       && (TARGET_CMODEL == CMODEL_SMALL
 		   || can_create_pseudo_p ()
@@ -22101,6 +22102,14 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code,
 
     case CONST_DOUBLE:
     case CONST_WIDE_INT:
+      /* Set a const to reg, it may needs a few insns.  */
+      if (outer_code == SET)
+	{
+	  *total = COSTS_N_INSNS (num_insns_constant (x, mode));
+	  return true;
+	}
+      /* FALLTHRU */
+
     case CONST:
     case HIGH:
     case SYMBOL_REF:
@@ -22110,8 +22119,12 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code,
     case MEM:
       /* When optimizing for size, MEM should be slightly more expensive
 	 than generating address, e.g., (plus (reg) (const)).
-	 L1 cache latency is about two instructions.  */
-      *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
+	 L1 cache latency is about two instructions.
+	 For prefixed load (pld), we would set it slightly faster than
+	 than two instructions. */
+      *total = !speed
+		 ? COSTS_N_INSNS (1) + 1
+		 : TARGET_PREFIXED ? COSTS_N_INSNS (2) - 1 : COSTS_N_INSNS (2);
       if (rs6000_slow_unaligned_access (mode, MEM_ALIGN (x)))
 	*total += COSTS_N_INSNS (100);
       return true;
diff --git a/gcc/testsuite/gcc.target/powerpc/medium_offset.c b/gcc/testsuite/gcc.target/powerpc/medium_offset.c
index f29eba08c38..4889e8fa8ec 100644
--- a/gcc/testsuite/gcc.target/powerpc/medium_offset.c
+++ b/gcc/testsuite/gcc.target/powerpc/medium_offset.c
@@ -1,7 +1,7 @@
 /* { dg-do compile { target { powerpc*-*-* } } } */
 /* { dg-require-effective-target lp64 } */
 /* { dg-options "-O" } */
-/* { dg-final { scan-assembler-not "\\+4611686018427387904" } } */
+/* { dg-final { scan-assembler-times {\msldi|pld\M} 1 } } */
 
 static int x;
 
diff --git a/gcc/testsuite/gcc.target/powerpc/pr63281.c b/gcc/testsuite/gcc.target/powerpc/pr63281.c
new file mode 100644
index 00000000000..469a8f64400
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr63281.c
@@ -0,0 +1,11 @@
+/* PR target/63281 */
+/* { dg-do compile { target lp64 } } */
+/* { dg-options "-O2 -std=c99" } */
+
+void
+foo (unsigned long long *a)
+{
+  *a = 0x020805006106003;
+}
+
+/* { dg-final { scan-assembler-times {\mp?ld\M} 1 } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/pr93012.c b/gcc/testsuite/gcc.target/powerpc/pr93012.c
index 4f764d0576f..5afb4f79c45 100644
--- a/gcc/testsuite/gcc.target/powerpc/pr93012.c
+++ b/gcc/testsuite/gcc.target/powerpc/pr93012.c
@@ -10,4 +10,4 @@ unsigned long long mskh1() { return 0xffff9234ffff9234ULL; }
 unsigned long long mskl1() { return 0x2bcdffff2bcdffffULL; }
 unsigned long long mskse() { return 0xffff1234ffff1234ULL; }
 
-/* { dg-final { scan-assembler-times {\mrldimi\M} 7 } } */
+/* { dg-final { scan-assembler-times {\mrldimi|ld|pld\M} 7 } } */
-- 
2.25.1


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2022-05-23  1:39 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-10  9:28 [PATCH] Store complicated const into pool Jiufu Guo
2022-05-23  1:39 ` [PATCH V2]rs6000: Store complicated constant " Jiufu Guo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).