diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-12-21 12:59:06 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-12-21 12:59:06 +0000 |
commit | 98154846568061a379099dc36ace942b0f07e826 (patch) | |
tree | 1d489ceef638d5a2452b97cc182f9c3fcf0a78e3 /gcc/config/ia64 | |
parent | 65e83e609ed2a9a4247780f645bba240b7a848d6 (diff) | |
download | gcc-98154846568061a379099dc36ace942b0f07e826.tar.gz |
PR target/30230
* config/ia64/ia64.c (ia64_add_bundle_selector_before): New function.
(bundling): Use it.
* g++.dg/eh/ia64-2.C: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@120103 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/ia64')
-rw-r--r-- | gcc/config/ia64/ia64.c | 59 |
1 files changed, 51 insertions, 8 deletions
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index d0a86a36b59..5ee5a00779b 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -7646,6 +7646,53 @@ get_next_important_insn (rtx insn, rtx tail) return NULL_RTX; } +/* Add a bundle selector TEMPLATE0 before INSN. */ + +static void +ia64_add_bundle_selector_before (int template0, rtx insn) +{ + rtx b = gen_bundle_selector (GEN_INT (template0)); + + ia64_emit_insn_before (b, insn); +#if NR_BUNDLES == 10 + if ((template0 == 4 || template0 == 5) + && (flag_unwind_tables || (flag_exceptions && !USING_SJLJ_EXCEPTIONS))) + { + int i; + rtx note = NULL_RTX; + + /* In .mbb and .bbb bundles, check if CALL_INSN isn't in the + first or second slot. If it is and has REG_EH_NOTE set, copy it + to following nops, as br.call sets rp to the address of following + bundle and therefore an EH region end must be on a bundle + boundary. */ + insn = PREV_INSN (insn); + for (i = 0; i < 3; i++) + { + do + insn = next_active_insn (insn); + while (GET_CODE (insn) == INSN + && get_attr_empty (insn) == EMPTY_YES); + if (GET_CODE (insn) == CALL_INSN) + note = find_reg_note (insn, REG_EH_REGION, NULL_RTX); + else if (note) + { + int code; + + gcc_assert ((code = recog_memoized (insn)) == CODE_FOR_nop + || code == CODE_FOR_nop_b); + if (find_reg_note (insn, REG_EH_REGION, NULL_RTX)) + note = NULL_RTX; + else + REG_NOTES (insn) + = gen_rtx_EXPR_LIST (REG_EH_REGION, XEXP (note, 0), + REG_NOTES (insn)); + } + } + } +#endif +} + /* The following function does insn bundling. Bundling means inserting templates and nop insns to fit insn groups into permitted templates. Instruction scheduling uses NDFA (non-deterministic @@ -7927,8 +7974,7 @@ bundling (FILE *dump, int verbose, rtx prev_head_insn, rtx tail) /* We are at the start of a bundle: emit the template (it should be defined). */ gcc_assert (template0 >= 0); - b = gen_bundle_selector (GEN_INT (template0)); - ia64_emit_insn_before (b, nop); + ia64_add_bundle_selector_before (template0, nop); /* If we have two bundle window, we make one bundle rotation. Otherwise template0 will be undefined (negative value). */ @@ -7954,8 +8000,7 @@ bundling (FILE *dump, int verbose, rtx prev_head_insn, rtx tail) /* The current insn is at the bundle start: emit the template. */ gcc_assert (template0 >= 0); - b = gen_bundle_selector (GEN_INT (template0)); - ia64_emit_insn_before (b, insn); + ia64_add_bundle_selector_before (template0, insn); b = PREV_INSN (insn); insn = b; /* See comment above in analogous place for emitting nops @@ -7977,8 +8022,7 @@ bundling (FILE *dump, int verbose, rtx prev_head_insn, rtx tail) /* See comment above in analogous place for emitting nops after the insn. */ gcc_assert (template0 >= 0); - b = gen_bundle_selector (GEN_INT (template0)); - ia64_emit_insn_before (b, insn); + ia64_add_bundle_selector_before (template0, insn); b = PREV_INSN (insn); insn = b; template0 = template1; @@ -8072,8 +8116,7 @@ bundling (FILE *dump, int verbose, rtx prev_head_insn, rtx tail) } /* Put the MM-insn in the same slot of a bundle with the same template as the original one. */ - ia64_emit_insn_before (gen_bundle_selector (GEN_INT (template0)), - insn); + ia64_add_bundle_selector_before (template0, insn); /* To put the insn in the same slot, add necessary number of nops. */ for (j = n; j > 0; j --) |