From 7c2cc97e87a590de3744e03a25c262826087d3bc Mon Sep 17 00:00:00 2001 From: hubicka Date: Sun, 29 Jul 2001 21:28:42 +0000 Subject: [PATCH] * rtlanal.c (parms_set, find_first_parameter_load): Break out from...; handle multiple sets. * except.c (sjlj_mark_call_sites): .... here. * gcse.c (insert_insn_end_bb): Use find_first_parameter_load. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@44465 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 7 ++++++ gcc/except.c | 46 +------------------------------------ gcc/gcse.c | 32 +------------------------- gcc/rtl.h | 1 + gcc/rtlanal.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 84 insertions(+), 76 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1c84286..e332746 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +Sun Jul 29 23:26:50 CEST 2001 Jan Hubicka + + * rtlanal.c (parms_set, find_first_parameter_load): Break out from...; + handle multiple sets. + * except.c (sjlj_mark_call_sites): .... here. + * gcse.c (insert_insn_end_bb): Use find_first_parameter_load. + Sun Jul 29 21:38:45 CEST 2001 Jan Hubicka Suggested by Richard Henderson and Richard Kenner: diff --git a/gcc/except.c b/gcc/except.c index 49df0df..0ed89a0 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -2083,51 +2083,7 @@ sjlj_mark_call_sites (lp_info) /* Don't separate a call from it's argument loads. */ before = insn; if (GET_CODE (insn) == CALL_INSN) - { - HARD_REG_SET parm_regs; - int nparm_regs; - - /* Since different machines initialize their parameter registers - in different orders, assume nothing. Collect the set of all - parameter registers. */ - CLEAR_HARD_REG_SET (parm_regs); - nparm_regs = 0; - for (p = CALL_INSN_FUNCTION_USAGE (insn); p ; p = XEXP (p, 1)) - if (GET_CODE (XEXP (p, 0)) == USE - && GET_CODE (XEXP (XEXP (p, 0), 0)) == REG) - { - if (REGNO (XEXP (XEXP (p, 0), 0)) >= FIRST_PSEUDO_REGISTER) - abort (); - - /* We only care about registers which can hold function - arguments. */ - if (! FUNCTION_ARG_REGNO_P (REGNO (XEXP (XEXP (p, 0), 0)))) - continue; - - SET_HARD_REG_BIT (parm_regs, REGNO (XEXP (XEXP (p, 0), 0))); - nparm_regs++; - } - - /* Search backward for the first set of a register in this set. */ - while (nparm_regs) - { - before = PREV_INSN (before); - - /* Given that we've done no other optimizations yet, - the arguments should be immediately available. */ - if (GET_CODE (before) == CODE_LABEL) - abort (); - - p = single_set (before); - if (p && GET_CODE (SET_DEST (p)) == REG - && REGNO (SET_DEST (p)) < FIRST_PSEUDO_REGISTER - && TEST_HARD_REG_BIT (parm_regs, REGNO (SET_DEST (p)))) - { - CLEAR_HARD_REG_BIT (parm_regs, REGNO (SET_DEST (p))); - nparm_regs--; - } - } - } + before = find_first_parameter_load (insn, NULL_RTX); start_sequence (); emit_move_insn (mem, GEN_INT (this_call_site)); diff --git a/gcc/gcse.c b/gcc/gcse.c index fa18777..70ed275 100644 --- a/gcc/gcse.c +++ b/gcc/gcse.c @@ -4649,38 +4649,8 @@ insert_insn_end_bb (expr, bb, pre) /* Since different machines initialize their parameter registers in different orders, assume nothing. Collect the set of all parameter registers. */ - CLEAR_HARD_REG_SET (parm_regs); - nparm_regs = 0; - for (p = CALL_INSN_FUNCTION_USAGE (insn); p ; p = XEXP (p, 1)) - if (GET_CODE (XEXP (p, 0)) == USE - && GET_CODE (XEXP (XEXP (p, 0), 0)) == REG) - { - if (REGNO (XEXP (XEXP (p, 0), 0)) >= FIRST_PSEUDO_REGISTER) - abort (); - - /* We only care about registers which can hold function - arguments. */ - if (! FUNCTION_ARG_REGNO_P (REGNO (XEXP (XEXP (p, 0), 0)))) - continue; - - SET_HARD_REG_BIT (parm_regs, REGNO (XEXP (XEXP (p, 0), 0))); - nparm_regs++; - } + insn = find_first_parameter_load (insn, bb->head); - /* Search backward for the first set of a register in this set. */ - while (nparm_regs && bb->head != insn) - { - insn = PREV_INSN (insn); - p = single_set (insn); - if (p && GET_CODE (SET_DEST (p)) == REG - && REGNO (SET_DEST (p)) < FIRST_PSEUDO_REGISTER - && TEST_HARD_REG_BIT (parm_regs, REGNO (SET_DEST (p)))) - { - CLEAR_HARD_REG_BIT (parm_regs, REGNO (SET_DEST (p))); - nparm_regs--; - } - } - /* If we found all the parameter loads, then we want to insert before the first parameter load. diff --git a/gcc/rtl.h b/gcc/rtl.h index da454c2..3a97da3 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -1432,6 +1432,7 @@ extern int auto_inc_p PARAMS ((rtx)); extern void remove_node_from_expr_list PARAMS ((rtx, rtx *)); extern int insns_safe_to_move_p PARAMS ((rtx, rtx, rtx *)); extern int loc_mentioned_in_p PARAMS ((rtx *, rtx)); +extern rtx find_first_parameter_load PARAMS ((rtx, rtx)); /* flow.c */ diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index 92220f6..9762f9e 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -31,6 +31,7 @@ static void set_of_1 PARAMS ((rtx, rtx, void *)); static void insn_dependent_p_1 PARAMS ((rtx, rtx, void *)); static int computed_jump_p_1 PARAMS ((rtx)); static int operand_preference PARAMS ((rtx)); +static void parms_set PARAMS ((rtx, rtx, void *)); /* Bit flags that specify the machine subtype we are compiling for. Bits are tested using macros TARGET_... defined in the tm.h file @@ -2788,3 +2789,76 @@ subreg_regno (x) return ret; } +struct parms_set_data +{ + int nregs; + HARD_REG_SET regs; +}; + +/* Helper function for noticing stores to parameter registers. */ +static void +parms_set (x, pat, data) + rtx x, pat ATTRIBUTE_UNUSED; + void *data; +{ + struct parms_set_data *d = data; + if (REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER + && TEST_HARD_REG_BIT (d->regs, REGNO (x))) + { + CLEAR_HARD_REG_BIT (d->regs, REGNO (x)); + d->nregs--; + } +} + +/* Look backward for first parameter to be loaded. + Do not skip BOUNDARY. */ +rtx +find_first_parameter_load (call_insn, boundary) + rtx call_insn, boundary; +{ + struct parms_set_data parm; + rtx p, before; + + /* Since different machines initialize their parameter registers + in different orders, assume nothing. Collect the set of all + parameter registers. */ + CLEAR_HARD_REG_SET (parm.regs); + parm.nregs = 0; + for (p = CALL_INSN_FUNCTION_USAGE (call_insn); p; p = XEXP (p, 1)) + if (GET_CODE (XEXP (p, 0)) == USE + && GET_CODE (XEXP (XEXP (p, 0), 0)) == REG) + { + if (REGNO (XEXP (XEXP (p, 0), 0)) >= FIRST_PSEUDO_REGISTER) + abort (); + + /* We only care about registers which can hold function + arguments. */ + if (!FUNCTION_ARG_REGNO_P (REGNO (XEXP (XEXP (p, 0), 0)))) + continue; + + SET_HARD_REG_BIT (parm.regs, REGNO (XEXP (XEXP (p, 0), 0))); + parm.nregs++; + } + before = call_insn; + + /* Search backward for the first set of a register in this set. */ + while (parm.nregs && before != boundary) + { + before = PREV_INSN (before); + + /* It is possible that some loads got CSEed from one call to + another. Stop in that case. */ + if (GET_CODE (before) == CALL_INSN) + break; + + /* Our caller needs eighter ensure, that we will find all sets + (in case code has not been optimized yet), or take care + for possible labels in a way by setting boundary to preceeding + CODE_LABEL. */ + if (GET_CODE (before) == CODE_LABEL && before != boundary) + abort (); + + note_stores (PATTERN (before), parms_set, &parm); + } + return before; +} -- 2.7.4