(reg_to_stack): Use GET_RTX_CLASS.
Clear LABEL_REFs here. (find_blocks): Make algorithm identical to that inreg_to_stack. Use GET_RTX_CLASS. Don't clear LABEL_REFs here. Build a list of labels referenced by other than jumps. If computed jump, mark using that list and forced_labels. (uses_reg_or_mem): New function, copied from flow.c. From-SVN: r6671
This commit is contained in:
parent
2140ed5bfe
commit
0ab759e4fd
115
gcc/reg-stack.c
115
gcc/reg-stack.c
@ -1,5 +1,5 @@
|
||||
/* Register to Stack convert for GNU compiler.
|
||||
Copyright (C) 1992, 1993 Free Software Foundation, Inc.
|
||||
Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
@ -229,6 +229,7 @@ static rtx FP_mode_reg[FIRST_PSEUDO_REGISTER][(int) MAX_MACHINE_MODE];
|
||||
? (int *)(abort() , 0) \
|
||||
: block_number)[INSN_UID (INSN)])
|
||||
|
||||
extern rtx forced_labels;
|
||||
extern rtx gen_jump ();
|
||||
extern rtx gen_movdf (), gen_movxf ();
|
||||
extern rtx find_regno_note ();
|
||||
@ -238,6 +239,7 @@ extern rtx emit_label_after ();
|
||||
/* Forward declarations */
|
||||
|
||||
static void find_blocks ();
|
||||
static uses_reg_or_mem ();
|
||||
static void stack_reg_life_analysis ();
|
||||
static void change_stack ();
|
||||
static void convert_regs ();
|
||||
@ -311,7 +313,8 @@ reg_to_stack (first, file)
|
||||
for (insn = first; insn; insn = NEXT_INSN (insn))
|
||||
{
|
||||
/* Note that this loop must select the same block boundaries
|
||||
as code in find_blocks. */
|
||||
as code in find_blocks. Also note that this code is not the
|
||||
same as that used in flow.c. */
|
||||
|
||||
if (INSN_UID (insn) > max_uid)
|
||||
max_uid = INSN_UID (insn);
|
||||
@ -322,14 +325,13 @@ reg_to_stack (first, file)
|
||||
|| (prev_code != INSN
|
||||
&& prev_code != CALL_INSN
|
||||
&& prev_code != CODE_LABEL
|
||||
&& (code == INSN || code == CALL_INSN || code == JUMP_INSN)))
|
||||
&& GET_RTX_CLASS (code) == 'i'))
|
||||
blocks++;
|
||||
|
||||
/* Remember whether or not this insn mentions an FP regs.
|
||||
Check JUMP_INSNs too, in case someone creates a funny PARALLEL. */
|
||||
|
||||
if ((GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN
|
||||
|| GET_CODE (insn) == JUMP_INSN)
|
||||
if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
|
||||
&& stack_regs_mentioned_p (PATTERN (insn)))
|
||||
{
|
||||
stack_reg_seen = 1;
|
||||
@ -338,6 +340,9 @@ reg_to_stack (first, file)
|
||||
else
|
||||
PUT_MODE (insn, VOIDmode);
|
||||
|
||||
if (code == CODE_LABEL)
|
||||
LABEL_REFS (insn) = insn; /* delete old chain */
|
||||
|
||||
if (code != NOTE)
|
||||
prev_code = code;
|
||||
}
|
||||
@ -1171,8 +1176,9 @@ find_blocks (first)
|
||||
{
|
||||
register rtx insn;
|
||||
register int block;
|
||||
register RTX_CODE prev_code = BARRIER;
|
||||
register RTX_CODE prev_code = JUMP_INSN;
|
||||
register RTX_CODE code;
|
||||
rtx label_value_list = 0;
|
||||
|
||||
/* Record where all the blocks start and end.
|
||||
Record which basic blocks control can drop in to. */
|
||||
@ -1181,7 +1187,8 @@ find_blocks (first)
|
||||
for (insn = first; insn; insn = NEXT_INSN (insn))
|
||||
{
|
||||
/* Note that this loop must select the same block boundaries
|
||||
as code in reg_to_stack. */
|
||||
as code in reg_to_stack, but that these are not the same
|
||||
as those selected in flow.c. */
|
||||
|
||||
code = GET_CODE (insn);
|
||||
|
||||
@ -1189,19 +1196,27 @@ find_blocks (first)
|
||||
|| (prev_code != INSN
|
||||
&& prev_code != CALL_INSN
|
||||
&& prev_code != CODE_LABEL
|
||||
&& (code == INSN || code == CALL_INSN || code == JUMP_INSN)))
|
||||
&& GET_RTX_CLASS (code) == 'i'))
|
||||
{
|
||||
block_begin[++block] = insn;
|
||||
block_end[block] = insn;
|
||||
block_drops_in[block] = prev_code != BARRIER;
|
||||
}
|
||||
else if (code == INSN || code == CALL_INSN || code == JUMP_INSN)
|
||||
else if (GET_RTX_CLASS (code) == 'i')
|
||||
block_end[block] = insn;
|
||||
|
||||
BLOCK_NUM (insn) = block;
|
||||
if (GET_RTX_CLASS (code) == 'i')
|
||||
{
|
||||
rtx note;
|
||||
|
||||
if (code == CODE_LABEL)
|
||||
LABEL_REFS (insn) = insn; /* delete old chain */
|
||||
/* Make a list of all labels referred to other than by jumps. */
|
||||
for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
|
||||
if (REG_NOTE_KIND (note) == REG_LABEL)
|
||||
label_value_list = gen_rtx (EXPR_LIST, VOIDmode, XEXP (note, 0),
|
||||
label_value_list);
|
||||
}
|
||||
|
||||
BLOCK_NUM (insn) = block;
|
||||
|
||||
if (code != NOTE)
|
||||
prev_code = code;
|
||||
@ -1216,10 +1231,84 @@ find_blocks (first)
|
||||
insn = block_end[block];
|
||||
|
||||
if (GET_CODE (insn) == JUMP_INSN)
|
||||
record_label_references (insn, PATTERN (insn));
|
||||
{
|
||||
rtx pat = PATTERN (insn);
|
||||
int computed_jump = 0;
|
||||
rtx x;
|
||||
|
||||
if (GET_CODE (pat) == PARALLEL)
|
||||
{
|
||||
int len = XVECLEN (pat, 0);
|
||||
int has_use_labelref = 0;
|
||||
int i;
|
||||
|
||||
for (i = len - 1; i >= 0; i--)
|
||||
if (GET_CODE (XVECEXP (pat, 0, i)) == USE
|
||||
&& GET_CODE (XEXP (XVECEXP (pat, 0, i), 0)) == LABEL_REF)
|
||||
has_use_labelref = 1;
|
||||
|
||||
if (! has_use_labelref)
|
||||
for (i = len - 1; i >= 0; i--)
|
||||
if (GET_CODE (XVECEXP (pat, 0, i)) == SET
|
||||
&& SET_DEST (XVECEXP (pat, 0, i)) == pc_rtx
|
||||
&& uses_reg_or_mem (SET_SRC (XVECEXP (pat, 0, i))))
|
||||
computed_jump = 1;
|
||||
}
|
||||
else if (GET_CODE (pat) == SET
|
||||
&& SET_DEST (pat) == pc_rtx
|
||||
&& uses_reg_or_mem (SET_SRC (pat)))
|
||||
computed_jump = 1;
|
||||
|
||||
if (computed_jump)
|
||||
{
|
||||
for (x = label_value_list; x; x = XEXP (x, 1))
|
||||
record_label_references (insn,
|
||||
gen_rtx (LABEL_REF, VOIDmode,
|
||||
XEXP (x, 0)));
|
||||
|
||||
for (x = forced_labels; x; x = XEXP (x, 1))
|
||||
record_label_references (insn,
|
||||
gen_rtx (LABEL_REF, VOIDmode,
|
||||
XEXP (x, 0)));
|
||||
}
|
||||
|
||||
record_label_references (insn, pat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Return 1 if X contain a REG or MEM that is not in the constant pool. */
|
||||
|
||||
static int
|
||||
uses_reg_or_mem (x)
|
||||
rtx x;
|
||||
{
|
||||
enum rtx_code code = GET_CODE (x);
|
||||
int i, j;
|
||||
char *fmt;
|
||||
|
||||
if (code == REG
|
||||
|| (code == MEM
|
||||
&& ! (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
|
||||
&& CONSTANT_POOL_ADDRESS_P (XEXP (x, 0)))))
|
||||
return 1;
|
||||
|
||||
fmt = GET_RTX_FORMAT (code);
|
||||
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
|
||||
{
|
||||
if (fmt[i] == 'e'
|
||||
&& uses_reg_or_mem (XEXP (x, i)))
|
||||
return 1;
|
||||
|
||||
if (fmt[i] == 'E')
|
||||
for (j = 0; j < XVECLEN (x, i); j++)
|
||||
if (uses_reg_or_mem (XVECEXP (x, i, j)))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If current function returns its result in an fp stack register,
|
||||
return the register number. Otherwise return -1. */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user