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][AArch64] Improve add immediate expansion


This patch improves add immediate expansion by always expanding complex adds into a move immediate
and an add. This enables CSE of all complex immediates. A separate split pattern enables combine to
emit a 2-instruction add sequence for single use cases.

Bootstrapped & regression tested on AArch64.

OK for commit?

ChangeLog:
2015-09-25  Wilco Dijkstra  <wdijkstr@arm.com>

	* gcc/config/aarch64/aarch64.md (add<mode>3):
	Block early expansion into 2 add instructions.
	(add<mode>3_pluslong): New pattern to combine complex
	immediates into 2 additions.

---
 gcc/config/aarch64/aarch64.md | 54 ++++++++++++++++++++++++++++---------------
 1 file changed, 35 insertions(+), 19 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 78b9ae2..13d9257 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -1542,30 +1542,46 @@
 	      (match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
   ""
   "
-  if (! aarch64_plus_operand (operands[2], VOIDmode))
+  if (!aarch64_plus_operand (operands[2], VOIDmode))
     {
-      HOST_WIDE_INT imm = INTVAL (operands[2]);
-
-      if (aarch64_move_imm (imm, <MODE>mode) && can_create_pseudo_p ())
-        {
+      if (can_create_pseudo_p ())
+	{
 	  rtx tmp = gen_reg_rtx (<MODE>mode);
 	  emit_move_insn (tmp, operands[2]);
 	  operands[2] = tmp;
-        }
+	}
       else
-        {
-	  rtx subtarget = ((optimize && can_create_pseudo_p ())
-			   ? gen_reg_rtx (<MODE>mode) : operands[0]);
-
-	  if (imm < 0)
-	    imm = -(-imm & ~0xfff);
-	  else
-	    imm &= ~0xfff;
-
-	  emit_insn (gen_add<mode>3 (subtarget, operands[1], GEN_INT (imm)));
-	  operands[1] = subtarget;
-	  operands[2] = GEN_INT (INTVAL (operands[2]) - imm);
-        }
+	{
+	  HOST_WIDE_INT imm = INTVAL (operands[2]);
+	  imm = imm >= 0 ? imm & 0xfff : -(-imm & 0xfff);
+	  emit_insn (gen_add<mode>3 (operands[0], operands[1],
+				     GEN_INT (INTVAL (operands[2]) - imm)));
+	  operands[1] = operands[0];
+	  operands[2] = GEN_INT (imm);
+	}
+    }
+  "
+)
+
+;; Find add with a 2-instruction immediate and merge into 2 add instructions.
+
+(define_insn_and_split "*add<mode>3_pluslong"
+  [(set
+    (match_operand:GPI 0 "register_operand" "")
+    (plus:GPI (match_operand:GPI 1 "register_operand" "")
+	      (match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
+  "!aarch64_plus_operand (operands[2], VOIDmode)
+   && !aarch64_move_imm (INTVAL (operands[2]), <MODE>mode)"
+  "#"
+  "&& true"
+  [(set (match_dup 0) (plus:GPI (match_dup 1) (match_dup 3)))
+   (set (match_dup 0) (plus:GPI (match_dup 0) (match_dup 4)))]
+  "
+    {
+      HOST_WIDE_INT imm = INTVAL (operands[2]);
+      imm = imm >= 0 ? imm & 0xfff : -(-imm & 0xfff);
+      operands[3] = GEN_INT (INTVAL (operands[2]) - imm);
+      operands[4] = GEN_INT (imm);
     }
   "
 )
-- 
1.9.1



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