aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2013-04-26 12:56:36 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2013-04-26 12:56:36 +0000
commitd7ed20db763473e20d1186e5e138ae00e5afc764 (patch)
tree59f2be7bd6aa35b6e02ed5b1144cf5da176a6d03
parent6e03fa931c3264b82681e0f7894e161e148dbfc5 (diff)
downloadgcc-d7ed20db763473e20d1186e5e138ae00e5afc764.zip
gcc-d7ed20db763473e20d1186e5e138ae00e5afc764.tar.gz
gcc-d7ed20db763473e20d1186e5e138ae00e5afc764.tar.bz2
omp-low.c (finalize_task_copyfn): Do not drop PROP_loops.
2013-04-26 Richard Biener <rguenther@suse.de> * omp-low.c (finalize_task_copyfn): Do not drop PROP_loops. (expand_omp_taskreg): Likewise. Mark loops for fixup. * tree-cfg.c (move_block_to_fn): Remap loop fathers. (fixup_loop_arrays_after_move): New function. (move_sese_region_to_fn): Properly outline the loop tree parts of the SESE region. From-SVN: r198338
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/omp-low.c14
-rw-r--r--gcc/tree-cfg.c82
3 files changed, 86 insertions, 19 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a6b7ba7..dd49037 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2013-04-26 Richard Biener <rguenther@suse.de>
+
+ * omp-low.c (finalize_task_copyfn): Do not drop PROP_loops.
+ (expand_omp_taskreg): Likewise. Mark loops for fixup.
+ * tree-cfg.c (move_block_to_fn): Remap loop fathers.
+ (fixup_loop_arrays_after_move): New function.
+ (move_sese_region_to_fn): Properly outline the loop tree parts
+ of the SESE region.
+
2013-04-26 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.md (type, unit): Fix long lines.
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index eaeeaa5..81ae5b4 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -1258,10 +1258,7 @@ finalize_task_copyfn (gimple task_stmt)
return;
child_cfun = DECL_STRUCT_FUNCTION (child_fn);
-
- /* Inform the callgraph about the new function. */
- DECL_STRUCT_FUNCTION (child_fn)->curr_properties
- = cfun->curr_properties & ~PROP_loops;
+ DECL_STRUCT_FUNCTION (child_fn)->curr_properties = cfun->curr_properties;
push_cfun (child_cfun);
bind = gimplify_body (child_fn, false);
@@ -1276,6 +1273,7 @@ finalize_task_copyfn (gimple task_stmt)
gimple_set_body (child_fn, seq);
pop_cfun ();
+ /* Inform the callgraph about the new function. */
cgraph_add_new_function (child_fn, false);
}
@@ -3573,6 +3571,11 @@ expand_omp_taskreg (struct omp_region *region)
new_bb = move_sese_region_to_fn (child_cfun, entry_bb, exit_bb, block);
if (exit_bb)
single_succ_edge (new_bb)->flags = EDGE_FALLTHRU;
+ /* ??? As the OMP expansion process does not update the loop
+ tree of the original function before outlining the region to
+ the new child function we need to discover loops in the child.
+ Arrange for that. */
+ child_cfun->x_current_loops->state |= LOOPS_NEED_FIXUP;
/* Remove non-local VAR_DECLs from child_cfun->local_decls list. */
num = vec_safe_length (child_cfun->local_decls);
@@ -3589,8 +3592,7 @@ expand_omp_taskreg (struct omp_region *region)
vec_safe_truncate (child_cfun->local_decls, dstidx);
/* Inform the callgraph about the new function. */
- DECL_STRUCT_FUNCTION (child_fn)->curr_properties
- = cfun->curr_properties & ~PROP_loops;
+ DECL_STRUCT_FUNCTION (child_fn)->curr_properties = cfun->curr_properties;
cgraph_add_new_function (child_fn, true);
/* Fix the callgraph edges for child_cfun. Those for cfun will be
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index cbbc5c7..a8e9f5c 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -6346,8 +6346,14 @@ move_block_to_fn (struct function *dest_cfun, basic_block bb,
/* Remove BB from dominance structures. */
delete_from_dominance_info (CDI_DOMINATORS, bb);
+
+ /* Move BB from its current loop to the copy in the new function. */
if (current_loops)
- remove_bb_from_loops (bb);
+ {
+ struct loop *new_loop = (struct loop *)bb->loop_father->aux;
+ if (new_loop)
+ bb->loop_father = new_loop;
+ }
/* Link BB to the new linked list. */
move_block_after (bb, after);
@@ -6579,6 +6585,25 @@ replace_block_vars_by_duplicates (tree block, struct pointer_map_t *vars_map,
replace_block_vars_by_duplicates (block, vars_map, to_context);
}
+/* Fixup the loop arrays and numbers after moving LOOP and its subloops
+ from FN1 to FN2. */
+
+static void
+fixup_loop_arrays_after_move (struct function *fn1, struct function *fn2,
+ struct loop *loop)
+{
+ /* Discard it from the old loop array. */
+ (*fn1->x_current_loops->larray)[loop->num] = NULL;
+
+ /* Place it in the new loop array, assigning it a new number. */
+ loop->num = vec_safe_length (fn2->x_current_loops->larray);
+ vec_safe_push (fn2->x_current_loops->larray, loop);
+
+ /* Recurse to children. */
+ for (loop = loop->inner; loop; loop = loop->next)
+ fixup_loop_arrays_after_move (fn1, fn2, loop);
+}
+
/* Move a single-entry, single-exit region delimited by ENTRY_BB and
EXIT_BB to function DEST_CFUN. The whole region is replaced by a
single basic block in the original CFG and the new basic block is
@@ -6698,6 +6723,42 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
}
}
+ /* Initialize an empty loop tree. */
+ dest_cfun->x_current_loops = ggc_alloc_cleared_loops ();
+ init_loops_structure (dest_cfun, dest_cfun->x_current_loops, 1);
+ dest_cfun->x_current_loops->state = LOOPS_MAY_HAVE_MULTIPLE_LATCHES;
+
+ /* Move the outlined loop tree part. */
+ FOR_EACH_VEC_ELT (bbs, i, bb)
+ {
+ if (bb->loop_father->header == bb
+ && loop_outer (bb->loop_father) == loop)
+ {
+ struct loop *loop = bb->loop_father;
+ flow_loop_tree_node_remove (bb->loop_father);
+ flow_loop_tree_node_add (dest_cfun->x_current_loops->tree_root, loop);
+ fixup_loop_arrays_after_move (saved_cfun, cfun, loop);
+ }
+
+ /* Remove loop exits from the outlined region. */
+ if (saved_cfun->x_current_loops->exits)
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ {
+ void **slot = htab_find_slot_with_hash
+ (saved_cfun->x_current_loops->exits, e,
+ htab_hash_pointer (e), NO_INSERT);
+ if (slot)
+ htab_clear_slot (saved_cfun->x_current_loops->exits, slot);
+ }
+ }
+
+
+ /* Adjust the number of blocks in the tree root of the outlined part. */
+ dest_cfun->x_current_loops->tree_root->num_nodes = bbs.length () + 2;
+
+ /* Setup a mapping to be used by move_block_to_fn. */
+ loop->aux = current_loops->tree_root;
+
pop_cfun ();
/* Move blocks from BBS into DEST_CFUN. */
@@ -6715,18 +6776,6 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
d.eh_map = eh_map;
d.remap_decls_p = true;
- /* Cancel all loops inside the SESE region.
- ??? We rely on loop fixup because loop structure is not 100%
- up-to-date when called from OMP lowering and thus cancel_loop_tree
- will not work.
- ??? Properly move loops to the outlined function. */
- FOR_EACH_VEC_ELT (bbs, i, bb)
- if (bb->loop_father->header == bb)
- {
- bb->loop_father->header = NULL;
- bb->loop_father->latch = NULL;
- loops_state_set (LOOPS_NEED_FIXUP);
- }
FOR_EACH_VEC_ELT (bbs, i, bb)
{
/* No need to update edge counts on the last block. It has
@@ -6736,6 +6785,13 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
after = bb;
}
+ loop->aux = NULL;
+ /* Loop sizes are no longer correct, fix them up. */
+ loop->num_nodes -= bbs.length ();
+ for (struct loop *outer = loop_outer (loop);
+ outer; outer = loop_outer (outer))
+ outer->num_nodes -= bbs.length ();
+
/* Rewire BLOCK_SUBBLOCKS of orig_block. */
if (orig_block)
{