*** empty log message ***

From-SVN: r1336
This commit is contained in:
Tom Wood 1992-06-29 16:04:35 +00:00
parent 8194c19cbe
commit bdac5f5848
7 changed files with 267 additions and 4 deletions

View File

@ -49,6 +49,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "rtl.h"
#include "regs.h"
#include "insn-config.h"
#include "insn-flags.h"
#include "insn-attr.h"
#include "insn-codes.h"
#include "recog.h"
@ -111,6 +112,7 @@ void output_addr_const ();
static void output_source_line ();
rtx final_scan_insn ();
void profile_function ();
static void profile_after_prologue ();
#ifdef HAVE_ATTR_length
static int asm_insn_count ();
@ -689,6 +691,20 @@ final_start_function (first, file, optimize)
next_block_index = 1;
#endif
/* If the machine represents the prologue as RTL, the profiling code must
be emitted when NOTE_INSN_PROLOGUE_END is scanned. */
#ifdef HAVE_prologue
if (! HAVE_prologue)
#endif
profile_after_prologue (file);
profile_label_no++;
}
static void
profile_after_prologue (file)
FILE *file;
{
#ifdef FUNCTION_BLOCK_PROFILER
if (profile_block_flag)
{
@ -700,8 +716,6 @@ final_start_function (first, file, optimize)
if (profile_flag)
profile_function (file);
#endif /* not PROFILE_BEFORE_PROLOGUE */
profile_label_no++;
}
void
@ -926,6 +940,23 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END)
break;
if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_PROLOGUE_END)
{
#ifdef FUNCTION_END_PROLOGUE
FUNCTION_END_PROLOGUE (file);
#endif
profile_after_prologue (file);
break;
}
#ifdef FUNCTION_BEGIN_EPILOGUE
if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EPILOGUE_BEG)
{
FUNCTION_BEGIN_EPILOGUE (file);
break;
}
#endif
if (write_symbols == NO_DEBUG)
break;
if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_BEG)
@ -1061,7 +1092,11 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
case BARRIER:
#ifdef ASM_OUTPUT_ALIGN_CODE
ASM_OUTPUT_ALIGN_CODE (file);
/* Don't litter the assembler output with needless alignments. A
BARRIER will be placed at the end of every function if HAVE_epilogue
is true. */
if (NEXT_INSN (insn))
ASM_OUTPUT_ALIGN_CODE (file);
#endif
break;

View File

