This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR63196, ensure loops are fixed before inlining
- From: Richard Biener <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 8 Sep 2014 10:18:25 +0200 (CEST)
- Subject: [PATCH] Fix PR63196, ensure loops are fixed before inlining
- Authentication-results: sourceware.org; auth=none
The following patch makes sure we don't inline / copy a CFG with
loops needing fixups. In the particular case function versioning
after IPA-CP made a CFG portion dead, removing a loop.
The patch also makes the bogus loop removal detection unconditional
as gengtype doesn't seem to be able to handle preprocessor conditional
fields.
Bootstrap and regtest pending on x86_64-unknown-linux-gnu.
2014-09-08 Richard Biener <rguenther@suse.de>
PR ipa/63196
* cfgloop.c (mark_loop_for_removal): Track former header
unconditionally.
* cfgloop.h (struct loop): Add former_header member unconditionally.
* loop-init.c (fix_loop_structure): Enable bogus loop removal
diagnostic unconditionally.
* tree-inline.c (copy_loops): The source loop header should
always be non-NULL.
(tree_function_versioning): If loops need fixup after removing
unreachable blocks fix them.
Index: gcc/cfgloop.c
===================================================================
--- gcc/cfgloop.c (revision 215008)
+++ gcc/cfgloop.c (working copy)
@@ -1927,9 +1937,7 @@ bb_loop_depth (const_basic_block bb)
void
mark_loop_for_removal (loop_p loop)
{
-#ifdef ENABLE_CHECKING
loop->former_header = loop->header;
-#endif
loop->header = NULL;
loop->latch = NULL;
loops_state_set (LOOPS_NEED_FIXUP);
Index: gcc/cfgloop.h
===================================================================
--- gcc/cfgloop.h (revision 215008)
+++ gcc/cfgloop.h (working copy)
@@ -194,13 +194,11 @@ struct GTY ((chain_next ("%h.next"))) lo
/* Number of iteration analysis data for RTL. */
struct niter_desc *simple_loop_desc;
-#ifdef ENABLE_CHECKING
/* For sanity checking during loop fixup we record here the former
loop header for loops marked for removal. Note that this prevents
the basic-block from being collected but its index can still be
reused. */
basic_block former_header;
-#endif
};
/* Flags for state of loop structure. */
Index: gcc/loop-init.c
===================================================================
--- gcc/loop-init.c (revision 215008)
+++ gcc/loop-init.c (working copy)
@@ -245,12 +245,10 @@ fix_loop_structure (bitmap changed_bbs)
}
/* Remove the loop. */
-#ifdef ENABLE_CHECKING
if (loop->header)
loop->former_header = loop->header;
else
gcc_assert (loop->former_header != NULL);
-#endif
loop->header = NULL;
flow_loop_tree_node_remove (loop);
}
@@ -278,7 +276,6 @@ fix_loop_structure (bitmap changed_bbs)
FOR_EACH_VEC_ELT (*get_loops (cfun), i, loop)
if (loop && loop->header == NULL)
{
-#ifdef ENABLE_CHECKING
if (dump_file
&& ((unsigned) loop->former_header->index
< basic_block_info_for_fn (cfun)->length ()))
@@ -306,7 +303,6 @@ fix_loop_structure (bitmap changed_bbs)
former_header->loop_father->header->index);
}
}
-#endif
(*get_loops (cfun))[i] = NULL;
flow_loop_free (loop);
}
Index: gcc/tree-inline.c
===================================================================
--- gcc/tree-inline.c (revision 215008)
+++ gcc/tree-inline.c (working copy)
@@ -2376,11 +2376,8 @@ copy_loops (copy_body_data *id,
/* Assign the new loop its header and latch and associate
those with the new loop. */
- if (src_loop->header != NULL)
- {
- dest_loop->header = (basic_block)src_loop->header->aux;
- dest_loop->header->loop_father = dest_loop;
- }
+ dest_loop->header = (basic_block)src_loop->header->aux;
+ dest_loop->header->loop_father = dest_loop;
if (src_loop->latch != NULL)
{
dest_loop->latch = (basic_block)src_loop->latch->aux;
@@ -5536,6 +5533,11 @@ tree_function_versioning (tree old_decl,
delete_unreachable_blocks_update_callgraph (&id);
if (id.dst_node->definition)
cgraph_edge::rebuild_references ();
+ if (loops_state_satisfies_p (LOOPS_NEED_FIXUP))
+ {
+ calculate_dominance_info (CDI_DOMINATORS);
+ fix_loop_structure (NULL);
+ }
update_ssa (TODO_update_ssa);
/* After partial cloning we need to rescale frequencies, so they are