Commit ab0e5308 by Richard Biener Committed by Richard Biener

graphite-isl-ast-to-gimple.c (translate_pending_phi_nodes): Verify both BBs…

graphite-isl-ast-to-gimple.c (translate_pending_phi_nodes): Verify both BBs contain loop PHI nodes before dispatching to copy_loop_phi_args.

2017-09-21  Richard Biener  <rguenther@suse.de>

	* graphite-isl-ast-to-gimple.c (translate_pending_phi_nodes):
	Verify both BBs contain loop PHI nodes before dispatching to
	copy_loop_phi_args.
	(graphite_regenerate_ast_isl): Do not recompute dominators,
	do not verify three times.  Restructure for clarity.
	* graphite-scop-detection.c (same_close_phi_node,
	remove_duplicate_close_phi, make_close_phi_nodes_unique,
	defined_in_loop_p, canonicalize_loop_closed_ssa,
	canonicalize_loop_closed_ssa_form): Simplify, remove excess
	checking and SSA rewrite, move to ...
	* graphite.c: ... here.  Include ssa.h and tree-ssa-loop-manip.h.
	(graphite_initialize): Do not pass in ctx, do not reset the
	SCEV cache, compute only dominators.
	(graphite_transform_loops): Allocate ISL ctx after
	graphite_initialize.  Call canonicalize_loop_closed_ssa_form.
	Maintain post-dominators only around build_scops.
	* sese.c (if_region_set_false_region): Make static.  Free
	and recompute dominators.
	(move_sese_in_condition): Assert we don't get called with
	post-dominators computed.
	* sese.h (if_region_set_false_region): Remove.

