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]

Re: [PATCH] Make dataflow analyzer mark defs for call_fixed_regs


We had this scattered all over the place.  CSE and GCSE got
it right, FLOW didn't (in a way that was dangerous), SCHED
didn't (in a way that was safe).  REORG doesn't (in a way that
is safe) but I ain't touching that code except to remove it.

Tested on i686 and alphaev56 linux.


r~


	* hard-reg-set.h (regs_invalidated_by_call): Declare.
	* regclass.c (regs_invalidated_by_call): Move from cse.c.
	(init_reg_sets_1): Move initialization from cse_main.
	* cse.c (regs_invalidated_by_call): Move to regclass.c.
	(cse_main): Move its initialization also.
	* df.c (df_insn_refs_record): Use regs_invalidated_by_call.
	* flow.c (propagate_one_insn): Likewise.
	* gcse.c (compute_hash_table): Likewise.
	(compute_kill_rd, compute_store_table): Likewise.
	* sched-deps.c (sched_analyze_1): Likewise.

Index: cse.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cse.c,v
retrieving revision 1.189
diff -u -p -r1.189 cse.c
--- cse.c	2001/07/09 11:20:50	1.189
+++ cse.c	2001/07/16 06:48:12
@@ -346,11 +346,6 @@ static struct cse_reg_info *cached_cse_r
 
 static HARD_REG_SET hard_regs_in_table;
 
-/* A HARD_REG_SET containing all the hard registers that are invalidated
-   by a CALL_INSN.  */
-
-static HARD_REG_SET regs_invalidated_by_call;
-
 /* CUID of insn that starts the basic block currently being cse-processed.  */
 
 static int cse_basic_block_start;
@@ -7071,37 +7066,6 @@ cse_main (f, nregs, after_loop, file)
 	/* Give a line number note the same cuid as preceding insn.  */
 	INSN_CUID (insn) = i;
     }
-
-  /* Initialize which registers are clobbered by calls.  */
-
-  CLEAR_HARD_REG_SET (regs_invalidated_by_call);
-
-  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-    if ((call_used_regs[i]
-	 /* Used to check !fixed_regs[i] here, but that isn't safe;
-	    fixed regs are still call-clobbered, and sched can get
-	    confused if they can "live across calls".
-
-	    The frame pointer is always preserved across calls.  The arg
-	    pointer is if it is fixed.  The stack pointer usually is, unless
-	    RETURN_POPS_ARGS, in which case an explicit CLOBBER
-	    will be present.  If we are generating PIC code, the PIC offset
-	    table register is preserved across calls.  */
-
-	 && i != STACK_POINTER_REGNUM
-	 && i != FRAME_POINTER_REGNUM
-#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
-	 && i != HARD_FRAME_POINTER_REGNUM
-#endif
-#if ARG_POINTER_REGNUM != FRAME_POINTER_REGNUM
-	 && ! (i == ARG_POINTER_REGNUM && fixed_regs[i])
-#endif
-#if !defined (PIC_OFFSET_TABLE_REG_CALL_CLOBBERED)
-	 && ! (i == PIC_OFFSET_TABLE_REGNUM && flag_pic)
-#endif
-	 )
-	|| global_regs[i])
-      SET_HARD_REG_BIT (regs_invalidated_by_call, i);
 
   ggc_push_context ();
 
