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: big slowdown in egcs-1.1.2->gcc-2.95 on alpha


On Fri, Aug 06, 1999 at 11:27:32PM -0500, Brad Lucier wrote:
> Each sample counts as 0.000976562 seconds.
>   %   cumulative   self              self     total           
>  time   seconds   seconds    calls  ms/call  ms/call  name    
>  35.63     55.32    55.32       16  3457.52  3458.44  prune_preferences
>  12.51     74.75    19.43 391960848     0.00     0.00  bitmap_bit_p

The following should kill bitmap_bit_p from the interesting
functions.


r~



	* global.c (build_insn_chain): Use EXECUTE_IF_SET_IN_REG_SET 
	to invert loops.  Simplify block scanning.

Index: global.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/global.c,v
retrieving revision 1.28
diff -u -p -d -r1.28 global.c
--- global.c	1999/08/04 07:50:08	1.28
+++ global.c	1999/08/07 07:58:44
@@ -271,7 +271,7 @@ static void set_preference	PROTO((rtx, r
 static void dump_conflicts	PROTO((FILE *));
 static void reg_becomes_live	PROTO((rtx, rtx));
 static void reg_dies		PROTO((int, enum machine_mode));
-static void build_insn_chain	PROTO((rtx));
+static void build_insn_chain	PROTO((void));
 
 /* Perform allocation of pseudo-registers not allocated by local_alloc.
    FILE is a file to output debugging information on,
@@ -578,7 +578,7 @@ global_alloc (file)
   if (n_basic_blocks > 0)
 #endif
     {
-      build_insn_chain (get_insns ());
+      build_insn_chain ();
       retval = reload (get_insns (), 1, file);
     }
 
@@ -1667,96 +1667,88 @@ reg_dies (regno, mode)
 /* Walk the insns of the current function and build reload_insn_chain,
    and record register life information.  */
 static void
-build_insn_chain (first)
-     rtx first;
+build_insn_chain ()
 {
   struct insn_chain **p = &reload_insn_chain;
   struct insn_chain *prev = 0;
-  int b = 0;
+  int b;
 
   live_relevant_regs = ALLOCA_REG_SET ();
 
-  for (; first; first = NEXT_INSN (first))
+  for (b = n_basic_blocks - 1; b >= 0; --b)
     {
-      struct insn_chain *c;
-
-      if (first == BLOCK_HEAD (b))
-	{
-	  int i;
-	  CLEAR_REG_SET (live_relevant_regs);
-	  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-	    if (REGNO_REG_SET_P (BASIC_BLOCK (b)->global_live_at_start, i)
-		&& ! TEST_HARD_REG_BIT (eliminable_regset, i))
-	      SET_REGNO_REG_SET (live_relevant_regs, i);
+      basic_block bb = BASIC_BLOCK (b);
+      rtx insn, end;
+      int i;
 
-	  for (; i < max_regno; i++)
-	    if (reg_renumber[i] >= 0
-		&& REGNO_REG_SET_P (BASIC_BLOCK (b)->global_live_at_start, i))
-	      SET_REGNO_REG_SET (live_relevant_regs, i);
-	}
+      CLEAR_REG_SET (live_relevant_regs);
 
-      if (GET_CODE (first) != NOTE && GET_CODE (first) != BARRIER)
+      EXECUTE_IF_SET_IN_REG_SET (bb->global_live_at_start, 0, i,
 	{
-	  c = new_insn_chain ();
-	  c->prev = prev;
-	  prev = c;
-	  *p = c;
-	  p = &c->next;
-	  c->insn = first;
-	  c->block = b;
+	  if ((i < FIRST_PSEUDO_REGISTER
+	       && ! TEST_HARD_REG_BIT (eliminable_regset, i))
+	      || (i >= FIRST_PSEUDO_REGISTER
+		  && reg_renumber[i] >= 0))
+	    SET_REGNO_REG_SET (live_relevant_regs, i);
+	});
 
-	  COPY_REG_SET (c->live_before, live_relevant_regs);
+      insn = bb->head, end = bb->end;
+      while (1)
+	{
+	  struct insn_chain *c;
 
-	  if (GET_RTX_CLASS (GET_CODE (first)) == 'i')
+	  if (GET_CODE (insn) != NOTE)
 	    {
-	      rtx link;
-
-	      /* Mark the death of everything that dies in this instruction.  */
+	      c = new_insn_chain ();
+	      c->prev = prev;
+	      prev = c;
+	      *p = c;
+	      p = &c->next;
+	      c->insn = insn;
+	      c->block = b;
 
-	      for (link = REG_NOTES (first); link; link = XEXP (link, 1))
-		if (REG_NOTE_KIND (link) == REG_DEAD
-		    && GET_CODE (XEXP (link, 0)) == REG)
-		  reg_dies (REGNO (XEXP (link, 0)), GET_MODE (XEXP (link, 0)));
+	      COPY_REG_SET (c->live_before, live_relevant_regs);
 
-	      /* Mark everything born in this instruction as live.  */
+	      if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
+		{
+		  rtx link;
 
-	      note_stores (PATTERN (first), reg_becomes_live);
-	    }
+		  /* Mark the death of everything that dies in this
+		     instruction.  */
+		  for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
+		    if (REG_NOTE_KIND (link) == REG_DEAD
+			&& GET_CODE (XEXP (link, 0)) == REG)
+		      reg_dies (REGNO (XEXP (link, 0)),
+				GET_MODE (XEXP (link, 0)));
 
-	  /* Remember which registers are live at the end of the insn, before
-	     killing those with REG_UNUSED notes.  */
-	  COPY_REG_SET (c->live_after, live_relevant_regs);
+		  /* Mark everything born in this instruction as live.  */
+		  note_stores (PATTERN (insn), reg_becomes_live);
+		}
 
-	  if (GET_RTX_CLASS (GET_CODE (first)) == 'i')
-	    {
-	      rtx link;
+	      /* Remember which registers are live at the end of the insn,
+		 before killing those with REG_UNUSED notes.  */
+	      COPY_REG_SET (c->live_after, live_relevant_regs);
 
-	      /* Mark anything that is set in this insn and then unused as dying.  */
+	      if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
+		{
+		  rtx link;
 
-	      for (link = REG_NOTES (first); link; link = XEXP (link, 1))
-		if (REG_NOTE_KIND (link) == REG_UNUSED
-		    && GET_CODE (XEXP (link, 0)) == REG)
-		  reg_dies (REGNO (XEXP (link, 0)), GET_MODE (XEXP (link, 0)));
+		  /* Mark anything that is set in this insn and then unused
+		     as dying.  */
+		  for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
+		    if (REG_NOTE_KIND (link) == REG_UNUSED
+			&& GET_CODE (XEXP (link, 0)) == REG)
+		      reg_dies (REGNO (XEXP (link, 0)),
+				GET_MODE (XEXP (link, 0)));
+		}
 	    }
-	}
-
-      if (first == BLOCK_END (b))
-	b++;
 
-      /* Stop after we pass the end of the last basic block.  Verify that
-	 no real insns are after the end of the last basic block.
-
-	 We may want to reorganize the loop somewhat since this test should
-	 always be the right exit test.  */
-      if (b == n_basic_blocks)
-	{
-	  for (first = NEXT_INSN (first) ; first; first = NEXT_INSN (first))
-	    if (GET_RTX_CLASS (GET_CODE (first)) == 'i'
-		&& GET_CODE (PATTERN (first)) != USE)
-	      abort ();
-	  break;
+	  if (insn == end)
+	    break;
+	  insn = NEXT_INSN (insn);
 	}
     }
+
   FREE_REG_SET (live_relevant_regs);
   *p = 0;
 }


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