From-SVN: r253090
parent e7ba6a60
2017-09-22 Richard Biener <rguenther@suse.de>
* graphite-isl-ast-to-gimple.c (translate_pending_phi_nodes):
Verify both BBs contain loop PHI nodes before dispatching to
copy_loop_phi_args.
(graphite_regenerate_ast_isl): Do not recompute dominators,
do not verify three times. Restructure for clarity.
* graphite-scop-detection.c (same_close_phi_node,
remove_duplicate_close_phi, make_close_phi_nodes_unique,
defined_in_loop_p, canonicalize_loop_closed_ssa,
canonicalize_loop_closed_ssa_form): Simplify, remove excess
checking and SSA rewrite, move to ...
* graphite.c: ... here. Include ssa.h and tree-ssa-loop-manip.h.
(graphite_initialize): Do not pass in ctx, do not reset the
SCEV cache, compute only dominators.
(graphite_transform_loops): Allocate ISL ctx after
graphite_initialize. Call canonicalize_loop_closed_ssa_form.
Maintain post-dominators only around build_scops.
* sese.c (if_region_set_false_region): Make static. Free
and recompute dominators.
(move_sese_in_condition): Assert we don't get called with
post-dominators computed.
* sese.h (if_region_set_false_region): Remove.
2017-09-22 Sergey Shalnov <sergey.shalnov@intel.com> 2017-09-22 Sergey Shalnov <sergey.shalnov@intel.com>
* config/i386/sse.md ("mov<mode>_internal"): Use <sseinsnmode> * config/i386/sse.md ("mov<mode>_internal"): Use <sseinsnmode>
...@@ -2759,7 +2759,8 @@ translate_pending_phi_nodes () ...@@ -2759,7 +2759,8 @@ translate_pending_phi_nodes ()
} }
auto_vec <tree, 1> iv_map; auto_vec <tree, 1> iv_map;
if (bb_contains_loop_phi_nodes (new_bb)) if (bb_contains_loop_phi_nodes (new_bb)
&& bb_contains_loop_phi_nodes (old_bb))
codegen_error = !copy_loop_phi_args (old_phi, ibp_old_bb, new_phi, codegen_error = !copy_loop_phi_args (old_phi, ibp_old_bb, new_phi,
ibp_new_bb, false); ibp_new_bb, false);
else if (bb_contains_loop_close_phi_nodes (new_bb)) else if (bb_contains_loop_close_phi_nodes (new_bb))
...@@ -2941,12 +2942,8 @@ graphite_regenerate_ast_isl (scop_p scop) ...@@ -2941,12 +2942,8 @@ graphite_regenerate_ast_isl (scop_p scop)
print_isl_ast (dump_file, root_node); print_isl_ast (dump_file, root_node);
} }
recompute_all_dominators ();
graphite_verify ();
if_region = move_sese_in_condition (region); if_region = move_sese_in_condition (region);
region->if_region = if_region; region->if_region = if_region;
recompute_all_dominators ();
loop_p context_loop = region->region.entry->src->loop_father; loop_p context_loop = region->region.entry->src->loop_father;
...@@ -2960,45 +2957,28 @@ graphite_regenerate_ast_isl (scop_p scop) ...@@ -2960,45 +2957,28 @@ graphite_regenerate_ast_isl (scop_p scop)
region->if_region->true_region->region.exit = single_succ_edge (bb); region->if_region->true_region->region.exit = single_succ_edge (bb);
t.translate_isl_ast (context_loop, root_node, e, ip); t.translate_isl_ast (context_loop, root_node, e, ip);
if (! t.codegen_error_p ())
t.translate_pending_phi_nodes ();
if (! t.codegen_error_p ())
{
sese_insert_phis_for_liveouts (region,
if_region->region->region.exit->src,
if_region->false_region->region.exit,
if_region->true_region->region.exit);
if (dump_file)
fprintf (dump_file, "[codegen] isl AST to Gimple succeeded.\n");
mark_virtual_operands_for_renaming (cfun);
update_ssa (TODO_update_ssa);
}
if (t.codegen_error_p ()) if (t.codegen_error_p ())
{ {
if (dump_file) if (dump_file)
fprintf (dump_file, "codegen error: " fprintf (dump_file, "codegen error: "
"reverting back to the original code.\n"); "reverting back to the original code.\n");
set_ifsese_condition (if_region, integer_zero_node); set_ifsese_condition (if_region, integer_zero_node);
}
else
{
t.translate_pending_phi_nodes ();
if (!t.codegen_error_p ())
{
sese_insert_phis_for_liveouts (region,
if_region->region->region.exit->src,
if_region->false_region->region.exit,
if_region->true_region->region.exit);
mark_virtual_operands_for_renaming (cfun);
update_ssa (TODO_update_ssa);
graphite_verify ();
scev_reset ();
recompute_all_dominators ();
graphite_verify ();
if (dump_file)
fprintf (dump_file, "[codegen] isl AST to Gimple succeeded.\n");
}
else
{
if (dump_file)
fprintf (dump_file, "[codegen] unsuccessful in translating"
" pending phis, reverting back to the original code.\n");
set_ifsese_condition (if_region, integer_zero_node);
}
}
if (t.codegen_error_p ())
{
/* We registered new names, scrap that. */ /* We registered new names, scrap that. */
if (need_ssa_update_p (cfun)) if (need_ssa_update_p (cfun))
delete_update_ssa (); delete_update_ssa ();
...@@ -3017,6 +2997,9 @@ graphite_regenerate_ast_isl (scop_p scop) ...@@ -3017,6 +2997,9 @@ graphite_regenerate_ast_isl (scop_p scop)
delete_loop (loop); delete_loop (loop);
} }
graphite_verify ();
scev_reset ();
free (if_region->true_region); free (if_region->true_region);
free (if_region->region); free (if_region->region);
free (if_region); free (if_region);
......
...@@ -268,187 +268,6 @@ trivially_empty_bb_p (basic_block bb) ...@@ -268,187 +268,6 @@ trivially_empty_bb_p (basic_block bb)
return true; return true;
} }
/* Returns true when P1 and P2 are close phis with the same
argument. */
static inline bool
same_close_phi_node (gphi *p1, gphi *p2)
{
return (types_compatible_p (TREE_TYPE (gimple_phi_result (p1)),
TREE_TYPE (gimple_phi_result (p2)))
&& operand_equal_p (gimple_phi_arg_def (p1, 0),
gimple_phi_arg_def (p2, 0), 0));
}
static void make_close_phi_nodes_unique (basic_block bb);
/* Remove the close phi node at GSI and replace its rhs with the rhs
of PHI. */
static void
remove_duplicate_close_phi (gphi *phi, gphi_iterator *gsi)
{
gimple *use_stmt;
use_operand_p use_p;
imm_use_iterator imm_iter;
tree res = gimple_phi_result (phi);
tree def = gimple_phi_result (gsi->phi ());
gcc_assert (same_close_phi_node (phi, gsi->phi ()));
FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
{
FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
SET_USE (use_p, res);
update_stmt (use_stmt);
/* It is possible that we just created a duplicate close-phi
for an already-processed containing loop. Check for this
case and clean it up. */
if (gimple_code (use_stmt) == GIMPLE_PHI
&& gimple_phi_num_args (use_stmt) == 1)
make_close_phi_nodes_unique (gimple_bb (use_stmt));
}
remove_phi_node (gsi, true);
}
/* Removes all the close phi duplicates from BB. */
static void
make_close_phi_nodes_unique (basic_block bb)
{
gphi_iterator psi;
for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi))
{
gphi_iterator gsi = psi;
gphi *phi = psi.phi ();
/* At this point, PHI should be a close phi in normal form. */
gcc_assert (gimple_phi_num_args (phi) == 1);
/* Iterate over the next phis and remove duplicates. */
gsi_next (&gsi);
while (!gsi_end_p (gsi))
if (same_close_phi_node (phi, gsi.phi ()))
remove_duplicate_close_phi (phi, &gsi);
else
gsi_next (&gsi);
}
}
/* Return true when NAME is defined in LOOP. */
static bool
defined_in_loop_p (tree name, loop_p loop)
{
gcc_assert (TREE_CODE (name) == SSA_NAME);
return loop == loop_containing_stmt (SSA_NAME_DEF_STMT (name));
}
/* Transforms LOOP to the canonical loop closed SSA form. */
static void
canonicalize_loop_closed_ssa (loop_p loop)
{
edge e = single_exit (loop);
basic_block bb;
if (!e || (e->flags & EDGE_COMPLEX))
return;
bb = e->dest;
if (single_pred_p (bb))
{
e = split_block_after_labels (bb);
DEBUG_PRINT (dp << "Splitting bb_" << bb->index << ".\n");
make_close_phi_nodes_unique (e->src);
}
else
{
gphi_iterator psi;
basic_block close = split_edge (e);
e = single_succ_edge (close);
DEBUG_PRINT (dp << "Splitting edge (" << e->src->index << ","
<< e->dest->index << ")\n");
for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi))
{
gphi *phi = psi.phi ();
unsigned i;
for (i = 0; i < gimple_phi_num_args (phi); i++)
if (gimple_phi_arg_edge (phi, i) == e)
{
tree res, arg = gimple_phi_arg_def (phi, i);
use_operand_p use_p;
gphi *close_phi;
/* Only add close phi nodes for SSA_NAMEs defined in LOOP. */
if (TREE_CODE (arg) != SSA_NAME
|| !defined_in_loop_p (arg, loop))
continue;
close_phi = create_phi_node (NULL_TREE, close);
res = create_new_def_for (arg, close_phi,
gimple_phi_result_ptr (close_phi));
add_phi_arg (close_phi, arg,
gimple_phi_arg_edge (close_phi, 0),
UNKNOWN_LOCATION);
use_p = gimple_phi_arg_imm_use_ptr (phi, i);
replace_exp (use_p, res);
update_stmt (phi);
}
}
make_close_phi_nodes_unique (close);
}
/* The code above does not properly handle changes in the post dominance
information (yet). */
recompute_all_dominators ();
}
/* Converts the current loop closed SSA form to a canonical form
expected by the Graphite code generation.
The loop closed SSA form has the following invariant: a variable
defined in a loop that is used outside the loop appears only in the
phi nodes in the destination of the loop exit. These phi nodes are
called close phi nodes.
The canonical loop closed SSA form contains the extra invariants:
- when the loop contains only one exit, the close phi nodes contain
only one argument. That implies that the basic block that contains
the close phi nodes has only one predecessor, that is a basic block
in the loop.
- the basic block containing the close phi nodes does not contain
other statements.
- there exist only one phi node per definition in the loop.
*/
static void
canonicalize_loop_closed_ssa_form (void)
{
checking_verify_loop_closed_ssa (true);
loop_p loop;
FOR_EACH_LOOP (loop, 0)
canonicalize_loop_closed_ssa (loop);
rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
update_ssa (TODO_update_ssa);
checking_verify_loop_closed_ssa (true);
}
/* Can all ivs be represented by a signed integer? /* Can all ivs be represented by a signed integer?
As isl might generate negative values in its expressions, signed loop ivs As isl might generate negative values in its expressions, signed loop ivs
are required in the backend. */ are required in the backend. */
...@@ -2038,8 +1857,6 @@ build_scops (vec<scop_p> *scops) ...@@ -2038,8 +1857,6 @@ build_scops (vec<scop_p> *scops)
if (dump_file) if (dump_file)
dp.set_dump_file (dump_file); dp.set_dump_file (dump_file);
canonicalize_loop_closed_ssa_form ();
/* ??? We walk the loop tree assuming loop->next is ordered. /* ??? We walk the loop tree assuming loop->next is ordered.
This is not so but we'd be free to order it here. */ This is not so but we'd be free to order it here. */
scop_detection sb; scop_detection sb;
......
...@@ -43,6 +43,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -43,6 +43,7 @@ along with GCC; see the file COPYING3. If not see
#include "cfghooks.h" #include "cfghooks.h"
#include "tree.h" #include "tree.h"
#include "gimple.h" #include "gimple.h"
#include "ssa.h"
#include "fold-const.h" #include "fold-const.h"
#include "gimple-iterator.h" #include "gimple-iterator.h"
#include "tree-cfg.h" #include "tree-cfg.h"
...@@ -53,6 +54,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -53,6 +54,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-parloops.h" #include "tree-parloops.h"
#include "tree-cfgcleanup.h" #include "tree-cfgcleanup.h"
#include "tree-vectorizer.h" #include "tree-vectorizer.h"
#include "tree-ssa-loop-manip.h"
#include "graphite.h" #include "graphite.h"
/* Print global statistics to FILE. */ /* Print global statistics to FILE. */
...@@ -213,7 +215,7 @@ print_graphite_statistics (FILE* file, vec<scop_p> scops) ...@@ -213,7 +215,7 @@ print_graphite_statistics (FILE* file, vec<scop_p> scops)
/* Initialize graphite: when there are no loops returns false. */ /* Initialize graphite: when there are no loops returns false. */
static bool static bool
graphite_initialize (isl_ctx *ctx) graphite_initialize (void)
{ {
int min_loops = PARAM_VALUE (PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION); int min_loops = PARAM_VALUE (PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION);
int max_bbs = PARAM_VALUE (PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION); int max_bbs = PARAM_VALUE (PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION);
...@@ -240,12 +242,10 @@ graphite_initialize (isl_ctx *ctx) ...@@ -240,12 +242,10 @@ graphite_initialize (isl_ctx *ctx)
print_global_statistics (dump_file); print_global_statistics (dump_file);
} }
isl_ctx_free (ctx);
return false; return false;
} }
scev_reset (); calculate_dominance_info (CDI_DOMINATORS);
recompute_all_dominators ();
initialize_original_copy_tables (); initialize_original_copy_tables ();
if (dump_file && dump_flags) if (dump_file && dump_flags)
...@@ -263,7 +263,6 @@ graphite_initialize (isl_ctx *ctx) ...@@ -263,7 +263,6 @@ graphite_initialize (isl_ctx *ctx)
static void static void
graphite_finalize (bool need_cfg_cleanup_p) graphite_finalize (bool need_cfg_cleanup_p)
{ {
free_dominance_info (CDI_POST_DOMINATORS);
if (need_cfg_cleanup_p) if (need_cfg_cleanup_p)
{ {
free_dominance_info (CDI_DOMINATORS); free_dominance_info (CDI_DOMINATORS);
...@@ -294,6 +293,162 @@ free_scops (vec<scop_p> scops) ...@@ -294,6 +293,162 @@ free_scops (vec<scop_p> scops)
scops.release (); scops.release ();
} }
/* Returns true when P1 and P2 are close phis with the same
argument. */
static inline bool
same_close_phi_node (gphi *p1, gphi *p2)
{
return (types_compatible_p (TREE_TYPE (gimple_phi_result (p1)),
TREE_TYPE (gimple_phi_result (p2)))
&& operand_equal_p (gimple_phi_arg_def (p1, 0),
gimple_phi_arg_def (p2, 0), 0));
}
static void make_close_phi_nodes_unique (basic_block bb);
/* Remove the close phi node at GSI and replace its rhs with the rhs
of PHI. */
static void
remove_duplicate_close_phi (gphi *phi, gphi_iterator *gsi)
{
gimple *use_stmt;
use_operand_p use_p;
imm_use_iterator imm_iter;
tree res = gimple_phi_result (phi);
tree def = gimple_phi_result (gsi->phi ());
gcc_assert (same_close_phi_node (phi, gsi->phi ()));
FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
{
FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
SET_USE (use_p, res);
update_stmt (use_stmt);
/* It is possible that we just created a duplicate close-phi
for an already-processed containing loop. Check for this
case and clean it up. */
if (gimple_code (use_stmt) == GIMPLE_PHI
&& gimple_phi_num_args (use_stmt) == 1)
make_close_phi_nodes_unique (gimple_bb (use_stmt));
}
remove_phi_node (gsi, true);
}
/* Removes all the close phi duplicates from BB. */
static void
make_close_phi_nodes_unique (basic_block bb)
{
gphi_iterator psi;
for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi))
{
gphi_iterator gsi = psi;
gphi *phi = psi.phi ();
/* At this point, PHI should be a close phi in normal form. */
gcc_assert (gimple_phi_num_args (phi) == 1);
/* Iterate over the next phis and remove duplicates. */
gsi_next (&gsi);
while (!gsi_end_p (gsi))
if (same_close_phi_node (phi, gsi.phi ()))
remove_duplicate_close_phi (phi, &gsi);
else
gsi_next (&gsi);
}
}
/* Return true when NAME is defined in LOOP. */
static bool
defined_in_loop_p (tree name, loop_p loop)
{
gcc_assert (TREE_CODE (name) == SSA_NAME);
return loop == loop_containing_stmt (SSA_NAME_DEF_STMT (name));
}
/* Transforms LOOP to the canonical loop closed SSA form. */
static void
canonicalize_loop_closed_ssa (loop_p loop)
{
edge e = single_exit (loop);
basic_block bb;
if (!e || (e->flags & EDGE_COMPLEX))
return;
bb = e->dest;
if (single_pred_p (bb))
{
e = split_block_after_labels (bb);
make_close_phi_nodes_unique (e->src);
}
else
{
gphi_iterator psi;
basic_block close = split_edge (e);
e = single_succ_edge (close);
for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi))
{
gphi *phi = psi.phi ();
use_operand_p use_p = PHI_ARG_DEF_PTR_FROM_EDGE (phi, e);
tree arg = USE_FROM_PTR (use_p);
/* Only add close phi nodes for SSA_NAMEs defined in LOOP. */
if (TREE_CODE (arg) != SSA_NAME
|| !defined_in_loop_p (arg, loop))
continue;
tree res = copy_ssa_name (arg);
gphi *close_phi = create_phi_node (res, close);
add_phi_arg (close_phi, arg, gimple_phi_arg_edge (close_phi, 0),
UNKNOWN_LOCATION);
SET_USE (use_p, res);
}
make_close_phi_nodes_unique (close);
}
}
/* Converts the current loop closed SSA form to a canonical form
expected by the Graphite code generation.
The loop closed SSA form has the following invariant: a variable
defined in a loop that is used outside the loop appears only in the
phi nodes in the destination of the loop exit. These phi nodes are
called close phi nodes.
The canonical loop closed SSA form contains the extra invariants:
- when the loop contains only one exit, the close phi nodes contain
only one argument. That implies that the basic block that contains
the close phi nodes has only one predecessor, that is a basic block
in the loop.
- the basic block containing the close phi nodes does not contain
other statements.
- there exist only one phi node per definition in the loop.
*/
static void
canonicalize_loop_closed_ssa_form (void)
{
loop_p loop;
FOR_EACH_LOOP (loop, 0)
canonicalize_loop_closed_ssa (loop);
checking_verify_loop_closed_ssa (true);
}
isl_ctx *the_isl_ctx; isl_ctx *the_isl_ctx;
/* Perform a set of linear transforms on the loops of the current /* Perform a set of linear transforms on the loops of the current
...@@ -313,13 +468,18 @@ graphite_transform_loops (void) ...@@ -313,13 +468,18 @@ graphite_transform_loops (void)
if (parallelized_function_p (cfun->decl)) if (parallelized_function_p (cfun->decl))
return; return;
ctx = isl_ctx_alloc (); if (!graphite_initialize ())
isl_options_set_on_error (ctx, ISL_ON_ERROR_ABORT);
if (!graphite_initialize (ctx))
return; return;
ctx = isl_ctx_alloc ();
isl_options_set_on_error (ctx, ISL_ON_ERROR_ABORT);
the_isl_ctx = ctx; the_isl_ctx = ctx;
canonicalize_loop_closed_ssa_form ();
calculate_dominance_info (CDI_POST_DOMINATORS);
build_scops (&scops); build_scops (&scops);
free_dominance_info (CDI_POST_DOMINATORS);
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
{ {
......
...@@ -335,9 +335,11 @@ get_false_edge_from_guard_bb (basic_block bb) ...@@ -335,9 +335,11 @@ get_false_edge_from_guard_bb (basic_block bb)
/* Sets the false region of an IF_REGION to REGION. */ /* Sets the false region of an IF_REGION to REGION. */
void static void
if_region_set_false_region (ifsese if_region, sese_info_p region) if_region_set_false_region (ifsese if_region, sese_info_p region)
{ {
free_dominance_info (CDI_DOMINATORS);
basic_block condition = if_region_get_condition_block (if_region); basic_block condition = if_region_get_condition_block (if_region);
edge false_edge = get_false_edge_from_guard_bb (condition); edge false_edge = get_false_edge_from_guard_bb (condition);
basic_block dummy = false_edge->dest; basic_block dummy = false_edge->dest;
...@@ -348,6 +350,8 @@ if_region_set_false_region (ifsese if_region, sese_info_p region) ...@@ -348,6 +350,8 @@ if_region_set_false_region (ifsese if_region, sese_info_p region)
hashval_t hash = htab_hash_pointer (exit_region); hashval_t hash = htab_hash_pointer (exit_region);
loop_exit **slot loop_exit **slot
= current_loops->exits->find_slot_with_hash (exit_region, hash, NO_INSERT); = current_loops->exits->find_slot_with_hash (exit_region, hash, NO_INSERT);
bool latch_p
= exit_region->dest->loop_father->latch == exit_region->src;
entry_region->flags = false_edge->flags; entry_region->flags = false_edge->flags;
false_edge->flags = exit_region->flags; false_edge->flags = exit_region->flags;
...@@ -359,7 +363,6 @@ if_region_set_false_region (ifsese if_region, sese_info_p region) ...@@ -359,7 +363,6 @@ if_region_set_false_region (ifsese if_region, sese_info_p region)
delete_basic_block (dummy); delete_basic_block (dummy);
exit_region->flags = EDGE_FALLTHRU; exit_region->flags = EDGE_FALLTHRU;
recompute_all_dominators ();
region->region.exit = false_edge; region->region.exit = false_edge;
...@@ -381,6 +384,10 @@ if_region_set_false_region (ifsese if_region, sese_info_p region) ...@@ -381,6 +384,10 @@ if_region_set_false_region (ifsese if_region, sese_info_p region)
*slot = loop_exit; *slot = loop_exit;
false_edge->src->loop_father->exits->next = loop_exit; false_edge->src->loop_father->exits->next = loop_exit;
} }
if (latch_p)
exit_region->dest->loop_father->latch = before_region;
calculate_dominance_info (CDI_DOMINATORS);
} }
/* Creates an IFSESE with CONDITION on edge ENTRY. */ /* Creates an IFSESE with CONDITION on edge ENTRY. */
...@@ -429,6 +436,7 @@ create_if_region_on_edge (edge entry, tree condition) ...@@ -429,6 +436,7 @@ create_if_region_on_edge (edge entry, tree condition)
ifsese ifsese
move_sese_in_condition (sese_info_p region) move_sese_in_condition (sese_info_p region)
{ {
gcc_assert (! dom_info_available_p (cfun, CDI_POST_DOMINATORS));
basic_block pred_block = split_edge (region->region.entry); basic_block pred_block = split_edge (region->region.entry);
ifsese if_region; ifsese if_region;
......
...@@ -233,7 +233,6 @@ typedef struct ifsese_s { ...@@ -233,7 +233,6 @@ typedef struct ifsese_s {
sese_info_p false_region; sese_info_p false_region;
} *ifsese; } *ifsese;
extern void if_region_set_false_region (ifsese, sese_info_p);
extern ifsese move_sese_in_condition (sese_info_p); extern ifsese move_sese_in_condition (sese_info_p);
extern void set_ifsese_condition (ifsese, tree); extern void set_ifsese_condition (ifsese, tree);
extern edge get_true_edge_from_guard_bb (basic_block); extern edge get_true_edge_from_guard_bb (basic_block);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment