From 752ae91493c7b2a0d99405a35ecb42407762000d Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 14 Dec 2001 18:24:21 -0800 Subject: [PATCH] regrename.c (struct value_data): Add max_value_regs. * regrename.c (struct value_data): Add max_value_regs. (init_value_data): Initialize it. (kill_value): Kill values that overlap the dying register. (set_value_regno): New. (kill_set_value, kill_autoinc_value, copy_value): Use it. (copyprop_hardreg_forward_1): Kill earlyclobber operands before looking at inputs. From-SVN: r48028 --- gcc/ChangeLog | 16 +++++++++++++--- gcc/regrename.c | 50 +++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 59 insertions(+), 7 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cfa921d1c28..623adb9aa6e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2001-12-14 Richard Henderson + + * regrename.c (struct value_data): Add max_value_regs. + (init_value_data): Initialize it. + (kill_value): Kill values that overlap the dying register. + (set_value_regno): New. + (kill_set_value, kill_autoinc_value, copy_value): Use it. + (copyprop_hardreg_forward_1): Kill earlyclobber operands + before looking at inputs. + 2001-12-14 David Edelsohn * config/rs6000/rs6000.h (ASM_OUTPUT_DEF_FROM_DECLS): Handle @@ -180,8 +190,8 @@ Fri Dec 14 12:05:14 CET 2001 Jan Hubicka 2001-12-13 Aldy Hernandez * config/rs6000/rs6000.md (eh_set_lr_di): Change scratch - constraint to base register. - (eh_set_lr_si): Same. + constraint to base register. + (eh_set_lr_si): Same. 2001-12-13 Hans-Peter Nilsson @@ -284,7 +294,7 @@ Thu Dec 13 12:31:07 CET 2001 Jan Hubicka (flag_prefetch_loop_arrays): New global variable. (lang_independent_option): Add -fprefetch-loop-arrays. (rest_of_compilation) Pass LOOP_PREFETCH when flag_prefetch_loop_arrays - is set. + is set. * Makefile.in (toplev.c): Depend on insn-flags.h. * invoke.texi (-fprefetch-loop-arrays): Document. diff --git a/gcc/regrename.c b/gcc/regrename.c index e6aa8c8f9b9..4683de40620 100644 --- a/gcc/regrename.c +++ b/gcc/regrename.c @@ -984,10 +984,13 @@ struct value_data_entry struct value_data { struct value_data_entry e[FIRST_PSEUDO_REGISTER]; + unsigned int max_value_regs; }; static void kill_value_regno PARAMS ((unsigned, struct value_data *)); static void kill_value PARAMS ((rtx, struct value_data *)); +static void set_value_regno PARAMS ((unsigned, enum machine_mode, + struct value_data *)); static void init_value_data PARAMS ((struct value_data *)); static void kill_clobbered_value PARAMS ((rtx, rtx, void *)); static void kill_set_value PARAMS ((rtx, rtx, void *)); @@ -1054,13 +1057,46 @@ kill_value (x, vd) { unsigned int regno = REGNO (x); unsigned int n = HARD_REGNO_NREGS (regno, GET_MODE (x)); - unsigned int i; + unsigned int i, j; + /* Kill the value we're told to kill. */ for (i = 0; i < n; ++i) kill_value_regno (regno + i, vd); + + /* Kill everything that overlapped what we're told to kill. */ + if (regno < vd->max_value_regs) + j = 0; + else + j = regno - vd->max_value_regs; + for (; j < regno; ++j) + { + if (vd->e[j].mode == VOIDmode) + continue; + n = HARD_REGNO_NREGS (regno, vd->e[j].mode); + if (j + n > regno) + for (i = 0; i < n; ++i) + kill_value_regno (j + i, vd); + } } } +/* Remember that REGNO is valid in MODE. */ + +static void +set_value_regno (regno, mode, vd) + unsigned int regno; + enum machine_mode mode; + struct value_data *vd; +{ + unsigned int nregs; + + vd->e[regno].mode = mode; + + nregs = HARD_REGNO_NREGS (regno, mode); + if (nregs > vd->max_value_regs) + vd->max_value_regs = nregs; +} + /* Initialize VD such that there are no known relationships between regs. */ static void @@ -1074,6 +1110,7 @@ init_value_data (vd) vd->e[i].oldest_regno = i; vd->e[i].next_regno = INVALID_REGNUM; } + vd->max_value_regs = 0; } /* Called through note_stores. If X is clobbered, kill its value. */ @@ -1102,7 +1139,7 @@ kill_set_value (x, set, data) if (GET_CODE (set) != CLOBBER && REG_P (x)) { kill_value (x, vd); - vd->e[REGNO (x)].mode = GET_MODE (x); + set_value_regno (REGNO (x), GET_MODE (x), vd); } } @@ -1122,7 +1159,7 @@ kill_autoinc_value (px, data) { x = XEXP (x, 0); kill_value (x, vd); - vd->e[REGNO (x)].mode = Pmode; + set_value_regno (REGNO (x), Pmode, vd); return -1; } @@ -1160,7 +1197,7 @@ copy_value (dest, src, vd) assign it now and assume the value came from an input argument or somesuch. */ if (vd->e[sr].mode == VOIDmode) - vd->e[sr].mode = vd->e[dr].mode; + set_value_regno (sr, vd->e[dr].mode, vd); /* Link DR at the end of the value chain used by SR. */ @@ -1426,6 +1463,11 @@ copyprop_hardreg_forward_1 (bb, vd) /* ??? REG_INC is useless, since stack pushes aren't done that way. */ for_each_rtx (&PATTERN (insn), kill_autoinc_value, vd); + /* Kill all early-clobbered operands. */ + for (i = 0; i < n_ops; i++) + if (recog_op_alt[i][alt].earlyclobber) + kill_value (recog_data.operand[i], vd); + /* Special-case plain move instructions, since we may well be able to do the move from a different register class. */ if (set && REG_P (SET_SRC (set))) -- 2.30.2