From b69208e6b2b66f0bbb71ad6a8168566c688bb2db Mon Sep 17 00:00:00 2001 From: rth Date: Sat, 12 May 2001 05:21:09 +0000 Subject: [PATCH] * config/ia64/ia64.c (group_barrier_needed_p): Don't allow calls and jumps to be bundled together. (ia64_reorg): Emit a break after a noreturn call that ends a function. * config/ia64/ia64.md (break_f): New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@41979 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 8 ++++++++ gcc/config/ia64/ia64.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ gcc/config/ia64/ia64.md | 6 ++++++ 3 files changed, 58 insertions(+) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c04386c..63309d3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2001-05-11 Richard Henderson + + * config/ia64/ia64.c (group_barrier_needed_p): Don't allow + calls and jumps to be bundled together. + (ia64_reorg): Emit a break after a noreturn call that ends + a function. + * config/ia64/ia64.md (break_f): New. + 2001-05-12 Neil Booth * c-lex.c (lex_charconst): Convert into a simple wrapper diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index 31907fa..0a1284a 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -4509,11 +4509,28 @@ group_barrier_needed_p (insn) flags.is_branch = 1; flags.is_sibcall = SIBLING_CALL_P (insn); memset (rws_insn, 0, sizeof (rws_insn)); + + /* Don't bundle a call following another call. */ + if ((pat = prev_active_insn (insn)) + && GET_CODE (pat) == CALL_INSN) + { + need_barrier = 1; + break; + } + need_barrier = rtx_needs_barrier (PATTERN (insn), flags, 0); break; case JUMP_INSN: flags.is_branch = 1; + + /* Don't bundle a jump following a call. */ + if ((pat = prev_active_insn (insn)) + && GET_CODE (pat) == CALL_INSN) + { + need_barrier = 1; + break; + } /* FALLTHRU */ case INSN: @@ -6411,6 +6428,33 @@ ia64_reorg (insns) else emit_all_insn_group_barriers (rtl_dump_file, insns); + /* A call must not be the last instruction in a function, so that the + return address is still within the function, so that unwinding works + properly. Note that IA-64 differs from dwarf2 on this point. */ + if (flag_unwind_tables || (flag_exceptions && !USING_SJLJ_EXCEPTIONS)) + { + rtx insn; + int saw_stop = 0; + + insn = get_last_insn (); + if (! INSN_P (insn)) + insn = prev_active_insn (insn); + if (GET_CODE (insn) == INSN + && GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE + && XINT (PATTERN (insn), 1) == 2) + { + saw_stop = 1; + insn = prev_active_insn (insn); + } + if (GET_CODE (insn) == CALL_INSN) + { + if (! saw_stop) + emit_insn (gen_insn_group_barrier (GEN_INT (3))); + emit_insn (gen_break_f ()); + emit_insn (gen_insn_group_barrier (GEN_INT (3))); + } + } + fixup_errata (); emit_predicate_relation_info (); } diff --git a/gcc/config/ia64/ia64.md b/gcc/config/ia64/ia64.md index 6a6f91f..36823d6 100644 --- a/gcc/config/ia64/ia64.md +++ b/gcc/config/ia64/ia64.md @@ -71,6 +71,7 @@ ;; 0 alloc ;; 1 blockage ;; 2 insn_group_barrier +;; 3 break ;; 5 set_bsp ;; 8 pred.safe_across_calls all ;; 9 pred.safe_across_calls normal @@ -4940,6 +4941,11 @@ [(set_attr "itanium_class" "stop_bit") (set_attr "predicable" "no")]) +(define_insn "break_f" + [(unspec_volatile [(const_int 0)] 3)] + "" + "break.f 0" + [(set_attr "itanium_class" "nop_f")]) ;; Non-local goto support. -- 2.7.4