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]

scheduler fix for small register classes


Hi,

While working with Glauber on TLS improvements for ARM, we've come
across a problem in the scheduler.  Even though the scheduler is
careful enough to not extend the life of CLASS_LIKELY_SPILLED_P
classes before reload, to avoid problems such as moving the
instruction that sets the return value before other instructions that
might need that hardware register, it does nothing to avoid extending
the life of hardware registers holding incoming arguments.  Even
though combine avoids substituting such hardware registers, schedule
might still move the copies from the hardware registers to pseudos,
emitted before the function begin note, past instructions that might
require such hardware registers, and then reload loses.

This patch fixes this problem, by arranging for the function begin
note to be a scheduler move barrier before reload, thus avoiding the
harmful rearrangement.

Bootstrapped and tested on amd64-linux-gnu native and cross to
arm-linux-gnu, with a patch that modifies SMALL_REGISTER_CLASSES in
arm.h so as to be defined to 1, and introduces a register class
containing only r0, as well as a number of TLS-related instructions
that use the new class.

Ok to install?

for gcc/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	* sched-deps.c (sched_analyze): Set a move barrier at the
	function begin note.

Index: gcc/sched-deps.c
===================================================================
--- gcc/sched-deps.c.orig	2006-04-12 02:45:05.000000000 -0300
+++ gcc/sched-deps.c	2006-06-19 03:26:53.000000000 -0300
@@ -1568,8 +1568,19 @@ sched_analyze (struct deps *deps, rtx he
       /* EH_REGION insn notes can not appear until well after we complete
 	 scheduling.  */
       if (NOTE_P (insn))
-	gcc_assert (NOTE_LINE_NUMBER (insn) != NOTE_INSN_EH_REGION_BEG
-		    && NOTE_LINE_NUMBER (insn) != NOTE_INSN_EH_REGION_END);
+	{
+	  /* Set the function begin note before reload as a move
+	     barrier on machines with small register classes, such
+	     that we don't extend the live ranges of hardware
+	     registers holding incoming arguments.  ??? Perhaps we
+	     should scan the insns for copies from regs in
+	     CLASS_LIKELY_SPILLED_P?  */
+	  if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_BEG
+	       && !reload_completed && SMALL_REGISTER_CLASSES)
+	    reg_pending_barrier = MOVE_BARRIER;
+	  gcc_assert (NOTE_LINE_NUMBER (insn) != NOTE_INSN_EH_REGION_BEG
+		      && NOTE_LINE_NUMBER (insn) != NOTE_INSN_EH_REGION_END);
+	}
 
       if (current_sched_info->use_cselib)
 	cselib_process_insn (insn);

-- 
Alexandre Oliva         http://www.lsd.ic.unicamp.br/~oliva/
Secretary for FSF Latin America        http://www.fsfla.org/
Red Hat Compiler Engineer   aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist  oliva@{lsd.ic.unicamp.br, gnu.org}

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