diff options
author | Richard Kenner <kenner@gcc.gnu.org> | 1992-04-02 06:03:52 -0500 |
---|---|---|
committer | Richard Kenner <kenner@gcc.gnu.org> | 1992-04-02 06:03:52 -0500 |
commit | 29ebe69a723a07771383e4cddc917521ee6e82bd (patch) | |
tree | 672b626b63ce454b1ae9629f4e26a65581e0e2f3 /gcc/optabs.c | |
parent | d64be5ecc9c27800b5e6cf09ec50a1e1ad1d5d2a (diff) | |
download | gcc-29ebe69a723a07771383e4cddc917521ee6e82bd.tar.gz |
*** empty log message ***
From-SVN: r666
Diffstat (limited to 'gcc/optabs.c')
-rw-r--r-- | gcc/optabs.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/gcc/optabs.c b/gcc/optabs.c index b1578531a50..c345fc9d294 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -1315,6 +1315,16 @@ emit_no_conflict_block (insns, target, op0, op1, equiv) an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL note with an operand of EQUIV. + Moving assignments to pseudos outside of the block is done to improve + the generated code, but is not required to generate correct code, + hence being unable to move an assignment is not grounds for not making + a libcall block. There are two reasons why it is safe to leave these + insns inside the block: First, we know that these pseudos cannot be + used in generated RTL outside the block since they are created for + temporary purposes within the block. Second, CSE will not record the + values of anything set inside a libcall block, so we know they must + be dead at the end of the block. + Except for the first group of insns (the ones setting pseudos), the block is delimited by REG_RETVAL and REG_LIBCALL notes. */ @@ -1328,7 +1338,9 @@ emit_libcall_block (insns, target, result, equiv) rtx prev, next, first, last, insn; /* First emit all insns that set pseudos. Remove them from the list as - we go. */ + we go. Avoid insns that set pseudo which were referenced in previous + insns. These can be generated by move_by_pieces, for example, + to update an address. */ for (insn = insns; insn; insn = next) { @@ -1337,7 +1349,9 @@ emit_libcall_block (insns, target, result, equiv) next = NEXT_INSN (insn); if (set != 0 && GET_CODE (SET_DEST (set)) == REG - && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER) + && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER + && ! reg_mentioned_p (SET_DEST (set), PATTERN (insns)) + && ! reg_used_between_p (SET_DEST (set), insns, insn)) { if (PREV_INSN (insn)) NEXT_INSN (PREV_INSN (insn)) = next; |