This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Blackfin eh broken with dataflow merge


Exception handling on the Blackfin was broken by the dataflow merge.
Inspecting the differences in the generated code, it appears that when
compiling functions like _Unwind_Resume in unwind-dw2.c, the dse pass
deletes necessary instructions.

Before:
(insn 56 55 57 7 (set (reg/v:SI 56 [ offset ])
        (reg:SI 0 R0)) 14 {*movsi_insn} (expr_list:REG_DEAD (reg:SI 0 R0)
        (nil)))

(insn 57 56 67 7 (set (reg/v/f:SI 55 [ handler ])
        (mem/s/f/c:SI (plus:SI (reg/f:SI 15 FP)
                (const_int -376 [0xfffffe88])) [12 cur_context.ra+0 S4
A32])) 14 {*movsi_insn} (nil))

(insn 67 57 68 7 (set (reg:SI 10 P2 [ offset ])
        (reg/v:SI 56 [ offset ])) 14 {*movsi_insn} (expr_list:REG_DEAD
(reg/v:SI 56 [ offset ])
        (nil)))

(insn 68 67 69 7 (set (mem:SI (plus:SI (reg/f:SI 15 FP)
                (const_int 4 [0x4])) [0 S4 A32])
        (reg/v/f:SI 55 [ handler ])) 14 {*movsi_insn}
(expr_list:REG_DEAD (reg/v/f:SI 55 [ handler ])
        (nil)))

(jump_insn 69 68 0 7 (set (pc)
        (unspec_volatile [
                (reg:SI 10 P2)
            ] 0)) 126 {eh_return_internal} (expr_list:REG_DEAD (reg:SI
10 P2)
        (expr_list:REG_EQUAL (unspec_volatile [
                    (reg:SI 10 P2)
                ] 0)
            (nil))))

After:
(insn 56 55 67 7 (set (reg/v:SI 56 [ offset ])
        (reg:SI 0 R0)) 14 {*movsi_insn} (expr_list:REG_DEAD (reg:SI 0 R0)
        (nil)))

(insn 67 56 69 7 (set (reg:SI 10 P2 [ offset ])
        (reg/v:SI 56 [ offset ])) 14 {*movsi_insn} (expr_list:REG_DEAD
(reg/v:SI 56 [ offset ])
        (nil)))

(jump_insn 69 67 0 7 (set (pc)
        (unspec_volatile [
                (reg:SI 10 P2)
            ] 0)) 126 {eh_return_internal} (expr_list:REG_DEAD (reg:SI
10 P2)
        (expr_list:REG_EQUAL (unspec_volatile [
                    (reg:SI 10 P2)
                ] 0)
            (nil))))

[FP + 4] is part of the register save area.  Insn 68, which stores a
value into it, gets deleted.

There is a reference to current_function_uses_eh_return in dse.c, but
it's not clear to me what it's trying to achieve.  Anyway, turning the
store into an unspec_volatile solves the problem.  I've committed the
following.


Bernd
-- 
This footer brought to you by insane German lawmakers.
Analog Devices GmbH      Wilhelm-Wagenfeld-Str. 6      80807 Muenchen
Sitz der Gesellschaft Muenchen, Registergericht Muenchen HRB 40368
Geschaeftsfuehrer Thomas Wessel, William A. Martin, Margaret Seif
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 125680)
+++ ChangeLog	(working copy)
@@ -1,3 +1,10 @@
+2007-06-13  Bernd Schmidt  <bernd.schmidt@analog.com>
+
+	* config/bfin/bfin.h (EH_RETURN_HANDLER_RTX): Use gen_frame_mem.
+	* config/bfin/bfin.md (UNSPEC_VOLATILE_STORE_EH_HANDLER): New constant.
+	(eh_store_handler): New pattern.
+	(eh_return): Emit it instead of a plain move.
+
 2007-06-13  Uros Bizjak  <ubizjak@gmail.com>
 
 	* config/i386/i386.c (ix86_init_mmx_sse_builtins)
Index: config/bfin/bfin.h
===================================================================
--- config/bfin/bfin.h	(revision 125641)
+++ config/bfin/bfin.h	(working copy)
@@ -813,7 +813,7 @@ typedef struct {
 #define EH_RETURN_DATA_REGNO(N)	((N) < 2 ? (N) : INVALID_REGNUM)
 #define EH_RETURN_STACKADJ_RTX	gen_rtx_REG (Pmode, REG_P2)
 #define EH_RETURN_HANDLER_RTX \
-    gen_rtx_MEM (Pmode, plus_constant (frame_pointer_rtx, UNITS_PER_WORD))
+    gen_frame_mem (Pmode, plus_constant (frame_pointer_rtx, UNITS_PER_WORD))
 
 /* Addressing Modes */
 
Index: config/bfin/bfin.md
===================================================================
--- config/bfin/bfin.md	(revision 125648)
+++ config/bfin/bfin.md	(working copy)
@@ -144,7 +144,8 @@ (define_constants
   [(UNSPEC_VOLATILE_EH_RETURN 0)
    (UNSPEC_VOLATILE_CSYNC 1)
    (UNSPEC_VOLATILE_SSYNC 2)
-   (UNSPEC_VOLATILE_LOAD_FUNCDESC 3)])
+   (UNSPEC_VOLATILE_LOAD_FUNCDESC 3)
+   (UNSPEC_VOLATILE_STORE_EH_HANDLER 4)])
 
 (define_constants
   [(MACFLAG_NONE 0)
@@ -2687,12 +2688,20 @@ (define_expand "eh_return"
 		    UNSPEC_VOLATILE_EH_RETURN)]
   ""
 {
-  emit_move_insn (EH_RETURN_HANDLER_RTX, operands[0]);
+  emit_insn (gen_eh_store_handler (EH_RETURN_HANDLER_RTX, operands[0]));
   emit_jump_insn (gen_eh_return_internal ());
   emit_barrier ();
   DONE;
 })
 
+(define_insn "eh_store_handler"
+  [(unspec_volatile [(match_operand:SI 1 "register_operand" "da")]
+		    UNSPEC_VOLATILE_STORE_EH_HANDLER)
+   (clobber (match_operand:SI 0 "memory_operand" "=m"))]
+  ""
+  "%0 = %1%!"
+  [(set_attr "type" "mcst")])
+
 (define_insn_and_split "eh_return_internal"
   [(set (pc)
 	(unspec_volatile [(reg:SI REG_P2)] UNSPEC_VOLATILE_EH_RETURN))]

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]