This is the mail archive of the 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]

[RFC, PATCH] Getting the live registers correct when caller-saves are inserted by reload


I put this patch into my development tree after I spotted a problem in reload ( specifically when caller-saves are inserted). The problem was reported on the lists and discussed here -

To sum it up here, caller-save.c:insert_one_insn, while inserting a caller-save insn before a call_insn initializes the live_throughout set of the new insn to (live_throughout of call_insn + registers that die in the call_insn i.e regs with REG_DEAD notes). However, in the case where one of the registers that holds one of the arguments to the function is also the register used to hold the return value ( i.e one of the arguments of the function is also 'set' in the call_insn ) then a REG_DEAD note may be omitted. Therefore relying on REG_DEAD notes isnt all that good. In the patch I have used CALL_INSN_FUNCTION_USAGE to find the arguments to the function and mark them live_throughout for the new insn.

Bootstrapped and regtested on i686-pc-linux-gnu.


Pranav Bhandarkar
GNU Tools
Celunite, Inc.
+91-98220 82881

Index: caller-save.c
--- caller-save.c	(revision 130131)
+++ caller-save.c	(working copy)
@@ -850,6 +850,34 @@
 		SET_REGNO_REG_SET (&new->live_throughout, regno + i);
+      /* if CHAIN->INSN is a call, then the registers which contain
+	 the arguments to the function are live in the new insn. */
+      if (CALL_P (chain->insn))
+	{
+	  rtx link, arg, reg;
+	  int regno, i;
+	  for (link = CALL_INSN_FUNCTION_USAGE (chain->insn); link; link = XEXP (link, 1))
+	    {
+	      arg = XEXP (link, 0);
+	      if (GET_CODE (arg) == USE)
+		{
+		  reg = XEXP (arg, 0);
+		  if (REG_P (reg))
+		    {
+		      regno = REGNO (reg);
+		      if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] >= 0)
+			regno = reg_renumber[regno];
+		      for (i = hard_regno_nregs[regno][GET_MODE (reg)] - 1;
+			   i >= 0; i--)
+			SET_REGNO_REG_SET (&new->live_throughout, regno + i);
+		    }
+		}
+	    }
+	}
       CLEAR_REG_SET (&new->dead_or_set);
       if (chain->insn == BB_HEAD (BASIC_BLOCK (chain->block)))
 	BB_HEAD (BASIC_BLOCK (chain->block)) = new->insn;

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