[patch] for PR 31676
Zdenek Dvorak
rakdver@atrey.karlin.mff.cuni.cz
Fri Apr 27 09:57:00 GMT 2007
Hello,
this patch fixes two problems with non-local goto handling that were
exposed by the fix for PR 31360.
1) At the beginning of non-local goto receiver, we restore the frame
pointer based on hard_frame_pointer_rtx; we need to consider
hard_frame_pointer_rtx to be defined at the beginning of the
receiver, to prevent this initialization to be moved by invariant
motion.
2) We forget to create edges in CFG from non-local gotos to the
non-local goto receivers inside the same function.
Bootstrapped & regtested on ppc-linux and i686.
Zdenek
PR rtl-optimization/31676
* df-scan.c (record_nonlocal_goto_receiver_defs): New function.
(df_refs_record): Call it.
* cfgbuild.c (make_edges): Make edges for non-local gotos.
Index: df-scan.c
===================================================================
*** df-scan.c (revision 124185)
--- df-scan.c (working copy)
*************** df_bb_refs_record (struct dataflow *dflo
*** 1765,1770 ****
--- 1765,1796 ----
}
}
+ /* Records the implicit definitions at targets of nonlocal gotos in BLOCKS. */
+
+ static void
+ record_nonlocal_goto_receiver_defs (struct dataflow *dflow, bitmap blocks)
+ {
+ rtx x;
+ basic_block bb;
+
+ /* See expand_builtin_setjmp_receiver; hard_frame_pointer_rtx is used in
+ the nonlocal goto receiver, and needs to be considered defined
+ implicitly. */
+ if (!(dflow->flags & DF_HARD_REGS))
+ return;
+
+ for (x = nonlocal_goto_handler_labels; x; x = XEXP (x, 1))
+ {
+ bb = BLOCK_FOR_INSN (XEXP (x, 0));
+ if (!bitmap_bit_p (blocks, bb->index))
+ continue;
+
+ df_ref_record (dflow, hard_frame_pointer_rtx, &hard_frame_pointer_rtx,
+ bb, NULL,
+ DF_REF_REG_DEF, DF_REF_ARTIFICIAL | DF_REF_AT_TOP,
+ false);
+ }
+ }
/* Record all the refs in the basic blocks specified by BLOCKS. */
*************** df_refs_record (struct dataflow *dflow,
*** 1785,1790 ****
--- 1811,1818 ----
if (bitmap_bit_p (blocks, ENTRY_BLOCK))
df_record_entry_block_defs (dflow);
+
+ record_nonlocal_goto_receiver_defs (dflow, blocks);
}
Index: cfgbuild.c
===================================================================
*** cfgbuild.c (revision 124185)
--- cfgbuild.c (working copy)
*************** make_edges (basic_block min, basic_block
*** 307,315 ****
rtl_make_eh_edge (edge_cache, bb, insn);
/* Recognize a non-local goto as a branch outside the
! current function. */
else if (find_reg_note (insn, REG_NON_LOCAL_GOTO, NULL_RTX))
! ;
/* Recognize a tablejump and do the right thing. */
else if (tablejump_p (insn, NULL, &tmp))
--- 307,320 ----
rtl_make_eh_edge (edge_cache, bb, insn);
/* Recognize a non-local goto as a branch outside the
! current function. It might also jump to one of the
! non-local goto targets in the current function. */
else if (find_reg_note (insn, REG_NON_LOCAL_GOTO, NULL_RTX))
! {
! for (x = nonlocal_goto_handler_labels; x; x = XEXP (x, 1))
! make_label_edge (edge_cache, bb, XEXP (x, 0),
! EDGE_ABNORMAL);
! }
/* Recognize a tablejump and do the right thing. */
else if (tablejump_p (insn, NULL, &tmp))
More information about the Gcc-patches
mailing list