diff options
author | Jim Wilson <wilson@cygnus.com> | 1998-06-22 12:02:52 +0000 |
---|---|---|
committer | Jim Wilson <wilson@gcc.gnu.org> | 1998-06-22 05:02:52 -0700 |
commit | aeb2f500b073c09d86daf7d0cdbe71ddd9e1561c (patch) | |
tree | fcfeac16601900f555f6e18a00c09d9d28703514 /gcc/gcse.c | |
parent | efef624b6f02ae9bacb45069f79d88201b847f7c (diff) | |
download | gcc-aeb2f500b073c09d86daf7d0cdbe71ddd9e1561c.zip gcc-aeb2f500b073c09d86daf7d0cdbe71ddd9e1561c.tar.gz gcc-aeb2f500b073c09d86daf7d0cdbe71ddd9e1561c.tar.bz2 |
Fix irix6 -O3 -funroll-all-loops bootstrap failure reported by Kaveh Ghazi.
* gcse.c (add_label_notes): New function.
(pre_insert_insn): Call it.
* unroll.c (unroll_loop): Look for insns with a REG_LABEL note, and
pass the label to set_label_in_map.
From-SVN: r20658
Diffstat (limited to 'gcc/gcse.c')
-rw-r--r-- | gcc/gcse.c | 51 |
1 files changed, 51 insertions, 0 deletions
@@ -641,6 +641,8 @@ static void pre_insert_copies PROTO ((void)); static int pre_delete PROTO ((void)); static int pre_gcse PROTO ((void)); static int one_pre_gcse_pass PROTO ((rtx, int)); + +static void add_label_notes PROTO ((rtx, rtx)); /* Entry point for global common subexpression elimination. F is the first instruction in the function. */ @@ -4354,6 +4356,7 @@ pre_insert_insn (expr, bb) #endif /* FIXME: What if something in cc0/jump uses value set in new insn? */ new_insn = emit_insn_before (pat, insn); + 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. */ @@ -4364,6 +4367,7 @@ pre_insert_insn (expr, bb) 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); @@ -4695,3 +4699,50 @@ one_pre_gcse_pass (f, pass) return changed; } + +/* If X contains any LABEL_REF's, add REG_LABEL notes for them to INSN. + We have to add REG_LABEL notes, because the following loop optimization + pass requires them. */ + +/* ??? This is very similar to the loop.c add_label_notes function. We + could probably share code here. */ + +/* ??? If there was a jump optimization pass after gcse and before loop, + then we would not need to do this here, because jump would add the + necessary REG_LABEL notes. */ + +static void +add_label_notes (x, insn) + rtx x; + rtx insn; +{ + enum rtx_code code = GET_CODE (x); + int i, j; + char *fmt; + + if (code == LABEL_REF && !LABEL_REF_NONLOCAL_P (x)) + { + rtx next = next_real_insn (XEXP (x, 0)); + + /* Don't record labels that refer to dispatch tables. + This is not necessary, since the tablejump references the same label. + And if we did record them, flow.c would make worse code. */ + if (next == 0 + || ! (GET_CODE (next) == JUMP_INSN + && (GET_CODE (PATTERN (next)) == ADDR_VEC + || GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC))) + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_LABEL, XEXP (x, 0), + REG_NOTES (insn)); + return; + } + + fmt = GET_RTX_FORMAT (code); + for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) + { + if (fmt[i] == 'e') + add_label_notes (XEXP (x, i), insn); + else if (fmt[i] == 'E') + for (j = XVECLEN (x, i) - 1; j >= 0; j--) + add_label_notes (XVECEXP (x, i, j), insn); + } +} |