LogoopenSUSE Build Service > Projects
Sign Up | Log In

View File suse50394.diff of Package gcc33 (Project openSUSE:Factory)

Index: gcc/global.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/global.c,v
retrieving revision 1.86.2.3
diff -u -p -r1.86.2.3 global.c
--- gcc/global.c	31 Jan 2004 12:46:03 -0000	1.86.2.3
+++ gcc/global.c	14 Feb 2005 08:02:59 -0000
@@ -131,10 +131,8 @@ struct allocno
 
   HARD_REG_SET regs_someone_prefers;
 
-#ifdef STACK_REGS
   /* Set to true if allocno can't be allocated in the stack register.  */
-  bool no_stack_reg;
-#endif
+  bool live_over_abnormal;
 };
 
 static struct allocno *allocno;
@@ -727,26 +725,37 @@ global_conflicts ()
 	    scan the instruction that makes either X or Y become live.  */
 	record_conflicts (block_start_allocnos, ax);
 
-#ifdef STACK_REGS
+ 	/* Pseudos can't go in stack regs at the start of a basic block that
+ 	   is reached by an abnormal edge. Ditto for call clobbered regs,
+ 	   because because caller-save, fixup_abnormal_edges, and possibly the
+ 	   table driven EH machinery are not quite ready to handle such regs
+ 	   live across such edges.  */
 	{
-	  /* Pseudos can't go in stack regs at the start of a basic block
-	     that is reached by an abnormal edge.  */
-
 	  edge e;
 	  for (e = b->pred; e ; e = e->pred_next)
 	    if (e->flags & EDGE_ABNORMAL)
 	      break;
+
 	  if (e != NULL)
 	    {
 	      EXECUTE_IF_SET_IN_ALLOCNO_SET (allocnos_live, ax,
 		{
-		  allocno[ax].no_stack_reg = 1;
+		  allocno[ax].live_over_abnormal = 1;
 		});
+#ifdef STACK_REGS
 	      for (ax = FIRST_STACK_REG; ax <= LAST_STACK_REG; ax++)
 	        record_one_conflict (ax);
+#endif
+
+	      /* No need to record conflicts for call clobbered regs if we have
+		 nonlocal labels around, as we don't ever try to allocate such
+		 regs in this case.  */
+	      if (! current_function_has_nonlocal_label)
+		for (ax = 0; ax < FIRST_PSEUDO_REGISTER; ax ++)
+		  if (call_used_regs [ax])
+		    record_one_conflict (ax);
 	    }
 	}
-#endif
       }
 
       insn = b->head;
@@ -1241,10 +1250,12 @@ find_reg (num, losers, alt_regs_p, accep
 	      && ! invalid_mode_change_p (regno, REGNO_REG_CLASS (regno),
 					  mode)
 #endif
+	      && (!allocno[num].live_over_abnormal
+		  || (!call_used_regs[regno]
 #ifdef STACK_REGS
-	      && (!allocno[num].no_stack_reg
-		  || regno < FIRST_STACK_REG || regno > LAST_STACK_REG)
+		      && (regno < FIRST_STACK_REG || regno > LAST_STACK_REG)
 #endif
+                     ))
 	      )
 	    {
 	      /* We explicitly evaluate the divide results into temporary