On 07/05/2011 04:30 PM, David Edelsohn wrote:
> On Fri, Jul 1, 2011 at 8:31 PM, Richard Henderson <[email protected]> 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