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]

Re: [Bug rtl-optimization/33676] libgfortran bootstrap failure: selected_int_kind.f90:22: Segmentation fault, wrong code with -fomit-frame-pointer


Eric Botcazou wrote:
>> 2007-10-11  Kenneth Zadeck <zadeck@naturalbridge.com>
>>
>>     PR middle-end/33676
>>     * global.c (build_insn_chain): Include insn that occur between
>>     basic blocks.
>>     
>
> Who approved this patch?
>
>   
>> However, the reload_insn_chain actually needs the insns that appear
>> between basic blocks, in particular the labels in front of branch
>> tables.  I added code here to check for insns that may be in front of a
>> basic block after scanning that block.
>>
>> There are a lot of ways that I could have done this, for instance, I
>> could have just written in terms of the PREV_INSN as the old code was.
>> I think that in doing it the way that i have done it, it is obvious what
>> needs to be done if someone really does get rid of the branch tables
>> between the blocks.
>>     
>
> Sure, but the code in build_insn_chain is now more convoluted than in the 
> original version (and twice as big).  And, please, fix the formatting.
>
>   
it was approved by seonbae, a register allocation reviewer.    The
reason that it is longer is that it is more precise.  The code to
properly handle subregs, as well as properly dealing with registers live
thru insns,  accounts for most of the expansion over the old code.

formatting fixes committed as revision 129262.

kenny
Index: global.c
===================================================================
--- global.c	(revision 129260)
+++ global.c	(working copy)
@@ -1358,6 +1358,8 @@ mark_elimination (int from, int to)
     }
 }
 
+/* Print chain C to FILE.  */
+
 static void
 print_insn_chain (FILE *file, struct insn_chain *c)
 {
@@ -1366,6 +1368,9 @@ print_insn_chain (FILE *file, struct ins
   bitmap_print (file, &c->dead_or_set, "dead_or_set: ", "\n");
 }
 
+
+/* Print all reload_insn_chains to FILE.  */
+
 static void
 print_insn_chains (FILE *file)
 {
@@ -1373,8 +1378,11 @@ print_insn_chains (FILE *file)
   for (c = reload_insn_chain; c ; c = c->next)
     print_insn_chain (file, c);
 }
+
+
 /* Walk the insns of the current function and build reload_insn_chain,
    and record register life information.  */
+
 static void
 build_insn_chain (void)
 {
@@ -1450,7 +1458,7 @@ build_insn_chain (void)
 		      {
 			if (regno < FIRST_PSEUDO_REGISTER)
 			  {
-			    if (! fixed_regs[regno])
+			    if (!fixed_regs[regno])
 			      bitmap_set_bit (&c->dead_or_set, regno);
 			  }
 			else if (reg_renumber[regno] >= 0)
@@ -1461,16 +1469,20 @@ build_insn_chain (void)
 			&& (!DF_REF_FLAGS_IS_SET (def, DF_REF_CONDITIONAL)))
 		      {
 			rtx reg = DF_REF_REG (def);
+
 			/* We can model subregs, but not if they are
 			   wrapped in ZERO_EXTRACTS.  */
 			if (GET_CODE (reg) == SUBREG
 			    && !DF_REF_FLAGS_IS_SET (def, DF_REF_EXTRACT))
 			  {
 			    unsigned int start = SUBREG_BYTE (reg);
-			    unsigned int last = start + GET_MODE_SIZE (GET_MODE (reg));
+			    unsigned int last = start 
+			      + GET_MODE_SIZE (GET_MODE (reg));
 
-			    ra_init_live_subregs (bitmap_bit_p (live_relevant_regs, regno), 
-						  live_subregs, live_subregs_used,
+			    ra_init_live_subregs (bitmap_bit_p (live_relevant_regs, 
+								regno), 
+						  live_subregs, 
+						  live_subregs_used,
 						  regno, reg);
 			    /* Ignore the paradoxical bits.  */
 			    if ((int)last > live_subregs_used[regno])
@@ -1535,7 +1547,7 @@ build_insn_chain (void)
 		      {
 			if (regno < FIRST_PSEUDO_REGISTER)
 			  {
-			    if (! fixed_regs[regno])
+			    if (!fixed_regs[regno])
 			      bitmap_set_bit (&c->dead_or_set, regno);
 			  }
 			else if (reg_renumber[regno] >= 0)
@@ -1548,10 +1560,13 @@ build_insn_chain (void)
 			    && !DF_REF_FLAGS_IS_SET (use, DF_REF_EXTRACT)) 
 			  {
 			    unsigned int start = SUBREG_BYTE (reg);
-			    unsigned int last = start + GET_MODE_SIZE (GET_MODE (reg));
+			    unsigned int last = start 
+			      + GET_MODE_SIZE (GET_MODE (reg));
 			    
-			    ra_init_live_subregs (bitmap_bit_p (live_relevant_regs, regno), 
-						  live_subregs, live_subregs_used,
+			    ra_init_live_subregs (bitmap_bit_p (live_relevant_regs, 
+								regno), 
+						  live_subregs, 
+						  live_subregs_used,
 						  regno, reg);
 			    
 			    /* Ignore the paradoxical bits.  */
@@ -1579,13 +1594,13 @@ build_insn_chain (void)
       /* FIXME!! The following code is a disaster.  Reload needs to see the
 	 labels and jump tables that are just hanging out in between
 	 the basic blocks.  See pr33676.  */
-
       insn = BB_HEAD (bb);
-
+      
       /* Skip over the barriers and cruft.  */
-      while (insn && (BARRIER_P (insn) || NOTE_P (insn) || BLOCK_FOR_INSN (insn) == bb))
+      while (insn && (BARRIER_P (insn) || NOTE_P (insn) 
+		      || BLOCK_FOR_INSN (insn) == bb))
 	insn = PREV_INSN (insn);
-	
+      
       /* While we add anything except barriers and notes, the focus is
 	 to get the labels and jump tables into the
 	 reload_insn_chain.  */
@@ -1595,24 +1610,24 @@ build_insn_chain (void)
 	    {
 	      if (BLOCK_FOR_INSN (insn))
 		break;
-
+	      
 	      c = new_insn_chain ();
 	      c->next = next;
 	      next = c;
 	      *p = c;
 	      p = &c->prev;
 	      
-	      c->insn = insn;
 	      /* The block makes no sense here, but it is what the old
 		 code did.  */
 	      c->block = bb->index;
+	      c->insn = insn;
 	      bitmap_copy (&c->live_throughout, live_relevant_regs);
 	    }	  
 	  insn = PREV_INSN (insn);
 	}
     }
 
-  for (i = 0; i < (unsigned int)max_regno; i++)
+  for (i = 0; i < (unsigned int) max_regno; i++)
     if (live_subregs[i])
       free (live_subregs[i]);
 

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