From 902197eb4fbf3b936300d6df647e9d978d32ca28 Mon Sep 17 00:00:00 2001 From: DJ Delorie Date: Wed, 14 Nov 2001 22:02:24 -0500 Subject: [PATCH] integrate.c (get_hard_reg_initial_reg): New. * integrate.c (get_hard_reg_initial_reg): New. * integrate.h (get_hard_reg_initial_reg): Prototype. * local-alloc.c (block_alloc): Don't tie pseudos that represent call-saved hard regs' initial values. From-SVN: r47037 --- gcc/ChangeLog | 7 +++++++ gcc/integrate.c | 18 ++++++++++++++++++ gcc/integrate.h | 3 +++ gcc/local-alloc.c | 15 ++++++++++++++- 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 083f0d9ddac..c7e5fba7ba5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2001-11-14 DJ Delorie + + * integrate.c (get_hard_reg_initial_reg): New. + * integrate.h (get_hard_reg_initial_reg): Prototype. + * local-alloc.c (block_alloc): Don't tie pseudos that + represent call-saved hard regs' initial values. + 2001-11-14 Kaveh R. Ghazi * m68k/linux.h: Include not "linux.h" to avoid infinite diff --git a/gcc/integrate.c b/gcc/integrate.c index 4bcfc226c75..4aa87006f2c 100644 --- a/gcc/integrate.c +++ b/gcc/integrate.c @@ -2963,6 +2963,24 @@ output_inline_function (fndecl) /* Functions to keep track of the values hard regs had at the start of the function. */ +rtx +get_hard_reg_initial_reg (fun, reg) + struct function *fun; + rtx reg; +{ + struct initial_value_struct *ivs = fun->hard_reg_initial_vals; + int i; + + if (ivs == 0) + return NULL_RTX; + + for (i = 0; i < ivs->num_entries; i++) + if (rtx_equal_p (ivs->entries[i].pseudo, reg)) + return ivs->entries[i].hard_reg; + + return NULL_RTX; +} + rtx has_func_hard_reg_initial_val (fun, reg) struct function *fun; diff --git a/gcc/integrate.h b/gcc/integrate.h index c96d0112af4..9ddefefc956 100644 --- a/gcc/integrate.h +++ b/gcc/integrate.h @@ -140,6 +140,9 @@ extern rtx get_func_hard_reg_initial_val PARAMS ((struct function *, rtx)); extern rtx has_func_hard_reg_initial_val PARAMS ((struct function *, rtx)); /* Likewise, but for common cases. */ extern rtx has_hard_reg_initial_val PARAMS ((enum machine_mode, int)); +/* If a pseudo represents an initial hard reg (or expression), return + it, else return NULL_RTX. */ +extern rtx get_hard_reg_initial_reg PARAMS ((struct function *, rtx)); /* This is for GC. */ extern void mark_hard_reg_initial_vals PARAMS ((struct function *)); /* Called from rest_of_compilation. */ diff --git a/gcc/local-alloc.c b/gcc/local-alloc.c index 7de721e8f09..1c45ae4f069 100644 --- a/gcc/local-alloc.c +++ b/gcc/local-alloc.c @@ -74,6 +74,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "output.h" #include "toplev.h" #include "except.h" +#include "integrate.h" /* Next quantity number available for allocation. */ @@ -1216,7 +1217,7 @@ block_alloc (b) { int i, q; rtx insn; - rtx note; + rtx note, hard_reg; int insn_number = 0; int insn_count = 0; int max_uid = get_max_uid (); @@ -1340,6 +1341,18 @@ block_alloc (b) while (GET_CODE (r1) == PLUS || GET_CODE (r1) == MULT) r1 = XEXP (r1, 0); + /* Avoid making a call-saved register unnecessarily + clobbered. */ + hard_reg = get_hard_reg_initial_reg (cfun, r1); + if (hard_reg != NULL_RTX) + { + if (GET_CODE (hard_reg) == REG + && REGNO (hard_reg) >= 0 + && REGNO (hard_reg) < FIRST_PSEUDO_REGISTER + && ! call_used_regs[REGNO (hard_reg)]) + continue; + } + if (GET_CODE (r0) == REG || GET_CODE (r0) == SUBREG) { /* We have two priorities for hard register preferences. -- 2.30.2