@ -53,6 +53,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "insn-config.h"
#include "recog.h"
#include "output.h"
#include "basic-block.h"
/* Round a value to the lowest integer less than it that is a multiple of
the required alignment. Avoid using division in case the value is
@ -4076,3 +4077,209 @@ expand_function_end (filename, line)
then you will lose. */
fixup_gotos (0, 0, 0, get_insns (), 0);
}
/* These arrays record the INSN_UIDs of the prologue and epilogue insns. */
static int *prologue;
static int *epilogue;
/* Create an array that records the INSN_UIDs of INSNS (either a sequence
or a single insn). */
static int *
record_insns (insns)
rtx insns;
{
int *vec;
if (GET_CODE (insns) == SEQUENCE)
{
int len = XVECLEN (insns, 0);
vec = (int *) oballoc ((len + 1) * sizeof (int));
vec[len] = 0;
while (--len >= 0)
vec[len] = INSN_UID (XVECEXP (insns, 0, len));
}
else
{
vec = (int *) oballoc (2 * sizeof (int));
vec[0] = INSN_UID (insns);
vec[1] = 0;
}
return vec;
}
/* Determine whether INSN is in the array of INSN_UIDs VEC. */
static rtx
contains (insn, vec)
rtx insn;
int *vec;
{
register int i, j;
if (GET_CODE (insn) == INSN
&& GET_CODE (PATTERN (insn)) == SEQUENCE)
{
for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
for (j = 0; vec[j]; j++)
if (INSN_UID (XVECEXP (PATTERN (insn), 0, i)) == vec[j])
return XVECEXP (PATTERN (insn), 0, i);
}
else
{
for (j = 0; vec[j]; j++)
if (INSN_UID (insn) == vec[j])
return insn;
}
return 0;
}
/* Generate the prologe and epilogue RTL if the machine supports it. Thread
this into place with notes indicating where the prologue ends and where
the epilogue begins. Update the basic block information when possible. */
void
thread_prologue_and_epilogue_insns (f)
rtx f;
{
#ifdef HAVE_prologue
if (HAVE_prologue)
{
rtx head, seq, insn;
/* The first insn (a NOTE_INSN_DELETED) is followed by zero or more
prologue insns and a NOTE_INSN_PROLOGUE_END. */
emit_note_after (NOTE_INSN_PROLOGUE_END, f);
seq = gen_prologue ();
head = emit_insn_after (seq, f);
/* Include the new prologue insns in the first block. Ignore them
if they form a basic block unto themselves. */
if (basic_block_head && n_basic_blocks
&& GET_CODE (basic_block_head[0]) != CODE_LABEL)
basic_block_head[0] = NEXT_INSN (f);
/* Retain a map of the prologue insns. */
prologue = record_insns (GET_CODE (seq) == SEQUENCE ? seq : head);
}
else
#endif
prologue = 0;
#ifdef HAVE_epilogue
if (HAVE_epilogue)
{
rtx insn = get_last_insn ();
rtx prev = prev_nonnote_insn (insn);
/* If we end with a BARRIER, we don't need an epilogue. */
if (! (prev && GET_CODE (prev) == BARRIER))
{
rtx tail, seq;
/* The last basic block ends with a NOTE_INSN_EPILOGUE_BEG,
the epilogue insns (this must include the jump insn that
returns), USE insns ad the end of a function, and a BARRIER. */
emit_barrier_after (insn);
/* Place the epilogue before the USE insns at the end of a
function. */
while (prev
&& GET_CODE (prev) == INSN
&& GET_CODE (PATTERN (prev)) == USE)
{
insn = PREV_INSN (prev);
prev = prev_nonnote_insn (prev);
}
seq = gen_epilogue ();
tail = emit_jump_insn_after (seq, insn);
emit_note_after (NOTE_INSN_EPILOGUE_BEG, insn);
/* Include the new epilogue insns in the last block. Ignore
them if they form a basic block unto themselves. */
if (basic_block_end && n_basic_blocks
&& GET_CODE (basic_block_end[n_basic_blocks - 1]) != JUMP_INSN)
basic_block_end[n_basic_blocks - 1] = tail;
/* Retain a map of the epilogue insns. */
epilogue = record_insns (GET_CODE (seq) == SEQUENCE ? seq : tail);
return;
}
}
#endif
epilogue = 0;
}
/* Reposition the prologue-end and epilogue-begin notes after instruction
scheduling and delayed branch scheduling. */
void
reposition_prologue_and_epilogue_notes (f)
rtx f;
{
#if defined (HAVE_prologue) || defined (HAVE_epilogue)
/* Reposition the prologue and epilogue notes. */
if (n_basic_blocks)
{
rtx next, prev;
if (prologue)
{
register rtx insn, end_prologue;
/* From the end of the first basic block, search backward for a
prologue insn. */
for (insn = NEXT_INSN (PREV_INSN (basic_block_end[0]));
insn; insn = prev_nonnote_insn (insn))
if (contains (insn, prologue))
{
end_prologue = insn;
/* Find the prologue-end note and move it to just after the
last prologue insn. */
for (insn = f; insn; insn = NEXT_INSN (insn))
if (GET_CODE (insn) == NOTE
&& NOTE_LINE_NUMBER (insn) == NOTE_INSN_PROLOGUE_END)
break;
next = NEXT_INSN (insn);
prev = PREV_INSN (insn);
if (prev)
NEXT_INSN (prev) = next;
if (next)
PREV_INSN (next) = prev;
add_insn_after (insn, end_prologue);
break;
}
}
if (epilogue)
{
register rtx insn, beg_epilogue;
/* From the start of the last basic block, search forward for an
epilogue insn. */
for (insn = PREV_INSN (NEXT_INSN (basic_block_head[n_basic_blocks - 1]));
insn; insn = next_nonnote_insn (insn))
if (beg_epilogue = contains (insn, epilogue))
{
/* Find the epilogue-begin note and move it to just before
the first epilogue insn. */
for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
if (GET_CODE (insn) == NOTE
&& NOTE_LINE_NUMBER (insn) == NOTE_INSN_EPILOGUE_BEG)
break;
next = NEXT_INSN (insn);
prev = PREV_INSN (insn);
if (prev)
NEXT_INSN (prev) = next;
if (next)
PREV_INSN (next) = prev;
add_insn_after (insn, PREV_INSN (beg_epilogue));
break;
}
}
}
#endif /* HAVE_prologue or HAVE_epilogue */
}

