#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "rtl.h"
#include "tm_p.h"
#include "hard-reg-set.h"
#include "basic-block.h"
#include "output.h"
#include "diagnostic.h"
#include "tree-flow.h"
#include "tree-dump.h"
#include "tree-pass.h"
#include "timevar.h"
#include "cfgloop.h"
#include "flags.h"
#include "tree-inline.h"
#include "tree-scalar-evolution.h"
#include "tree-data-ref.h"
#include "tree-vectorizer.h"
#include "function.h"
struct loops *current_loops;
struct loops *
tree_loop_optimizer_init (FILE *dump, bool canonicalize_ssa)
{
struct loops *loops = loop_optimizer_init (dump);
if (!loops)
return NULL;
if (!canonicalize_ssa)
return loops;
kill_redundant_phi_nodes ();
rewrite_into_ssa (false);
bitmap_clear (vars_to_rename);
rewrite_into_loop_closed_ssa ();
#ifdef ENABLE_CHECKING
verify_loop_closed_ssa ();
#endif
return loops;
}
static bool
gate_loop (void)
{
return flag_tree_loop_optimize != 0;
}
struct tree_opt_pass pass_loop =
{
"loop",
gate_loop,
NULL,
NULL,
NULL,
0,
TV_TREE_LOOP,
PROP_cfg,
0,
0,
TODO_ggc_collect,
TODO_dump_func | TODO_verify_ssa | TODO_ggc_collect,
0
};
static void
tree_ssa_loop_init (void)
{
current_loops = tree_loop_optimizer_init (dump_file, true);
if (!current_loops)
return;
mark_single_exit_loops (current_loops);
scev_initialize (current_loops);
}
struct tree_opt_pass pass_loop_init =
{
"loopinit",
NULL,
tree_ssa_loop_init,
NULL,
NULL,
0,
0,
PROP_cfg,
0,
0,
0,
TODO_dump_func,
0
};
static void
tree_ssa_loop_im (void)
{
if (!current_loops)
return;
tree_ssa_lim (current_loops);
}
static bool
gate_tree_ssa_loop_im (void)
{
return flag_tree_loop_im != 0;
}
struct tree_opt_pass pass_lim =
{
"lim",
gate_tree_ssa_loop_im,
tree_ssa_loop_im,
NULL,
NULL,
0,
TV_LIM,
PROP_cfg,
0,
0,
0,
TODO_dump_func,
0
};
static void
tree_ssa_loop_unswitch (void)
{
if (!current_loops)
return;
tree_ssa_unswitch_loops (current_loops);
}
static bool
gate_tree_ssa_loop_unswitch (void)
{
return flag_unswitch_loops != 0;
}
struct tree_opt_pass pass_unswitch =
{
"unswitch",
gate_tree_ssa_loop_unswitch,
tree_ssa_loop_unswitch,
NULL,
NULL,
0,
TV_TREE_LOOP_UNSWITCH,
PROP_cfg,
0,
0,
0,
TODO_dump_func,
0
};
static void
tree_ssa_loop_test (void)
{
if (!current_loops)
return;
scev_analysis ();
analyze_all_data_dependences (current_loops);
}
static bool
gate_tree_ssa_loop_test (void)
{
return flag_tree_ssa_loop_test != 0;
}
struct tree_opt_pass pass_loop_test =
{
"lptest",
gate_tree_ssa_loop_test,
tree_ssa_loop_test,
NULL,
NULL,
0,
0,
PROP_cfg,
0,
0,
0,
0,
0
};
static void
tree_mark_maybe_inf_loops (void)
{
if (!current_loops)
return;
cfun->marked_maybe_inf_loops = 1;
mark_maybe_infinite_loops (current_loops);
}
static bool
gate_tree_mark_maybe_inf_loops (void)
{
return (flag_tree_dce != 0 && optimize >= 2);
}
struct tree_opt_pass pass_mark_maybe_inf_loops =
{
"miloops",
gate_tree_mark_maybe_inf_loops,
tree_mark_maybe_inf_loops,
NULL,
NULL,
0,
TV_MARK_MILOOPS,
PROP_cfg | PROP_ssa,
0,
0,
0,
TODO_dump_func,
0
};
static void
tree_elim_checks (void)
{
if (!current_loops)
return;
}
static bool
gate_tree_elim_checks (void)
{
return flag_tree_elim_checks != 0;
}
struct tree_opt_pass pass_elim_checks =
{
"elck",
gate_tree_elim_checks,
tree_elim_checks,
NULL,
NULL,
0,
TV_TREE_ELIM_CHECKS,
PROP_cfg | PROP_ssa,
0,
0,
0,
TODO_dump_func,
0
};
static void
tree_vectorize (void)
{
if (!current_loops)
return;
bitmap_clear (vars_to_rename);
vectorize_loops (current_loops);
}
static bool
gate_tree_vectorize (void)
{
return flag_tree_vectorize != 0;
}
struct tree_opt_pass pass_vectorize =
{
"vect",
gate_tree_vectorize,
tree_vectorize,
NULL,
NULL,
0,
TV_TREE_VECTORIZATION,
PROP_cfg | PROP_ssa,
0,
0,
0,
TODO_dump_func,
0
};
static void
tree_linear_transform (void)
{
if (!current_loops)
return;
linear_transform_loops (current_loops);
}
static bool
gate_tree_linear_transform (void)
{
return flag_tree_loop_linear != 0;
}
struct tree_opt_pass pass_linear_transform =
{
"ltrans",
gate_tree_linear_transform,
tree_linear_transform,
NULL,
NULL,
0,
TV_TREE_LINEAR_TRANSFORM,
PROP_cfg | PROP_ssa,
0,
0,
0,
TODO_dump_func,
0
};
static void
tree_ssa_loop_prefetch (void)
{
if (!current_loops)
return;
tree_ssa_prefetch_arrays (current_loops);
}
static bool
gate_tree_ssa_loop_prefetch (void)
{
return flag_prefetch_loop_arrays != 0;
}
struct tree_opt_pass pass_loop_prefetch =
{
"prefetch",
gate_tree_ssa_loop_prefetch,
tree_ssa_loop_prefetch,
NULL,
NULL,
0,
TV_TREE_PREFETCH,
PROP_cfg | PROP_ssa,
0,
0,
0,
TODO_dump_func,
0
};
static void
tree_ssa_loop_ivcanon (void)
{
if (!current_loops)
return;
canonicalize_induction_variables (current_loops);
}
static bool
gate_tree_ssa_loop_ivcanon (void)
{
return flag_tree_loop_ivcanon != 0;
}
struct tree_opt_pass pass_iv_canon =
{
"ivcanon",
gate_tree_ssa_loop_ivcanon,
tree_ssa_loop_ivcanon,
NULL,
NULL,
0,
TV_TREE_LOOP_IVCANON,
PROP_cfg | PROP_ssa,
0,
0,
0,
TODO_dump_func,
0
};
static void
tree_ssa_loop_bounds (void)
{
if (!current_loops)
return;
estimate_numbers_of_iterations (current_loops);
scev_reset ();
}
struct tree_opt_pass pass_record_bounds =
{
NULL,
NULL,
tree_ssa_loop_bounds,
NULL,
NULL,
0,
0,
PROP_cfg | PROP_ssa,
0,
0,
0,
0,
0
};
static void
tree_complete_unroll (void)
{
if (!current_loops)
return;
tree_unroll_loops_completely (current_loops);
}
static bool
gate_tree_complete_unroll (void)
{
return flag_unroll_loops != 0;
}
struct tree_opt_pass pass_complete_unroll =
{
"cunroll",
gate_tree_complete_unroll,
tree_complete_unroll,
NULL,
NULL,
0,
TV_COMPLETE_UNROLL,
PROP_cfg | PROP_ssa,
0,
0,
0,
TODO_dump_func,
0
};
static void
tree_ssa_loop_ivopts (void)
{
if (!current_loops)
return;
tree_ssa_iv_optimize (current_loops);
}
static bool
gate_tree_ssa_loop_ivopts (void)
{
return flag_ivopts != 0;
}
struct tree_opt_pass pass_iv_optimize =
{
"ivopts",
gate_tree_ssa_loop_ivopts,
tree_ssa_loop_ivopts,
NULL,
NULL,
0,
TV_TREE_LOOP_IVOPTS,
PROP_cfg | PROP_ssa,
0,
0,
0,
TODO_dump_func,
0
};
static void
tree_ssa_loop_done (void)
{
if (!current_loops)
return;
#ifdef ENABLE_CHECKING
verify_loop_closed_ssa ();
#endif
free_numbers_of_iterations_estimates (current_loops);
scev_finalize ();
loop_optimizer_finalize (current_loops,
(dump_flags & TDF_DETAILS ? dump_file : NULL));
current_loops = NULL;
}
struct tree_opt_pass pass_loop_done =
{
"loopdone",
NULL,
tree_ssa_loop_done,
NULL,
NULL,
0,
0,
PROP_cfg,
0,
0,
0,
TODO_cleanup_cfg | TODO_dump_func,
0
};