On 07/05/2011 04:30 PM, David Edelsohn wrote: > On Fri, Jul 1, 2011 at 8:31 PM, Richard Henderson <r...@redhat.com> wrote: >> The implementation of TARGET_SCHED_PROLOG is incompatible with >> some coming changes to how dwarf2 cfi is to be generated. >> >> Some suggested solutions are: >> >> (1) Remove the option. Is it really that interesting >> beyond -mno-sched-insns2? >> >> (2) Emit blockage insns at the end of the prologue >> and the beginning of the epilogue. That'll prevent >> the majority of the changes that scheduling could >> introduce. >> >> (3) Emit the prologue and epilogue somewhere after >> scheduling and before final. E.g. md_reorg. >> >> I'd be delighted if someone could actually implement one >> of these changes at some point in the next week, but >> failing that please weigh in on the preferred solution. > > As we discussed on IRC, (1) with and eventual implementation of (2) are okay.
Implements (2). I emit the blockage in the expanders and not in rs6000_emit_{pro,epi}logue because the functions contain several sets of early-returns. Putting it here avoids any tricky code rearrangement. Tested via cross-compile, and as they say, "what could go wrong?" Ok? r~
* config/rs6000/rs6000.c (rs6000_output_function_prologue): Don't try to insert an rtl prologue here. (rs6000_output_function_epilogue): Similarly. * config/rs6000/rs6000.md (prologue): Emit a barrier to satisfy !TARGET_SCHED_PROLOG. (epilogue, sibcall_epilogue): Likewise. diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 475c104..a25e5af 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -20570,39 +20570,6 @@ rs6000_output_function_prologue (FILE *file, common_mode_defined = 1; } - if (! HAVE_prologue) - { - rtx prologue; - - start_sequence (); - - /* A NOTE_INSN_DELETED is supposed to be at the start and end of - the "toplevel" insn chain. */ - emit_note (NOTE_INSN_DELETED); - rs6000_emit_prologue (); - emit_note (NOTE_INSN_DELETED); - - /* Expand INSN_ADDRESSES so final() doesn't crash. */ - { - rtx insn; - unsigned addr = 0; - for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn)) - { - INSN_ADDRESSES_NEW (insn, addr); - addr += 4; - } - } - - prologue = get_insns (); - end_sequence (); - - if (TARGET_DEBUG_STACK) - debug_rtx_list (prologue, 100); - - emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb), - ENTRY_BLOCK_PTR); - } - rs6000_pic_labelno++; } @@ -21413,43 +21380,6 @@ static void rs6000_output_function_epilogue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED) { - if (! HAVE_epilogue) - { - rtx insn = get_last_insn (); - /* If the last insn was a BARRIER, we don't have to write anything except - the trace table. */ - if (GET_CODE (insn) == NOTE) - insn = prev_nonnote_insn (insn); - if (insn == 0 || GET_CODE (insn) != BARRIER) - { - /* This is slightly ugly, but at least we don't have two - copies of the epilogue-emitting code. */ - start_sequence (); - - /* A NOTE_INSN_DELETED is supposed to be at the start - and end of the "toplevel" insn chain. */ - emit_note (NOTE_INSN_DELETED); - rs6000_emit_epilogue (FALSE); - emit_note (NOTE_INSN_DELETED); - - /* Expand INSN_ADDRESSES so final() doesn't crash. */ - { - rtx insn; - unsigned addr = 0; - for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn)) - { - INSN_ADDRESSES_NEW (insn, addr); - addr += 4; - } - } - - if (TARGET_DEBUG_STACK) - debug_rtx_list (get_insns (), 100); - final (get_insns (), file, FALSE); - end_sequence (); - } - } - #if TARGET_MACHO macho_branch_islands (); /* Mach-O doesn't support labels at the end of objects, so if diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 8c0e299..a404448 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -13025,12 +13025,13 @@ (define_expand "sibcall_epilogue" [(use (const_int 0))] - "TARGET_SCHED_PROLOG" - " + "" { - rs6000_emit_epilogue (TRUE); - DONE; -}") + if (!TARGET_SCHED_PROLOG) + emit_insn (gen_blockage ()); + rs6000_emit_epilogue (TRUE); + DONE; +}) ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and ;; all of memory. This blocks insns from being moved across this point. @@ -15791,12 +15792,13 @@ (define_expand "prologue" [(use (const_int 0))] - "TARGET_SCHED_PROLOG" - " + "" { - rs6000_emit_prologue (); - DONE; -}") + rs6000_emit_prologue (); + if (!TARGET_SCHED_PROLOG) + emit_insn (gen_blockage ()); + DONE; +}) (define_insn "*movesi_from_cr_one" [(match_parallel 0 "mfcr_operation" @@ -15946,12 +15948,13 @@ (define_expand "epilogue" [(use (const_int 0))] - "TARGET_SCHED_PROLOG" - " + "" { - rs6000_emit_epilogue (FALSE); - DONE; -}") + if (!TARGET_SCHED_PROLOG) + emit_insn (gen_blockage ()); + rs6000_emit_epilogue (FALSE); + DONE; +}) ; On some processors, doing the mtcrf one CC register at a time is ; faster (like on the 604e). On others, doing them all at once is