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][ARM] Refactor MOVW/MOVT fusion logic to allow extension


Hi all,

If we want to add more macro fusion cases in the arm backend we need to rework the aarch_macro_fusion_pair_p a bit
to not return early during the MOVW/MOVT fusion checks.  This simple patch does that by adding a helper function
that can be called with the two sets to check if they satisfy the fusion logic.  There is no change in codegen.

Bootstrapped and tested on arm-none-linux-gnueabihf.

Ok for trunk?
Thanks,
Kyrill

2016-08-23  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

    * config/arm/arm.c (arm_sets_movw_movt_fusible_p): New function.
    (aarch_macro_fusion_pair_p): Use above to avoid early return.
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 2deb62b2f724ef9c17f585046480e47abcd341b0..bb6ada9e0f62efae95fdeb11dfcee14dba3299b0 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -29903,11 +29903,57 @@ arm_macro_fusion_p (void)
   return current_tune->fusible_ops != tune_params::FUSE_NOTHING;
 }
 
+/* Return true if the two back-to-back sets PREV_SET, CURR_SET are suitable
+   for MOVW / MOVT macro fusion.  */
+
+static bool
+arm_sets_movw_movt_fusible_p (rtx prev_set, rtx curr_set)
+{
+  /* We are trying to fuse
+     movw imm / movt imm
+    instructions as a group that gets scheduled together.  */
+
+  rtx set_dest = SET_DEST (curr_set);
+
+  if (GET_MODE (set_dest) != SImode)
+    return false;
+
+  /* We are trying to match:
+     prev (movw)  == (set (reg r0) (const_int imm16))
+     curr (movt) == (set (zero_extract (reg r0)
+					(const_int 16)
+					(const_int 16))
+			  (const_int imm16_1))
+     or
+     prev (movw) == (set (reg r1)
+			  (high (symbol_ref ("SYM"))))
+    curr (movt) == (set (reg r0)
+			(lo_sum (reg r1)
+				(symbol_ref ("SYM"))))  */
+
+    if (GET_CODE (set_dest) == ZERO_EXTRACT)
+      {
+	if (CONST_INT_P (SET_SRC (curr_set))
+	    && CONST_INT_P (SET_SRC (prev_set))
+	    && REG_P (XEXP (set_dest, 0))
+	    && REG_P (SET_DEST (prev_set))
+	    && REGNO (XEXP (set_dest, 0)) == REGNO (SET_DEST (prev_set)))
+	  return true;
+
+      }
+    else if (GET_CODE (SET_SRC (curr_set)) == LO_SUM
+	     && REG_P (SET_DEST (curr_set))
+	     && REG_P (SET_DEST (prev_set))
+	     && GET_CODE (SET_SRC (prev_set)) == HIGH
+	     && REGNO (SET_DEST (curr_set)) == REGNO (SET_DEST (prev_set)))
+      return true;
+
+  return false;
+}
 
 static bool
 aarch_macro_fusion_pair_p (rtx_insn* prev, rtx_insn* curr)
 {
-  rtx set_dest;
   rtx prev_set = single_set (prev);
   rtx curr_set = single_set (curr);
 
@@ -29925,45 +29971,10 @@ aarch_macro_fusion_pair_p (rtx_insn* prev, rtx_insn* curr)
       && aarch_crypto_can_dual_issue (prev, curr))
     return true;
 
-  if (current_tune->fusible_ops & tune_params::FUSE_MOVW_MOVT)
-    {
-      /* We are trying to fuse
-	 movw imm / movt imm
-	 instructions as a group that gets scheduled together.  */
-
-      set_dest = SET_DEST (curr_set);
-
-      if (GET_MODE (set_dest) != SImode)
-	return false;
+  if (current_tune->fusible_ops & tune_params::FUSE_MOVW_MOVT
+      && arm_sets_movw_movt_fusible_p (prev_set, curr_set))
+    return true;
 
-      /* We are trying to match:
-	 prev (movw)  == (set (reg r0) (const_int imm16))
-	 curr (movt) == (set (zero_extract (reg r0)
-					  (const_int 16)
-					   (const_int 16))
-			     (const_int imm16_1))
-	 or
-	 prev (movw) == (set (reg r1)
-			      (high (symbol_ref ("SYM"))))
-	 curr (movt) == (set (reg r0)
-			     (lo_sum (reg r1)
-				     (symbol_ref ("SYM"))))  */
-      if (GET_CODE (set_dest) == ZERO_EXTRACT)
-	{
-	  if (CONST_INT_P (SET_SRC (curr_set))
-	      && CONST_INT_P (SET_SRC (prev_set))
-	      && REG_P (XEXP (set_dest, 0))
-	      && REG_P (SET_DEST (prev_set))
-	      && REGNO (XEXP (set_dest, 0)) == REGNO (SET_DEST (prev_set)))
-	    return true;
-	}
-      else if (GET_CODE (SET_SRC (curr_set)) == LO_SUM
-	       && REG_P (SET_DEST (curr_set))
-	       && REG_P (SET_DEST (prev_set))
-	       && GET_CODE (SET_SRC (prev_set)) == HIGH
-	       && REGNO (SET_DEST (curr_set)) == REGNO (SET_DEST (prev_set)))
-	     return true;
-    }
   return false;
 }
 

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