View File

@ -3592,6 +3592,10 @@ dbr_schedule (first, file)
/* It is not clear why the line below is needed, but it does seem to be. */
unfilled_firstobj = (rtx *) obstack_alloc (&unfilled_slots_obstack, 0);
/* Reposition the prologue and epilogue notes in case we moved the
prologue/epilogue insns. */
reposition_prologue_and_epilogue_notes (first);
if (file)
{
register int i, j, need_comma;

View File

@ -169,7 +169,8 @@ char *note_insn_name[] = { "NOTE_INSN_FUNCTION_BEG", "NOTE_INSN_DELETED",
"NOTE_INSN_BLOCK_BEG", "NOTE_INSN_BLOCK_END",
"NOTE_INSN_LOOP_BEG", "NOTE_INSN_LOOP_END",
"NOTE_INSN_FUNCTION_END", "NOTE_INSN_SETJMP",
"NOTE_INSN_LOOP_CONT", "NOTE_INSN_LOOP_VTOP" };
"NOTE_INSN_LOOP_CONT", "NOTE_INSN_LOOP_VTOP",
"NOTE_INSN_PROLOGUE_END", "NOTE_INSN_EPILOGUE_BEG" };
char *reg_note_name[] = { "", "REG_DEAD", "REG_INC", "REG_EQUIV", "REG_WAS_0",
"REG_EQUAL", "REG_RETVAL", "REG_LIBCALL",

View File

@ -336,6 +336,10 @@ extern char *reg_note_name[];
#define NOTE_INSN_LOOP_CONT -8
/* Generated at the start of a duplicated exit test. */
#define NOTE_INSN_LOOP_VTOP -9
/* This marks the point immediately after the last prologue insn. */
#define NOTE_INSN_PROLOGUE_END -10
/* This marks the point immediately prior to the first epilogue insn. */
#define NOTE_INSN_EPILOGUE_BEG -11
/* Don't forget to change note_insn_name in rtl.c. */
#define NOTE_DECL_NAME(INSN) ((INSN)->fld[3].rtstr)

View File

@ -3949,6 +3949,11 @@ schedule_insns (dump_file)
#endif
}
/* Reposition the prologue and epilogue notes in case we moved the
prologue/epilogue insns. */
if (reload_completed)
reposition_prologue_and_epilogue_notes (get_insns ());
if (write_symbols != NO_DEBUG)
{
rtx line = 0;

View File

@ -2368,6 +2368,13 @@ rest_of_compilation (decl)
reload_completed = 1;
/* On some machines, the prologue and epilogue code, or parts thereof,
can be represented as RTL. Doing so lets us schedule insns between
it and the rest of the code and also allows delayed branch
scheduling to operate in the epilogue. */
thread_prologue_and_epilogue_insns (insns);
if (optimize > 0 && flag_schedule_insns_after_reload)
{
if (sched2_dump)