From: Bernd Schmidt Date: Fri, 8 Oct 1999 17:39:10 +0000 (+0000) Subject: Add functions copy_insn/copy_insn_1; use them in jump.c X-Git-Tag: prereleases/libstdc++-2.92~10157 X-Git-Url: https://gcc.gnu.org/git/?a=commitdiff_plain;h=da43a810ca70d16ba1a53e4e28c9701e1708d5ee;p=gcc.git Add functions copy_insn/copy_insn_1; use them in jump.c From-SVN: r29870 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6fd99de02cd8..dfe8f967d996 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +Fri Oct 8 18:46:11 1999 Bernd Schmidt + + * 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 * 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 3d59220378cd..9f6819771439 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 f6e973e85b9d..2328d8f06998 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 b23727266071..5f3e68983dc2 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));