From 3947e2f9840de6201a06267c05fea6f1eb47256a Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 7 Oct 1998 03:08:16 -0700 Subject: [PATCH] gcse.c (pre_insert_insn): When a call ends a bb, insert the new insns before the argument regs are loaded. * gcse.c (pre_insert_insn): When a call ends a bb, insert the new insns before the argument regs are loaded. From-SVN: r22891 --- gcc/ChangeLog | 5 ++++ gcc/gcse.c | 66 ++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 63 insertions(+), 8 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 674da88166f..e6ff5938796 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +Wed Oct 7 10:07:29 1998 Richard Henderson + + * gcse.c (pre_insert_insn): When a call ends a bb, insert + the new insns before the argument regs are loaded. + Wed Oct 7 12:55:26 1998 Kaveh R. Ghazi * Makefile.in (c-gperf.h): Add -L KR-C -F ', 0, 0' flags to gperf. diff --git a/gcc/gcse.c b/gcc/gcse.c index a992d111ea1..463959d520a 100644 --- a/gcc/gcse.c +++ b/gcc/gcse.c @@ -4373,22 +4373,72 @@ pre_insert_insn (expr, bb) add_label_notes (SET_SRC (pat), new_insn); if (BLOCK_HEAD (bb) == insn) BLOCK_HEAD (bb) = new_insn; - /* Keep block number table up to date. */ - set_block_num (new_insn, bb); - /* Keep register set table up to date. */ - record_one_set (regno, new_insn); + } + /* Likewise if the last insn is a call, as will happen in the presence + of exception handling. */ + else if (GET_CODE (insn) == CALL_INSN) + { + HARD_REG_SET parm_regs; + int nparm_regs; + rtx p; + + /* Keeping in mind SMALL_REGISTER_CLASSES and parameters in registers, + we search backward and place the instructions before the first + parameter is loaded. Do this for everyone for consistency and a + presumtion that we'll get better code elsewhere as well. */ + + /* It should always be the case that we can put these instructions + anywhere in the basic block. Check this. */ + if (!TEST_BIT (pre_antloc[bb], expr->bitmap_index) + && !TEST_BIT (pre_transp[bb], expr->bitmap_index)) + abort (); + + /* 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) + { + int regno = REGNO (XEXP (XEXP (p, 0), 0)); + if (regno >= FIRST_PSEUDO_REGISTER) + abort(); + SET_HARD_REG_BIT (parm_regs, regno); + nparm_regs++; + } + + /* Search backward for the first set of a register in this set. */ + while (nparm_regs && BLOCK_HEAD (bb) != 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--; + } + } + + new_insn = emit_insn_before (pat, insn); + if (BLOCK_HEAD (bb) == insn) + BLOCK_HEAD (bb) = new_insn; } else { new_insn = emit_insn_after (pat, insn); add_label_notes (SET_SRC (pat), new_insn); BLOCK_END (bb) = new_insn; - /* Keep block number table up to date. */ - set_block_num (new_insn, bb); - /* Keep register set table up to date. */ - record_one_set (regno, new_insn); } + /* Keep block number table up to date. */ + set_block_num (new_insn, bb); + /* Keep register set table up to date. */ + record_one_set (regno, new_insn); + gcse_create_count++; if (gcse_file) -- 2.30.2