This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
ia64 bundling bugs
- To: gcc-patches at gcc dot gnu dot org
- Subject: ia64 bundling bugs
- From: Richard Henderson <rth at redhat dot com>
- Date: Fri, 11 May 2001 22:29:42 -0700
Somewhere in the recent past we lost the code to prevent calls and jumps
from being bundled together. This is a quick hack to prevent that. A
better solution would be to select the bundle type appropriately (eg .mib)
such that the two insns can't bundle together. This would avoid the extra
stop bit, which would be good in the presence of predicated false calls.
Also, the IA-64 unwind ABI, unlike dwarf2, does not allow a call to end
a function. That is, the return value should not point to something in
the next function. So in these cases we emit an extra bundle.
r~
* 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.
Index: config/ia64/ia64.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/ia64.c,v
retrieving revision 1.91
diff -c -p -d -r1.91 ia64.c
*** ia64.c 2001/05/04 15:06:35 1.91
--- ia64.c 2001/05/12 05:09:38
*************** group_barrier_needed_p (insn)
*** 4509,4519 ****
--- 4509,4536 ----
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:
*************** ia64_reorg (insns)
*** 6410,6415 ****
--- 6427,6459 ----
}
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 ();
Index: config/ia64/ia64.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/ia64.md,v
retrieving revision 1.62
diff -c -p -d -r1.62 ia64.md
*** ia64.md 2001/04/12 20:46:19 1.62
--- ia64.md 2001/05/12 05:09:38
***************
*** 71,76 ****
--- 71,77 ----
;; 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,4945 ****
--- 4941,4951 ----
[(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.