public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH-1, rs6000] Put constant into pseudo at expand when it needs two insns [PR86106]
@ 2023-03-16  5:34 HAO CHEN GUI
  2023-03-16  7:57 ` Richard Biener
  0 siblings, 1 reply; 6+ messages in thread
From: HAO CHEN GUI @ 2023-03-16  5:34 UTC (permalink / raw)
  To: gcc-patches; +Cc: Segher Boessenkool, David, Kewen.Lin, Peter Bergner

Hi,
  Currently, rs6000 directly expands to 2 insns if an integer constant is the
second operand and it needs two insns. For example, addi/addis and ori/oris.
It may not benefit when the constant is used for more than 2 times in an
extended basic block, just like the case in PR shows.

  One possible solution is to force the constant in pseudo at expand and let
propagation pass and combine pass decide if the pseudo should be replaced
with the constant or not by comparing the rtx/insn cost.

  It generates a constant move if the constant is forced to a pseudo. There
is one constant move if it's used only once. The combine pass can combine
the constant move and add/ior/xor insn and eliminate the move as the insn
cost reduces. There are multiple moves if the constant is used for several
times. In an extended basic block, these constant moves are merged to one by
propagation pass. The combine pass can't replace the pseudo with the constant
as it is no cost saving.

  In an extreme case, the constant is used twice in an extended basic block.
The cost(latency) is unchanged between putting constant in pseudo and
generating 2 insns. The dependence of instructions reduces but one more
register is used. In other case, it should be always optimal to put constant
in a pseudo.

  This patch changes the expander of integer add and force constant to a
pseudo when it needs 2 insn. Also a combine and split pattern is defined.

  Bootstrapped and tested on powerpc64-linux BE and LE with no regressions.

Thanks
Gui Haochen

ChangeLog
2023-03-14  Haochen Gui <guihaoc@linux.ibm.com>

gcc/
	* config/rs6000/predicates.md (add_2insn_cint_operand): New predicate
	which returns true when op is a 32-bit but not a 16-bit signed
	integer constant.
	* config/rs6000/rs6000.md (add<mode>3): Put the second operand into
	register when it's a constant and need 2 add insns.
	(*add<mode>_2insn): New insn_and_split for 2-insn add.


patch.diff
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index a1764018545..09e59a48cd3 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -282,6 +282,13 @@ (define_predicate "s32bit_cint_operand"
   (and (match_code "const_int")
        (match_test "(0x80000000 + UINTVAL (op)) >> 32 == 0")))

+;; Return 1 if op is a 32-bit but not 16-bit constant signed integer
+(define_predicate "add_2insn_cint_operand"
+  (and (match_code "const_int")
+       (and (match_operand 0 "s32bit_cint_operand")
+	    (and (not (match_operand 0 "short_cint_operand"))
+		 (not (match_operand 0 "upper16_cint_operand"))))))
+
 ;; Return 1 if op is a constant 32-bit unsigned
 (define_predicate "c32bit_cint_operand"
   (and (match_code "const_int")
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 6011f5bf76a..dba41e3df90 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -1796,12 +1796,44 @@ (define_expand "add<mode>3"
       /* The ordering here is important for the prolog expander.
 	 When space is allocated from the stack, adding 'low' first may
 	 produce a temporary deallocation (which would be bad).  */
-      emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
-      emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
-      DONE;
+      if (!can_create_pseudo_p ())
+	{
+	  emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
+	  emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
+	  DONE;
+	}
+
+      operands[2] = force_reg (<MODE>mode, operands[2]);
     }
 })

+/* The ordering here is important for the prolog expander.
+   When space is allocated from the stack, adding 'low' first may
+   produce a temporary deallocation (which would be bad).  */
+
+(define_insn_and_split "*add<mode>_2insn"
+  [(set (match_operand:GPR 0 "gpc_reg_operand" "=b")
+	(plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%b")
+		  (match_operand:GPR 2 "add_2insn_cint_operand" "n")))]
+  "!TARGET_PREFIXED"
+  "#"
+  "&& 1"
+  [(set (match_dup 0)
+	(plus:GPR (match_dup 1)
+		  (match_dup 3)))
+   (set (match_dup 0)
+	(plus:GPR (match_dup 0)
+		  (match_dup 4)))]
+{
+  HOST_WIDE_INT val = INTVAL (operands[2]);
+  HOST_WIDE_INT low = sext_hwi (val, 16);
+  HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
+
+  operands[3] = GEN_INT (rest);
+  operands[4] = GEN_INT (low);
+}
+  [(set_attr "length" "8")])
+
 (define_insn "*add<mode>3"
   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r,r")
 	(plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b,b")

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

end of thread, other threads:[~2023-03-22  3:08 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-16  5:34 [PATCH-1, rs6000] Put constant into pseudo at expand when it needs two insns [PR86106] HAO CHEN GUI
2023-03-16  7:57 ` Richard Biener
2023-03-16  9:04   ` HAO CHEN GUI
2023-03-16 10:36     ` Richard Biener
2023-03-17  2:48       ` HAO CHEN GUI
2023-03-22  3:08   ` HAO CHEN GUI

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).