diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c305c9b5c11..7adec343830 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2000-12-29 Bernd Schmidt + + * emit-rtl.c (gen_raw_REG): New function. + (gen_rtx_REG, gen_reg_rtx, init_emit_once): Use it instead of + gen_rtx_raw_REG. + * print-rtl.c (print_rtx): Print ORIGINAL_REGNO. + * final.c (alter_subreg): Update it. + * regrename.c (do_replace): Likewise. Use gen_raw_REG. + * rtl.def (REG): Update comment. + * rtl.h (X0UINT, ORIGINAL_REGNO): New macros. + (gen_raw_REG): Declare. + 2000-12-29 Richard Kenner * tree.c (get_set_constructor_bits): Use host_integerp and diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index 5d60100050c..9f2a4ae4595 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -228,6 +228,20 @@ rtx_htab_mark (htab) htab_traverse (*((htab_t *) htab), rtx_htab_mark_1, NULL); } +/* Generate a new REG rtx. Make sure ORIGINAL_REGNO is set properly, and + don't attempt to share with the various global pieces of rtl (such as + frame_pointer_rtx). */ + +rtx +gen_raw_REG (mode, regno) + enum machine_mode mode; + int regno; +{ + rtx x = gen_rtx_raw_REG (mode, regno); + ORIGINAL_REGNO (x) = regno; + return x; +} + /* There are some RTL codes that require special attention; the generation functions do the raw handling. If you add to this list, modify special_rtx in gengenrtl.c as well. */ @@ -319,7 +333,7 @@ gen_rtx_REG (mode, regno) return stack_pointer_rtx; } - return gen_rtx_raw_REG (mode, regno); + return gen_raw_REG (mode, regno); } rtx @@ -569,7 +583,7 @@ gen_reg_rtx (mode) f->emit->regno_pointer_align_length = old_size * 2; } - val = gen_rtx_raw_REG (mode, reg_rtx_no); + val = gen_raw_REG (mode, reg_rtx_no); regno_reg_rtx[reg_rtx_no++] = val; return val; } @@ -4053,22 +4067,22 @@ init_emit_once (line_numbers) pc_rtx = gen_rtx (PC, VOIDmode); cc0_rtx = gen_rtx (CC0, VOIDmode); - stack_pointer_rtx = gen_rtx_raw_REG (Pmode, STACK_POINTER_REGNUM); - frame_pointer_rtx = gen_rtx_raw_REG (Pmode, FRAME_POINTER_REGNUM); + stack_pointer_rtx = gen_raw_REG (Pmode, STACK_POINTER_REGNUM); + frame_pointer_rtx = gen_raw_REG (Pmode, FRAME_POINTER_REGNUM); if (hard_frame_pointer_rtx == 0) - hard_frame_pointer_rtx = gen_rtx_raw_REG (Pmode, - HARD_FRAME_POINTER_REGNUM); + hard_frame_pointer_rtx = gen_raw_REG (Pmode, + HARD_FRAME_POINTER_REGNUM); if (arg_pointer_rtx == 0) - arg_pointer_rtx = gen_rtx_raw_REG (Pmode, ARG_POINTER_REGNUM); + arg_pointer_rtx = gen_raw_REG (Pmode, ARG_POINTER_REGNUM); virtual_incoming_args_rtx = - gen_rtx_raw_REG (Pmode, VIRTUAL_INCOMING_ARGS_REGNUM); + gen_raw_REG (Pmode, VIRTUAL_INCOMING_ARGS_REGNUM); virtual_stack_vars_rtx = - gen_rtx_raw_REG (Pmode, VIRTUAL_STACK_VARS_REGNUM); + gen_raw_REG (Pmode, VIRTUAL_STACK_VARS_REGNUM); virtual_stack_dynamic_rtx = - gen_rtx_raw_REG (Pmode, VIRTUAL_STACK_DYNAMIC_REGNUM); + gen_raw_REG (Pmode, VIRTUAL_STACK_DYNAMIC_REGNUM); virtual_outgoing_args_rtx = - gen_rtx_raw_REG (Pmode, VIRTUAL_OUTGOING_ARGS_REGNUM); - virtual_cfa_rtx = gen_rtx_raw_REG (Pmode, VIRTUAL_CFA_REGNUM); + gen_raw_REG (Pmode, VIRTUAL_OUTGOING_ARGS_REGNUM); + virtual_cfa_rtx = gen_raw_REG (Pmode, VIRTUAL_CFA_REGNUM); /* These rtx must be roots if GC is enabled. */ ggc_add_rtx_root (global_rtl, GR_MAX); @@ -4148,7 +4162,7 @@ init_emit_once (line_numbers) #ifdef RETURN_ADDRESS_POINTER_REGNUM return_address_pointer_rtx - = gen_rtx_raw_REG (Pmode, RETURN_ADDRESS_POINTER_REGNUM); + = gen_raw_REG (Pmode, RETURN_ADDRESS_POINTER_REGNUM); #endif #ifdef STRUCT_VALUE diff --git a/gcc/final.c b/gcc/final.c index bbdb59eb13e..0d9d2a3bb61 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -3169,6 +3169,7 @@ alter_subreg (x) #endif PUT_CODE (x, REG); REGNO (x) = regno; + ORIGINAL_REGNO (x) = ORIGINAL_REGNO (y); /* This field has a different meaning for REGs and SUBREGs. Make sure to clear it! */ x->used = 0; diff --git a/gcc/print-rtl.c b/gcc/print-rtl.c index d895ce4bfb6..502834dd81a 100644 --- a/gcc/print-rtl.c +++ b/gcc/print-rtl.c @@ -170,6 +170,12 @@ print_rtx (in_rtx) An exception is the third field of a NOTE, where it indicates that the field has several different valid contents. */ case '0': + if (i == 1 && GET_CODE (in_rtx) == REG) + { + if (REGNO (in_rtx) != ORIGINAL_REGNO (in_rtx)) + fprintf (outfile, " [%d]", ORIGINAL_REGNO (in_rtx)); + break; + } if (i == 3 && GET_CODE (in_rtx) == NOTE) { switch (NOTE_LINE_NUMBER (in_rtx)) diff --git a/gcc/regrename.c b/gcc/regrename.c index bca986d24a4..bb45f3a2953 100644 --- a/gcc/regrename.c +++ b/gcc/regrename.c @@ -349,7 +349,9 @@ do_replace (chain, reg) { while (chain) { - *chain->loc = gen_rtx_REG (GET_MODE (*chain->loc), reg); + unsigned int regno = ORIGINAL_REGNO (*chain->loc); + *chain->loc = gen_raw_REG (GET_MODE (*chain->loc), reg); + ORIGINAL_REGNO (*chain->loc) = regno; chain = chain->next_use; } } diff --git a/gcc/rtl.def b/gcc/rtl.def index fcad7ec4b21..6f0aec86b5a 100644 --- a/gcc/rtl.def +++ b/gcc/rtl.def @@ -583,12 +583,10 @@ DEF_RTL_EXPR(VALUE, "value", "0", 'o') /* A register. The "operand" is the register number, accessed with the REGNO macro. If this number is less than FIRST_PSEUDO_REGISTER than a hardware register is being referred to. The second operand - doesn't really exist. Unfortunately, however, the compiler - implicitly assumes that a REG can be transformed in place into a - MEM, and therefore that a REG is at least as big as a MEM. To - avoid this memory overhead, which is likely to be substantial, - search for uses of PUT_CODE that turn REGs into MEMs, and fix them - somehow. Then, the trailing `0' can be removed here. */ + holds the original register number - this will be different for a + pseudo register that got turned into a hard register. + This rtx needs to have as many (or more) fields as a MEM, since we + can change REG rtx's into MEMs during reload. */ DEF_RTL_EXPR(REG, "reg", "i0", 'o') /* A scratch register. This represents a register used only within a diff --git a/gcc/rtl.h b/gcc/rtl.h index e1fd687e1c7..a79e27a737e 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -328,6 +328,7 @@ extern void rtvec_check_failed_bounds PARAMS ((rtvec, int, #define X0WINT(RTX, N) (RTL_CHECK1(RTX, N, '0').rtwint) #define X0INT(RTX, N) (RTL_CHECK1(RTX, N, '0').rtint) +#define X0UINT(RTX, N) (RTL_CHECK1(RTX, N, '0').rtuint) #define X0STR(RTX, N) (RTL_CHECK1(RTX, N, '0').rtstr) #define X0EXP(RTX, N) (RTL_CHECK1(RTX, N, '0').rtx) #define X0VEC(RTX, N) (RTL_CHECK1(RTX, N, '0').rtvec) @@ -742,9 +743,12 @@ extern const char * const note_insn_name[NOTE_INSN_MAX - NOTE_INSN_BIAS]; #define CONTAINING_INSN(RTX) XCEXP(RTX, 2, LABEL_REF) -/* For a REG rtx, REGNO extracts the register number. */ +/* For a REG rtx, REGNO extracts the register number. ORIGINAL_REGNO holds + the number the register originally had; for a pseudo register turned into + a hard reg this will hold the old pseudo register number. */ #define REGNO(RTX) XCUINT(RTX, 0, REG) +#define ORIGINAL_REGNO(RTX) X0UINT(RTX, 1) /* For a REG rtx, REG_FUNCTION_VALUE_P is nonzero if the reg is the current function's return value. */ @@ -1539,6 +1543,7 @@ extern rtx return_address_pointer_rtx; extern rtx gen_rtx_CONST_DOUBLE PARAMS ((enum machine_mode, rtx, HOST_WIDE_INT, HOST_WIDE_INT)); extern rtx gen_rtx_CONST_INT PARAMS ((enum machine_mode, HOST_WIDE_INT)); +extern rtx gen_raw_REG PARAMS ((enum machine_mode, int)); extern rtx gen_rtx_REG PARAMS ((enum machine_mode, int)); extern rtx gen_rtx_MEM PARAMS ((enum machine_mode, rtx));