public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] combine: Do not combine moves from hard registers
@ 2018-10-22 21:06 Segher Boessenkool
  2018-10-22 22:07 ` Jeff Law
                   ` (2 more replies)
  0 siblings, 3 replies; 32+ messages in thread
From: Segher Boessenkool @ 2018-10-22 21:06 UTC (permalink / raw)
  To: gcc-patches; +Cc: bergner, Segher Boessenkool

On most targets every function starts with moves from the parameter
passing (hard) registers into pseudos.  Similarly, after every call
there is a move from the return register into a pseudo.  These moves
usually combine with later instructions (leaving pretty much the same
instruction, just with a hard reg instead of a pseudo).

This isn't a good idea.  Register allocation can get rid of unnecessary
moves just fine, and moving the parameter passing registers into many
later instructions tends to prevent good register allocation.  This
patch disallows combining moves from a hard (non-fixed) register.

This also avoid the problem mentioned in PR87600 #c3 (combining hard
registers into inline assembler is problematic).

Because the register move can often be combined with other instructions
*itself*, for example for setting some condition code, this patch adds
extra copies via new pseudos after every copy-from-hard-reg.

On some targets this reduces average code size.  On others it increases
it a bit, 0.1% or 0.2% or so.  (I tested this on all *-linux targets).

I'll commit this to trunk now.  If there are problems, please don't
hesitate to let me know!  Thanks.


Segher


2018-10-22  Segher Boessenkool  <segher@kernel.crashing.org>

	PR rtl-optimization/87600
	* combine.c: Add include of expr.h.
	(cant_combine_insn_p): Do not combine moves from any hard non-fixed
	register to a pseudo.
	(make_more_copies): New function, add a copy to a new pseudo after
	the moves from hard registers into pseudos.
	(rest_of_handle_combine): Declare rebuild_jump_labels_after_combine
	later.  Call make_more_copies.

---
 gcc/combine.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 46 insertions(+), 4 deletions(-)

diff --git a/gcc/combine.c b/gcc/combine.c
index 256b5a4..3ff1760 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -99,6 +99,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "explow.h"
 #include "insn-attr.h"
 #include "rtlhooks-def.h"
+#include "expr.h"
 #include "params.h"
 #include "tree-pass.h"
 #include "valtrack.h"
@@ -2348,8 +2349,7 @@ cant_combine_insn_p (rtx_insn *insn)
     dest = SUBREG_REG (dest);
   if (REG_P (src) && REG_P (dest)
       && ((HARD_REGISTER_P (src)
-	   && ! TEST_HARD_REG_BIT (fixed_reg_set, REGNO (src))
-	   && targetm.class_likely_spilled_p (REGNO_REG_CLASS (REGNO (src))))
+	   && ! TEST_HARD_REG_BIT (fixed_reg_set, REGNO (src)))
 	  || (HARD_REGISTER_P (dest)
 	      && ! TEST_HARD_REG_BIT (fixed_reg_set, REGNO (dest))
 	      && targetm.class_likely_spilled_p (REGNO_REG_CLASS (REGNO (dest))))))
@@ -14969,11 +14969,53 @@ dump_combine_total_stats (FILE *file)
      total_attempts, total_merges, total_extras, total_successes);
 }
 \f
+/* Make pseudo-to-pseudo copies after every hard-reg-to-pseudo-copy, because
+   the reg-to-reg copy can usefully combine with later instructions, but we
+   do not want to combine the hard reg into later instructions, for that
+   restricts register allocation.  */
+static void
+make_more_copies (void)
+{
+  basic_block bb;
+
+  FOR_EACH_BB_FN (bb, cfun)
+    {
+      rtx_insn *insn;
+
+      FOR_BB_INSNS (bb, insn)
+        {
+          if (!NONDEBUG_INSN_P (insn))
+            continue;
+
+	  rtx set = single_set (insn);
+	  if (!set)
+	    continue;
+	  rtx src = SET_SRC (set);
+	  rtx dest = SET_DEST (set);
+	  if (GET_CODE (src) == SUBREG)
+	    src = SUBREG_REG (src);
+	  if (!(REG_P (src) && HARD_REGISTER_P (src)))
+	    continue;
+	  if (TEST_HARD_REG_BIT (fixed_reg_set, REGNO (src)))
+	    continue;
+
+	  rtx new_reg = gen_reg_rtx (GET_MODE (dest));
+	  rtx_insn *insn1 = gen_move_insn (new_reg, src);
+	  rtx_insn *insn2 = gen_move_insn (dest, new_reg);
+	  emit_insn_after (insn1, insn);
+	  emit_insn_after (insn2, insn1);
+	  delete_insn (insn);
+
+	  insn = insn2;
+	}
+    }
+}
+
 /* Try combining insns through substitution.  */
 static unsigned int
 rest_of_handle_combine (void)
 {
-  int rebuild_jump_labels_after_combine;
+  make_more_copies ();
 
   df_set_flags (DF_LR_RUN_DCE + DF_DEFER_INSN_RESCAN);
   df_note_add_problem ();
@@ -14982,7 +15024,7 @@ rest_of_handle_combine (void)
   regstat_init_n_sets_and_refs ();
   reg_n_sets_max = max_reg_num ();
 
-  rebuild_jump_labels_after_combine
+  int rebuild_jump_labels_after_combine
     = combine_instructions (get_insns (), max_reg_num ());
 
   /* Combining insns may have turned an indirect jump into a
-- 
1.8.3.1

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

end of thread, other threads:[~2018-11-12 12:54 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-10-22 21:06 [PATCH] combine: Do not combine moves from hard registers Segher Boessenkool
2018-10-22 22:07 ` Jeff Law
2018-10-22 22:46   ` Segher Boessenkool
2018-10-23 10:54 ` Christophe Lyon
2018-10-23 12:36   ` Christophe Lyon
2018-10-23 13:10     ` Segher Boessenkool
2018-10-23 13:30       ` Christophe Lyon
2018-10-23 13:08   ` Segher Boessenkool
2018-10-23 13:50     ` Christophe Lyon
2018-10-24  1:50       ` Segher Boessenkool
2018-10-24  9:52         ` Christophe Lyon
2018-11-02 22:19           ` Renlin Li
2018-11-02 23:03             ` Segher Boessenkool
2018-11-02 23:54               ` Segher Boessenkool
2018-11-03  2:34                 ` Jeff Law
2018-11-05 12:35                   ` Renlin Li
2018-11-05 18:16                     ` Renlin Li
2018-11-07 23:02                       ` Segher Boessenkool
2018-11-09 10:21                         ` Richard Earnshaw (lists)
2018-11-05 22:50                     ` Segher Boessenkool
2018-10-24  9:38   ` Paul Hua
2018-10-23 16:16 ` Andreas Schwab
2018-10-23 16:28   ` Segher Boessenkool
2018-10-24 12:24     ` Andreas Schwab
2018-10-26 17:41       ` Steve Ellcey
2018-10-26 18:37         ` Segher Boessenkool
     [not found]           ` <7bc8697f-a09e-627f-b032-eba5ecb682ac@arm.com>
2018-11-08 20:34             ` Segher Boessenkool
2018-11-09 21:12               ` Jeff Law
2018-11-10  4:51                 ` Segher Boessenkool
2018-11-10 16:54                   ` Jeff Law
2018-11-12 11:57               ` Sam Tebbs
     [not found]               ` <e9104024-2f6a-6cb8-e366-39b96f7a72f2@arm.com>
2018-11-12 12:54                 ` Segher Boessenkool

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