Add functions copy_insn/copy_insn_1; use them in jump.c
From-SVN: r29870
This commit is contained in:
parent
b1afd7f4e0
commit
da43a810ca
|
@ -1,3 +1,14 @@
|
|||
Fri Oct 8 18:46:11 1999 Bernd Schmidt <bernds@cygnus.co.uk>
|
||||
|
||||
* jump.c (duplicate_loop_exit_test): Use copy_insn/copy_insn_1
|
||||
instead of copy_rtx. Accept sequences that contain asm statements.
|
||||
* emit_rtl.c (copy_insn_1, copy_insn): New functions.
|
||||
(copy_insn_scratch_in, copy_insn_scratch_out, copy_insn_n_scratches,
|
||||
orig_asm_operands_vector, copy_asm_operands_vector,
|
||||
orig_asm_constraints_vecotr, copy_asm_constraints_vector): New static
|
||||
variables.
|
||||
* rtl.h (copy_insn, copy_insn_1): Declare.
|
||||
|
||||
Fri Oct 8 13:08:12 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
|
||||
|
||||
* Makefile.in (insn-recog.o): Depend on hard-reg-set.h and resource.h.
|
||||
|
|
196
gcc/emit-rtl.c
196
gcc/emit-rtl.c
|
@ -162,6 +162,9 @@ static rtx free_insn;
|
|||
#define last_filename (current_function->emit->x_last_filename)
|
||||
#define first_label_num (current_function->emit->x_first_label_num)
|
||||
|
||||
/* This is where the pointer to the obstack being used for RTL is stored. */
|
||||
extern struct obstack *rtl_obstack;
|
||||
|
||||
static rtx make_jump_insn_raw PROTO((rtx));
|
||||
static rtx make_call_insn_raw PROTO((rtx));
|
||||
static rtx find_line_note PROTO((rtx));
|
||||
|
@ -3370,6 +3373,199 @@ clear_emit_caches ()
|
|||
sequence_result[i] = 0;
|
||||
free_insn = 0;
|
||||
}
|
||||
|
||||
/* Used by copy_insn_1 to avoid copying SCRATCHes more than once. */
|
||||
static rtx copy_insn_scratch_in[MAX_RECOG_OPERANDS];
|
||||
static rtx copy_insn_scratch_out[MAX_RECOG_OPERANDS];
|
||||
static int copy_insn_n_scratches;
|
||||
|
||||
/* When an insn is being copied by copy_insn_1, this is nonzero if we have
|
||||
copied an ASM_OPERANDS.
|
||||
In that case, it is the original input-operand vector. */
|
||||
static rtvec orig_asm_operands_vector;
|
||||
|
||||
/* When an insn is being copied by copy_insn_1, this is nonzero if we have
|
||||
copied an ASM_OPERANDS.
|
||||
In that case, it is the copied input-operand vector. */
|
||||
static rtvec copy_asm_operands_vector;
|
||||
|
||||
/* Likewise for the constraints vector. */
|
||||
static rtvec orig_asm_constraints_vector;
|
||||
static rtvec copy_asm_constraints_vector;
|
||||
|
||||
/* Recursively create a new copy of an rtx for copy_insn.
|
||||
This function differs from copy_rtx in that it handles SCRATCHes and
|
||||
ASM_OPERANDs properly.
|
||||
Normally, this function is not used directly; use copy_insn as front end.
|
||||
However, you could first copy an insn pattern with copy_insn and then use
|
||||
this function afterwards to properly copy any REG_NOTEs containing
|
||||
SCRATCHes. */
|
||||
|
||||
rtx
|
||||
copy_insn_1 (orig)
|
||||
register rtx orig;
|
||||
{
|
||||
register rtx copy;
|
||||
register int i, j;
|
||||
register RTX_CODE code;
|
||||
register char *format_ptr;
|
||||
|
||||
code = GET_CODE (orig);
|
||||
|
||||
switch (code)
|
||||
{
|
||||
case REG:
|
||||
case QUEUED:
|
||||
case CONST_INT:
|
||||
case CONST_DOUBLE:
|
||||
case SYMBOL_REF:
|
||||
case CODE_LABEL:
|
||||
case PC:
|
||||
case CC0:
|
||||
case ADDRESSOF:
|
||||
return orig;
|
||||
|
||||
case SCRATCH:
|
||||
for (i = 0; i < copy_insn_n_scratches; i++)
|
||||
if (copy_insn_scratch_in[i] == orig)
|
||||
return copy_insn_scratch_out[i];
|
||||
break;
|
||||
|
||||
case CONST:
|
||||
/* CONST can be shared if it contains a SYMBOL_REF. If it contains
|
||||
a LABEL_REF, it isn't sharable. */
|
||||
if (GET_CODE (XEXP (orig, 0)) == PLUS
|
||||
&& GET_CODE (XEXP (XEXP (orig, 0), 0)) == SYMBOL_REF
|
||||
&& GET_CODE (XEXP (XEXP (orig, 0), 1)) == CONST_INT)
|
||||
return orig;
|
||||
break;
|
||||
|
||||
/* A MEM with a constant address is not sharable. The problem is that
|
||||
the constant address may need to be reloaded. If the mem is shared,
|
||||
then reloading one copy of this mem will cause all copies to appear
|
||||
to have been reloaded. */
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
copy = rtx_alloc (code);
|
||||
|
||||
/* Copy the various flags, and other information. We assume that
|
||||
all fields need copying, and then clear the fields that should
|
||||
not be copied. That is the sensible default behavior, and forces
|
||||
us to explicitly document why we are *not* copying a flag. */
|
||||
memcpy (copy, orig, sizeof (struct rtx_def) - sizeof (rtunion));
|
||||
|
||||
/* We do not copy the USED flag, which is used as a mark bit during
|
||||
walks over the RTL. */
|
||||
copy->used = 0;
|
||||
|
||||
/* We do not copy JUMP, CALL, or FRAME_RELATED for INSNs. */
|
||||
if (GET_RTX_CLASS (code) == 'i')
|
||||
{
|
||||
copy->jump = 0;
|
||||
copy->call = 0;
|
||||
copy->frame_related = 0;
|
||||
}
|
||||
|
||||
format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
|
||||
|
||||
for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
|
||||
{
|
||||
switch (*format_ptr++)
|
||||
{
|
||||
case 'e':
|
||||
XEXP (copy, i) = XEXP (orig, i);
|
||||
if (XEXP (orig, i) != NULL)
|
||||
XEXP (copy, i) = copy_insn_1 (XEXP (orig, i));
|
||||
break;
|
||||
|
||||
case '0':
|
||||
case 'u':
|
||||
XEXP (copy, i) = XEXP (orig, i);
|
||||
break;
|
||||
|
||||
case 'E':
|
||||
case 'V':
|
||||
XVEC (copy, i) = XVEC (orig, i);
|
||||
if (XVEC (orig, i) == orig_asm_constraints_vector)
|
||||
XVEC (copy, i) = copy_asm_constraints_vector;
|
||||
else if (XVEC (orig, i) == orig_asm_operands_vector)
|
||||
XVEC (copy, i) = copy_asm_operands_vector;
|
||||
else if (XVEC (orig, i) != NULL)
|
||||
{
|
||||
XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
|
||||
for (j = 0; j < XVECLEN (copy, i); j++)
|
||||
XVECEXP (copy, i, j) = copy_insn_1 (XVECEXP (orig, i, j));
|
||||
}
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
{
|
||||
bitmap new_bits = BITMAP_OBSTACK_ALLOC (rtl_obstack);
|
||||
bitmap_copy (new_bits, XBITMAP (orig, i));
|
||||
XBITMAP (copy, i) = new_bits;
|
||||
break;
|
||||
}
|
||||
|
||||
case 't':
|
||||
XTREE (copy, i) = XTREE (orig, i);
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
XWINT (copy, i) = XWINT (orig, i);
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
XINT (copy, i) = XINT (orig, i);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
case 'S':
|
||||
XSTR (copy, i) = XSTR (orig, i);
|
||||
break;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
if (code == SCRATCH)
|
||||
{
|
||||
i = copy_insn_n_scratches++;
|
||||
if (i >= MAX_RECOG_OPERANDS)
|
||||
abort ();
|
||||
copy_insn_scratch_in[i] = orig;
|
||||
copy_insn_scratch_out[i] = copy;
|
||||
}
|
||||
else if (code == ASM_OPERANDS)
|
||||
{
|
||||
orig_asm_operands_vector = XVEC (orig, 3);
|
||||
copy_asm_operands_vector = XVEC (copy, 3);
|
||||
orig_asm_constraints_vector = XVEC (orig, 4);
|
||||
copy_asm_constraints_vector = XVEC (copy, 4);
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
/* Create a new copy of an rtx.
|
||||
This function differs from copy_rtx in that it handles SCRATCHes and
|
||||
ASM_OPERANDs properly.
|
||||
INSN doesn't really have to be a full INSN; it could be just the
|
||||
pattern. */
|
||||
rtx
|
||||
copy_insn (insn)
|
||||
rtx insn;
|
||||
{
|
||||
copy_insn_n_scratches = 0;
|
||||
orig_asm_operands_vector = 0;
|
||||
orig_asm_constraints_vector = 0;
|
||||
copy_asm_operands_vector = 0;
|
||||
copy_asm_constraints_vector = 0;
|
||||
return copy_insn_1 (insn);
|
||||
}
|
||||
|
||||
/* Initialize data structures and variables in this file
|
||||
before generating rtl for each function. */
|
||||
|
|
11
gcc/jump.c
11
gcc/jump.c
|
@ -2805,8 +2805,7 @@ duplicate_loop_exit_test (loop_start)
|
|||
remove_note (insn, p);
|
||||
if (++num_insns > 20
|
||||
|| find_reg_note (insn, REG_RETVAL, NULL_RTX)
|
||||
|| find_reg_note (insn, REG_LIBCALL, NULL_RTX)
|
||||
|| asm_noperands (PATTERN (insn)) > 0)
|
||||
|| find_reg_note (insn, REG_LIBCALL, NULL_RTX))
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
|
@ -2869,7 +2868,7 @@ duplicate_loop_exit_test (loop_start)
|
|||
break;
|
||||
|
||||
case INSN:
|
||||
copy = emit_insn_before (copy_rtx (PATTERN (insn)), loop_start);
|
||||
copy = emit_insn_before (copy_insn (PATTERN (insn)), loop_start);
|
||||
if (reg_map)
|
||||
replace_regs (PATTERN (copy), reg_map, max_reg, 1);
|
||||
|
||||
|
@ -2880,7 +2879,7 @@ duplicate_loop_exit_test (loop_start)
|
|||
for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
|
||||
if (REG_NOTE_KIND (link) != REG_LABEL)
|
||||
REG_NOTES (copy)
|
||||
= copy_rtx (gen_rtx_EXPR_LIST (REG_NOTE_KIND (link),
|
||||
= copy_insn_1 (gen_rtx_EXPR_LIST (REG_NOTE_KIND (link),
|
||||
XEXP (link, 0),
|
||||
REG_NOTES (copy)));
|
||||
if (reg_map && REG_NOTES (copy))
|
||||
|
@ -2888,13 +2887,13 @@ duplicate_loop_exit_test (loop_start)
|
|||
break;
|
||||
|
||||
case JUMP_INSN:
|
||||
copy = emit_jump_insn_before (copy_rtx (PATTERN (insn)), loop_start);
|
||||
copy = emit_jump_insn_before (copy_insn (PATTERN (insn)), loop_start);
|
||||
if (reg_map)
|
||||
replace_regs (PATTERN (copy), reg_map, max_reg, 1);
|
||||
mark_jump_label (PATTERN (copy), copy, 0);
|
||||
if (REG_NOTES (insn))
|
||||
{
|
||||
REG_NOTES (copy) = copy_rtx (REG_NOTES (insn));
|
||||
REG_NOTES (copy) = copy_insn_1 (REG_NOTES (insn));
|
||||
if (reg_map)
|
||||
replace_regs (REG_NOTES (copy), reg_map, max_reg, 1);
|
||||
}
|
||||
|
|
|
@ -974,6 +974,8 @@ extern char *oballoc PROTO((int));
|
|||
extern char *permalloc PROTO((int));
|
||||
extern rtx rtx_alloc PROTO((RTX_CODE));
|
||||
extern rtvec rtvec_alloc PROTO((int));
|
||||
extern rtx copy_insn_1 PROTO((rtx));
|
||||
extern rtx copy_insn PROTO((rtx));
|
||||
extern rtx copy_rtx PROTO((rtx));
|
||||
extern rtx copy_rtx_if_shared PROTO((rtx));
|
||||
extern rtx copy_most_rtx PROTO((rtx, rtx));
|
||||
|
|
Loading…
Reference in New Issue