OSDN Git Service

* config/ia64/ia64.c (group_barrier_needed_p): Don't allow
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 12 May 2001 05:21:09 +0000 (05:21 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 12 May 2001 05:21:09 +0000 (05:21 +0000)
        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
gcc/config/ia64/ia64.c
gcc/config/ia64/ia64.md

index c04386c..63309d3 100644 (file)
@@ -1,3 +1,11 @@
+2001-05-11  Richard Henderson  <rth@redhat.com>
+
+       * 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  <neil@daikokuya.demon.co.uk>
 
        * c-lex.c (lex_charconst): Convert into a simple wrapper
index 31907fa..0a1284a 100644 (file)
@@ -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 ();
 }
index 6a6f91f..36823d6 100644 (file)
@@ -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
   [(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")])
 \f
 ;; Non-local goto support.