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

zadeck at naturalbridge dot com gcc-bugzilla@gcc.gnu.org
Fri Oct 12 14:38:00 GMT 2007



------- Comment #24 from zadeck at naturalbridge dot com  2007-10-12 14:38 -------
Subject: Re:  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]);



-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33676



More information about the Gcc-bugs mailing list