aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernd Schmidt <bernds@cygnus.co.uk>1999-10-08 17:39:10 +0000
committerBernd Schmidt <crux@gcc.gnu.org>1999-10-08 17:39:10 +0000
commitda43a810ca70d16ba1a53e4e28c9701e1708d5ee (patch)
tree6f2e50114b9e39ec7ea39b504e667a6a0f6631a9
parentb1afd7f4e03c52ed0b07387ad26e3e3c58595f28 (diff)
downloadgcc-da43a810ca70d16ba1a53e4e28c9701e1708d5ee.zip
gcc-da43a810ca70d16ba1a53e4e28c9701e1708d5ee.tar.gz
gcc-da43a810ca70d16ba1a53e4e28c9701e1708d5ee.tar.bz2
Add functions copy_insn/copy_insn_1; use them in jump.c
From-SVN: r29870
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/emit-rtl.c196
-rw-r--r--gcc/jump.c11
-rw-r--r--gcc/rtl.h2
4 files changed, 214 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6fd99de..dfe8f96 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 3d59220..9f68197 100644
--- a/gcc/emit-rtl.c
+++ b/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. */
diff --git a/gcc/jump.c b/gcc/jump.c
index f6e973e..2328d8f 100644
--- a/gcc/jump.c
+++ b/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);
}
diff --git a/gcc/rtl.h b/gcc/rtl.h
index b237272..5f3e689 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -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));