Index: df.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/df.c,v
retrieving revision 1.3
diff -u -p -r1.3 df.c
--- df.c	2001/07/10 16:27:54	1.3
+++ df.c	2001/07/16 06:48:12
@@ -1268,14 +1268,9 @@ df_insn_refs_record (df, bb, insn)
 
 	  if (df->flags & DF_HARD_REGS)
 	    {
-	      /* Each call clobbers all call-clobbered regs that are not
-		 global or fixed and have not been explicitly defined
-		 in the call pattern.  */
+	      /* Kill all registers invalidated by a call.  */
 	      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-		if (call_used_regs[i] 
-		    && ! global_regs[i]
-		    && ! fixed_regs[i]
-		    && ! df_insn_regno_def_p (df, bb, insn, i))
+		if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
 		  {
 		    rtx reg_clob = df_reg_clobber_gen (i);
 		    df_defs_record (df, reg_clob, bb, insn);
Index: flow.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/flow.c,v
retrieving revision 1.426
diff -u -p -r1.426 flow.c
--- flow.c	2001/07/15 15:47:05	1.426
+++ flow.c	2001/07/16 06:48:14
@@ -4948,8 +4948,7 @@ propagate_one_insn (pbi, insn)
 
 	  /* Calls change all call-used and global registers.  */
 	  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-	    if (call_used_regs[i] && ! global_regs[i]
-		&& ! fixed_regs[i])
+	    if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
 	      {
 		/* We do not want REG_UNUSED notes for these registers.  */
 		mark_set_1 (pbi, CLOBBER, gen_rtx_REG (reg_raw_mode[i], i),
Index: gcse.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gcse.c,v
retrieving revision 1.134
diff -u -p -r1.134 gcse.c
--- gcse.c	2001/07/11 16:11:47	1.134
+++ gcse.c	2001/07/16 06:48:16
@@ -2548,20 +2548,7 @@ compute_hash_table (set_p)
 	  if (GET_CODE (insn) == CALL_INSN)
 	    {
 	      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
-		if ((call_used_regs[regno]
-		     && regno != STACK_POINTER_REGNUM
-#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
-		     && regno != HARD_FRAME_POINTER_REGNUM
-#endif
-#if ARG_POINTER_REGNUM != FRAME_POINTER_REGNUM
-		     && ! (regno == ARG_POINTER_REGNUM && fixed_regs[regno])
-#endif
-#if !defined (PIC_OFFSET_TABLE_REG_CALL_CLOBBERED)
-		     && ! (regno == PIC_OFFSET_TABLE_REGNUM && flag_pic)
-#endif
-
-		     && regno != FRAME_POINTER_REGNUM)
-		    || global_regs[regno])
+		if (TEST_HARD_REG_BIT (regs_invalidated_by_call, regno))
 		  record_last_reg_set_info (insn, regno);
 
 	      if (! CONST_CALL_P (insn))
@@ -3007,23 +2994,8 @@ compute_kill_rd ()
 	  if (GET_CODE (insn) == CALL_INSN)
 	    {
 	      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
-		{
-		  if ((call_used_regs[regno]
-		       && regno != STACK_POINTER_REGNUM
-#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
-		       && regno != HARD_FRAME_POINTER_REGNUM
-#endif
-#if ARG_POINTER_REGNUM != FRAME_POINTER_REGNUM
-		       && ! (regno == ARG_POINTER_REGNUM
-			     && fixed_regs[regno])
-#endif
-#if !defined (PIC_OFFSET_TABLE_REG_CALL_CLOBBERED)
-		       && ! (regno == PIC_OFFSET_TABLE_REGNUM && flag_pic)
-#endif
-		       && regno != FRAME_POINTER_REGNUM)
-		      || global_regs[regno])
-		    handle_rd_kill_set (insn, regno, BASIC_BLOCK (bb));
-		}
+		if (TEST_HARD_REG_BIT (regs_invalidated_by_call, regno))
+		  handle_rd_kill_set (insn, regno, BASIC_BLOCK (bb));
 	    }
 
 	  if (GET_CODE (pat) == PARALLEL)
@@ -6554,21 +6526,8 @@ compute_store_table ()
 	  if (GET_CODE (insn) == CALL_INSN)
 	    {
 	      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
-		if ((call_used_regs[regno]
-		     && regno != STACK_POINTER_REGNUM
-#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
-		     && regno != HARD_FRAME_POINTER_REGNUM
-#endif
-#if ARG_POINTER_REGNUM != FRAME_POINTER_REGNUM
-		     && ! (regno == ARG_POINTER_REGNUM && fixed_regs[regno])
-#endif
-#if defined (PIC_OFFSET_TABLE_REGNUM) && !defined (PIC_OFFSET_TABLE_REG_CALL_CLOBBERED)
-		     && ! (regno == PIC_OFFSET_TABLE_REGNUM && flag_pic)
-#endif
-
-		     && regno != FRAME_POINTER_REGNUM)
-		    || global_regs[regno])
-		SET_BIT (reg_set_in_block[bb], regno);
+		if (TEST_HARD_REG_BIT (regs_invalidated_by_call, regno))
+		  SET_BIT (reg_set_in_block[bb], regno);
 	    }
 	  
 	  pat = PATTERN (insn);
Index: hard-reg-set.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/hard-reg-set.h,v
retrieving revision 1.10
diff -u -p -r1.10 hard-reg-set.h
--- hard-reg-set.h	2001/05/26 01:31:34	1.10
+++ hard-reg-set.h	2001/07/16 06:48:16
@@ -431,6 +431,15 @@ extern HARD_REG_SET call_fixed_reg_set;
 
 extern char global_regs[FIRST_PSEUDO_REGISTER];
 
+/* Contains 1 for registers that are set or clobbered by calls.  */
+/* ??? Ideally, this would be just call_used_regs plus global_regs, but
+   for someone's bright idea to have call_used_regs strictly include
+   fixed_regs.  Which leaves us guessing as to the set of fixed_regs
+   that are actually preserved.  We know for sure that those associated
+   with the local stack frame are safe, but scant others.  */
+
+extern HARD_REG_SET regs_invalidated_by_call;
+
 #ifdef REG_ALLOC_ORDER
 /* Table of register numbers in the order in which to try to use them.  */
 
Index: regclass.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/regclass.c,v
retrieving revision 1.121
diff -u -p -r1.121 regclass.c
--- regclass.c	2001/06/22 23:27:47	1.121
+++ regclass.c	2001/07/16 06:48:16
@@ -116,7 +116,16 @@ int n_non_fixed_regs;
    and are also considered fixed.  */
 
 char global_regs[FIRST_PSEUDO_REGISTER];
-  
+
+/* Contains 1 for registers that are set or clobbered by calls.  */
+/* ??? Ideally, this would be just call_used_regs plus global_regs, but
+   for someone's bright idea to have call_used_regs strictly include
+   fixed_regs.  Which leaves us guessing as to the set of fixed_regs
+   that are actually preserved.  We know for sure that those associated
+   with the local stack frame are safe, but scant others.  */
+
+HARD_REG_SET regs_invalidated_by_call;
+
 /* Table of register numbers in the order in which to try to use them.  */
 #ifdef REG_ALLOC_ORDER
 int reg_alloc_order[FIRST_PSEUDO_REGISTER] = REG_ALLOC_ORDER;
@@ -410,6 +419,7 @@ init_reg_sets_1 ()
   CLEAR_HARD_REG_SET (fixed_reg_set);
   CLEAR_HARD_REG_SET (call_used_reg_set);
   CLEAR_HARD_REG_SET (call_fixed_reg_set);
+  CLEAR_HARD_REG_SET (regs_invalidated_by_call);
 
   memcpy (call_fixed_regs, fixed_regs, sizeof call_fixed_regs);
 
@@ -428,7 +438,34 @@ init_reg_sets_1 ()
 	SET_HARD_REG_BIT (call_fixed_reg_set, i);
       if (CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (i)))
 	SET_HARD_REG_BIT (losing_caller_save_reg_set, i);
+
+      /* There are a couple of fixed registers that we know are safe to
+	 exclude from being clobbered by calls:
+
+	 The frame pointer is always preserved across calls.  The arg pointer
+	 is if it is fixed.  The stack pointer usually is, unless
+	 RETURN_POPS_ARGS, in which case an explicit CLOBBER will be present.
+	 If we are generating PIC code, the PIC offset table register is
+	 preserved across calls, though the target can override that.  */
+	 
+      if (i == STACK_POINTER_REGNUM || i == FRAME_POINTER_REGNUM)
+	;
+#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
+      else if (i == HARD_FRAME_POINTER_REGNUM)
+	;
+#endif
+#if ARG_POINTER_REGNUM != FRAME_POINTER_REGNUM
+      else if (i == ARG_POINTER_REGNUM && fixed_regs[i])
+	;
+#endif
+#ifndef PIC_OFFSET_TABLE_REG_CALL_CLOBBERED
+      else if (i == PIC_OFFSET_TABLE_REGNUM && flag_pic)
+	;
+#endif
+      else if (call_used_regs[i] || global_regs[i])
+	SET_HARD_REG_BIT (regs_invalidated_by_call, i);
     }
+
   memset (contains_reg_of_mode, 0, sizeof (contains_reg_of_mode));
   memset (allocatable_regs_of_mode, 0, sizeof (allocatable_regs_of_mode));
   for (m = 0; m < (unsigned int) MAX_MACHINE_MODE; m++)
Index: sched-deps.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/sched-deps.c,v
retrieving revision 1.16
diff -u -p -r1.16 sched-deps.c
--- sched-deps.c	2001/07/11 16:11:47	1.16
+++ sched-deps.c	2001/07/16 06:48:17
@@ -618,7 +618,9 @@ sched_analyze_1 (deps, x, insn)
 		SET_REGNO_REG_SET (reg_pending_clobbers, r);
 
 	      /* Function calls clobber all call_used regs.  */
-	      if (global_regs[r] || (code == SET && call_used_regs[r]))
+	      if (global_regs[r]
+		  || (code == SET
+		      && TEST_HARD_REG_BIT (regs_invalidated_by_call, r)))
 		for (u = deps->last_function_call; u; u = XEXP (u, 1))
 		  add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
 	    }


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