tree-flow.h: Remove all remaining prototypes...
* tree-flow.h: Remove all remaining prototypes, enums and structs that are not related to tree-cfg.c. * tree-ssa-address.h: New file. Relocate prototypes. * tree-ssa-address.c: (struct mem_address): Relocate from tree-flow.h. (addr_for_mem_ref): New. Combine call to get_address_description and return addr_for_mem_ref. * expr.c (expand_expr_real_1): Use new addr_for_mem_ref routine. * tree-ssa-live.h: Adjust prototypes. * passes.c: Include tree-ssa-live.h. * gimple-pretty-print.h (gimple_dump_bb): Add prototype. * graphite.c (graphite_transform_loops): Make static. (graphite_transforms, gate_graphite_transforms, pass_data_graphite, make_pass_graphite, pass_data_graphite_transforms, make_pass_graphite_transforms): Relocate here from tree-ssa-loop.c. * ipa-pure-const.c (warn_function_noreturn): Make static. (execute_warn_function_noreturn, gate_warn_function_noreturn, class pass_warn_function_noreturn, make_pass_warn_function_noreturn): Relocate from tree-cfg.c * tree-cfg.c (tree_node_can_be_shared, gimple_empty_block_p): Make static. (execute_warn_function_noreturn, gate_warn_function_noreturn, class pass_warn_function_noreturn, make_pass_warn_function_noreturn): Move to ipa-pure-const.c. (execute_fixup_cfg, class pass_fixup_cfg, make_pass_fixup_cfg): Relocate from tree-optimize.c. * tree-optimize.c (execute_fixup_cfg, class pass_fixup_cfg, make_pass_fixup_cfg): Move to tree-cfg.c. * tree-chrec.h: (enum ev_direction): Relocate here from tree-flow.h. Relocate some prototypes. * tree-data-ref.h (tree_check_data_deps) Add prototype. * tree-dump.c (dump_function_to_file): Remove prototype. Add tree-flow.h to the include file. * tree-dump.h: Remove prototype. * tree-parloops.h: New File. Add prototypes. * tree-parloops.c (gate_tree_parallelize_loops, tree_parallelize_loops, pass_data_parallelize_loops, make_pass_parallelize_loops): Relocate from tree-ssa-loop.c. * tree-predcom.c (run_tree_predictive_commoning, gate_tree_predictive_commoning, pass_data_predcom, make_pass_predcom): Relocate here from tree-ssa-loop.c. * tree-ssa-dom.c (tree_ssa_dominator_optimize) Don't call ssa_name_values.release (). * tree-ssa-threadedge.h: New File. Relocate prototypes here. (ssa_name_values): Relocate from tree-flow.h. * tree-ssa.h: Include tree-ssa-threadedge.h and tree-ssa-address.h. * tree-ssa-loop.c (run_tree_predictive_commoning, gate_tree_predictive_commoning, pass_data_predcom, make_pass_predcom, graphite_transforms, gate_graphite_transforms, pass_data_graphite, make_pass_graphite, pass_data_graphite_transforms, make_pass_graphite_transforms, gate_tree_parallelize_loops, tree_parallelize_loops, pass_data_parallelize_loops, make_pass_parallelize_loops): Move to other files. * tree-vectorizer.h (lpeel_tree_duplicate_loop_to_edge_cfg): Prototype moved here. * tree.h: Remove prototypes from tree-address.c. From-SVN: r203320
This commit is contained in:
parent
428e041efe
commit
c1bf2a39b3
25 changed files with 666 additions and 553 deletions
|
@ -1,3 +1,61 @@
|
|||
2013-10-09 Andrew MacLeod <amacleod@redhat.com>
|
||||
|
||||
* tree-flow.h: Remove all remaining prototypes, enums and structs that
|
||||
are not related to tree-cfg.c.
|
||||
* tree-ssa-address.h: New file. Relocate prototypes.
|
||||
* tree-ssa-address.c: (struct mem_address): Relocate from tree-flow.h.
|
||||
(addr_for_mem_ref): New. Combine call to get_address_description and
|
||||
return addr_for_mem_ref.
|
||||
* expr.c (expand_expr_real_1): Use new addr_for_mem_ref routine.
|
||||
* tree-ssa-live.h: Adjust prototypes.
|
||||
* passes.c: Include tree-ssa-live.h.
|
||||
* gimple-pretty-print.h (gimple_dump_bb): Add prototype.
|
||||
* graphite.c (graphite_transform_loops): Make static.
|
||||
(graphite_transforms, gate_graphite_transforms, pass_data_graphite,
|
||||
make_pass_graphite, pass_data_graphite_transforms,
|
||||
make_pass_graphite_transforms): Relocate here from tree-ssa-loop.c.
|
||||
* ipa-pure-const.c (warn_function_noreturn): Make static.
|
||||
(execute_warn_function_noreturn, gate_warn_function_noreturn,
|
||||
class pass_warn_function_noreturn, make_pass_warn_function_noreturn):
|
||||
Relocate from tree-cfg.c
|
||||
* tree-cfg.c (tree_node_can_be_shared, gimple_empty_block_p): Make
|
||||
static.
|
||||
(execute_warn_function_noreturn, gate_warn_function_noreturn,
|
||||
class pass_warn_function_noreturn, make_pass_warn_function_noreturn):
|
||||
Move to ipa-pure-const.c.
|
||||
(execute_fixup_cfg, class pass_fixup_cfg, make_pass_fixup_cfg): Relocate
|
||||
from tree-optimize.c.
|
||||
* tree-optimize.c (execute_fixup_cfg, class pass_fixup_cfg,
|
||||
make_pass_fixup_cfg): Move to tree-cfg.c.
|
||||
* tree-chrec.h: (enum ev_direction): Relocate here from tree-flow.h.
|
||||
Relocate some prototypes.
|
||||
* tree-data-ref.h (tree_check_data_deps) Add prototype.
|
||||
* tree-dump.c (dump_function_to_file): Remove prototype.
|
||||
Add tree-flow.h to the include file.
|
||||
* tree-dump.h: Remove prototype.
|
||||
* tree-parloops.h: New File. Add prototypes.
|
||||
* tree-parloops.c (gate_tree_parallelize_loops, tree_parallelize_loops,
|
||||
pass_data_parallelize_loops, make_pass_parallelize_loops): Relocate
|
||||
from tree-ssa-loop.c.
|
||||
* tree-predcom.c (run_tree_predictive_commoning,
|
||||
gate_tree_predictive_commoning, pass_data_predcom, make_pass_predcom):
|
||||
Relocate here from tree-ssa-loop.c.
|
||||
* tree-ssa-dom.c (tree_ssa_dominator_optimize) Don't call
|
||||
ssa_name_values.release ().
|
||||
* tree-ssa-threadedge.h: New File. Relocate prototypes here.
|
||||
(ssa_name_values): Relocate from tree-flow.h.
|
||||
* tree-ssa.h: Include tree-ssa-threadedge.h and tree-ssa-address.h.
|
||||
* tree-ssa-loop.c (run_tree_predictive_commoning,
|
||||
gate_tree_predictive_commoning, pass_data_predcom, make_pass_predcom,
|
||||
graphite_transforms, gate_graphite_transforms, pass_data_graphite,
|
||||
make_pass_graphite, pass_data_graphite_transforms,
|
||||
make_pass_graphite_transforms, gate_tree_parallelize_loops,
|
||||
tree_parallelize_loops, pass_data_parallelize_loops,
|
||||
make_pass_parallelize_loops): Move to other files.
|
||||
* tree-vectorizer.h (lpeel_tree_duplicate_loop_to_edge_cfg): Prototype
|
||||
moved here.
|
||||
* tree.h: Remove prototypes from tree-address.c.
|
||||
|
||||
2013-10-09 Andrew MacLeod <amacleod@redhat.com>
|
||||
|
||||
* tree-flow.h (tm_restart_node, gimple_df): Move to gimple-ssa.h.
|
||||
|
|
|
@ -9560,12 +9560,10 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
|
|||
{
|
||||
addr_space_t as
|
||||
= TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0))));
|
||||
struct mem_address addr;
|
||||
enum insn_code icode;
|
||||
unsigned int align;
|
||||
|
||||
get_address_description (exp, &addr);
|
||||
op0 = addr_for_mem_ref (&addr, as, true);
|
||||
op0 = addr_for_mem_ref (exp, as, true);
|
||||
op0 = memory_address_addr_space (mode, op0, as);
|
||||
temp = gen_rtx_MEM (mode, op0);
|
||||
set_mem_attributes (temp, exp, 0);
|
||||
|
|
|
@ -33,6 +33,7 @@ extern void debug (gimple_statement_d &ref);
|
|||
extern void debug (gimple_statement_d *ptr);
|
||||
extern void print_gimple_expr (FILE *, gimple, int, int);
|
||||
extern void pp_gimple_stmt_1 (pretty_printer *, gimple, int, int);
|
||||
extern void gimple_dump_bb (FILE *, basic_block, int, int);
|
||||
extern void gimple_dump_bb_for_graph (pretty_printer *, basic_block);
|
||||
|
||||
#endif /* ! GCC_GIMPLE_PRETTY_PRINT_H */
|
||||
|
|
109
gcc/graphite.c
109
gcc/graphite.c
|
@ -55,6 +55,8 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "tree-scalar-evolution.h"
|
||||
#include "sese.h"
|
||||
#include "dbgcnt.h"
|
||||
#include "tree-parloops.h"
|
||||
#include "tree-pass.h"
|
||||
|
||||
#ifdef HAVE_cloog
|
||||
|
||||
|
@ -301,10 +303,115 @@ graphite_transform_loops (void)
|
|||
|
||||
#else /* If Cloog is not available: #ifndef HAVE_cloog. */
|
||||
|
||||
void
|
||||
static void
|
||||
graphite_transform_loops (void)
|
||||
{
|
||||
sorry ("Graphite loop optimizations cannot be used");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static unsigned int
|
||||
graphite_transforms (void)
|
||||
{
|
||||
if (!current_loops)
|
||||
return 0;
|
||||
|
||||
graphite_transform_loops ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool
|
||||
gate_graphite_transforms (void)
|
||||
{
|
||||
/* Enable -fgraphite pass if any one of the graphite optimization flags
|
||||
is turned on. */
|
||||
if (flag_loop_block
|
||||
|| flag_loop_interchange
|
||||
|| flag_loop_strip_mine
|
||||
|| flag_graphite_identity
|
||||
|| flag_loop_parallelize_all
|
||||
|| flag_loop_optimize_isl)
|
||||
flag_graphite = 1;
|
||||
|
||||
return flag_graphite != 0;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
const pass_data pass_data_graphite =
|
||||
{
|
||||
GIMPLE_PASS, /* type */
|
||||
"graphite0", /* name */
|
||||
OPTGROUP_LOOP, /* optinfo_flags */
|
||||
true, /* has_gate */
|
||||
false, /* has_execute */
|
||||
TV_GRAPHITE, /* tv_id */
|
||||
( PROP_cfg | PROP_ssa ), /* properties_required */
|
||||
0, /* properties_provided */
|
||||
0, /* properties_destroyed */
|
||||
0, /* todo_flags_start */
|
||||
0, /* todo_flags_finish */
|
||||
};
|
||||
|
||||
class pass_graphite : public gimple_opt_pass
|
||||
{
|
||||
public:
|
||||
pass_graphite (gcc::context *ctxt)
|
||||
: gimple_opt_pass (pass_data_graphite, ctxt)
|
||||
{}
|
||||
|
||||
/* opt_pass methods: */
|
||||
bool gate () { return gate_graphite_transforms (); }
|
||||
|
||||
}; // class pass_graphite
|
||||
|
||||
} // anon namespace
|
||||
|
||||
gimple_opt_pass *
|
||||
make_pass_graphite (gcc::context *ctxt)
|
||||
{
|
||||
return new pass_graphite (ctxt);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
const pass_data pass_data_graphite_transforms =
|
||||
{
|
||||
GIMPLE_PASS, /* type */
|
||||
"graphite", /* name */
|
||||
OPTGROUP_LOOP, /* optinfo_flags */
|
||||
true, /* has_gate */
|
||||
true, /* has_execute */
|
||||
TV_GRAPHITE_TRANSFORMS, /* tv_id */
|
||||
( PROP_cfg | PROP_ssa ), /* properties_required */
|
||||
0, /* properties_provided */
|
||||
0, /* properties_destroyed */
|
||||
0, /* todo_flags_start */
|
||||
0, /* todo_flags_finish */
|
||||
};
|
||||
|
||||
class pass_graphite_transforms : public gimple_opt_pass
|
||||
{
|
||||
public:
|
||||
pass_graphite_transforms (gcc::context *ctxt)
|
||||
: gimple_opt_pass (pass_data_graphite_transforms, ctxt)
|
||||
{}
|
||||
|
||||
/* opt_pass methods: */
|
||||
bool gate () { return gate_graphite_transforms (); }
|
||||
unsigned int execute () { return graphite_transforms (); }
|
||||
|
||||
}; // class pass_graphite_transforms
|
||||
|
||||
} // anon namespace
|
||||
|
||||
gimple_opt_pass *
|
||||
make_pass_graphite_transforms (gcc::context *ctxt)
|
||||
{
|
||||
return new pass_graphite_transforms (ctxt);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -179,7 +179,7 @@ warn_function_const (tree decl, bool known_finite)
|
|||
known_finite, warned_about, "const");
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
warn_function_noreturn (tree decl)
|
||||
{
|
||||
static struct pointer_set_t *warned_about;
|
||||
|
@ -1722,3 +1722,60 @@ make_pass_local_pure_const (gcc::context *ctxt)
|
|||
{
|
||||
return new pass_local_pure_const (ctxt);
|
||||
}
|
||||
|
||||
/* Emit noreturn warnings. */
|
||||
|
||||
static unsigned int
|
||||
execute_warn_function_noreturn (void)
|
||||
{
|
||||
if (!TREE_THIS_VOLATILE (current_function_decl)
|
||||
&& EDGE_COUNT (EXIT_BLOCK_PTR->preds) == 0)
|
||||
warn_function_noreturn (current_function_decl);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool
|
||||
gate_warn_function_noreturn (void)
|
||||
{
|
||||
return warn_suggest_attribute_noreturn;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
const pass_data pass_data_warn_function_noreturn =
|
||||
{
|
||||
GIMPLE_PASS, /* type */
|
||||
"*warn_function_noreturn", /* name */
|
||||
OPTGROUP_NONE, /* optinfo_flags */
|
||||
true, /* has_gate */
|
||||
true, /* has_execute */
|
||||
TV_NONE, /* tv_id */
|
||||
PROP_cfg, /* properties_required */
|
||||
0, /* properties_provided */
|
||||
0, /* properties_destroyed */
|
||||
0, /* todo_flags_start */
|
||||
0, /* todo_flags_finish */
|
||||
};
|
||||
|
||||
class pass_warn_function_noreturn : public gimple_opt_pass
|
||||
{
|
||||
public:
|
||||
pass_warn_function_noreturn (gcc::context *ctxt)
|
||||
: gimple_opt_pass (pass_data_warn_function_noreturn, ctxt)
|
||||
{}
|
||||
|
||||
/* opt_pass methods: */
|
||||
bool gate () { return gate_warn_function_noreturn (); }
|
||||
unsigned int execute () { return execute_warn_function_noreturn (); }
|
||||
|
||||
}; // class pass_warn_function_noreturn
|
||||
|
||||
} // anon namespace
|
||||
|
||||
gimple_opt_pass *
|
||||
make_pass_warn_function_noreturn (gcc::context *ctxt)
|
||||
{
|
||||
return new pass_warn_function_noreturn (ctxt);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -72,6 +72,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "tree-pretty-print.h" /* for dump_function_header */
|
||||
#include "context.h"
|
||||
#include "pass_manager.h"
|
||||
#include "tree-ssa-live.h" /* For remove_unused_locals. */
|
||||
|
||||
using namespace gcc;
|
||||
|
||||
|
|
201
gcc/tree-cfg.c
201
gcc/tree-cfg.c
|
@ -41,6 +41,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "pointer-set.h"
|
||||
#include "tree-inline.h"
|
||||
#include "target.h"
|
||||
#include "tree-ssa-live.h"
|
||||
|
||||
/* This file contains functions for building the Control Flow Graph (CFG)
|
||||
for a function tree. */
|
||||
|
@ -4449,7 +4450,7 @@ verify_gimple_in_seq (gimple_seq stmts)
|
|||
|
||||
/* Return true when the T can be shared. */
|
||||
|
||||
bool
|
||||
static bool
|
||||
tree_node_can_be_shared (tree t)
|
||||
{
|
||||
if (IS_TYPE_OR_DECL_P (t)
|
||||
|
@ -5459,7 +5460,7 @@ gimple_move_block_after (basic_block bb, basic_block after)
|
|||
/* Return TRUE if block BB has no executable statements, otherwise return
|
||||
FALSE. */
|
||||
|
||||
bool
|
||||
static bool
|
||||
gimple_empty_block_p (basic_block bb)
|
||||
{
|
||||
/* BB must have no executable statements. */
|
||||
|
@ -8106,62 +8107,6 @@ make_pass_warn_function_return (gcc::context *ctxt)
|
|||
return new pass_warn_function_return (ctxt);
|
||||
}
|
||||
|
||||
/* Emit noreturn warnings. */
|
||||
|
||||
static unsigned int
|
||||
execute_warn_function_noreturn (void)
|
||||
{
|
||||
if (!TREE_THIS_VOLATILE (current_function_decl)
|
||||
&& EDGE_COUNT (EXIT_BLOCK_PTR->preds) == 0)
|
||||
warn_function_noreturn (current_function_decl);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool
|
||||
gate_warn_function_noreturn (void)
|
||||
{
|
||||
return warn_suggest_attribute_noreturn;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
const pass_data pass_data_warn_function_noreturn =
|
||||
{
|
||||
GIMPLE_PASS, /* type */
|
||||
"*warn_function_noreturn", /* name */
|
||||
OPTGROUP_NONE, /* optinfo_flags */
|
||||
true, /* has_gate */
|
||||
true, /* has_execute */
|
||||
TV_NONE, /* tv_id */
|
||||
PROP_cfg, /* properties_required */
|
||||
0, /* properties_provided */
|
||||
0, /* properties_destroyed */
|
||||
0, /* todo_flags_start */
|
||||
0, /* todo_flags_finish */
|
||||
};
|
||||
|
||||
class pass_warn_function_noreturn : public gimple_opt_pass
|
||||
{
|
||||
public:
|
||||
pass_warn_function_noreturn (gcc::context *ctxt)
|
||||
: gimple_opt_pass (pass_data_warn_function_noreturn, ctxt)
|
||||
{}
|
||||
|
||||
/* opt_pass methods: */
|
||||
bool gate () { return gate_warn_function_noreturn (); }
|
||||
unsigned int execute () { return execute_warn_function_noreturn (); }
|
||||
|
||||
}; // class pass_warn_function_noreturn
|
||||
|
||||
} // anon namespace
|
||||
|
||||
gimple_opt_pass *
|
||||
make_pass_warn_function_noreturn (gcc::context *ctxt)
|
||||
{
|
||||
return new pass_warn_function_noreturn (ctxt);
|
||||
}
|
||||
|
||||
|
||||
/* Walk a gimplified function and warn for functions whose return value is
|
||||
ignored and attribute((warn_unused_result)) is set. This is done before
|
||||
inlining, so we don't have to worry about that. */
|
||||
|
@ -8278,6 +8223,146 @@ make_pass_warn_unused_result (gcc::context *ctxt)
|
|||
return new pass_warn_unused_result (ctxt);
|
||||
}
|
||||
|
||||
/* IPA passes, compilation of earlier functions or inlining
|
||||
might have changed some properties, such as marked functions nothrow,
|
||||
pure, const or noreturn.
|
||||
Remove redundant edges and basic blocks, and create new ones if necessary.
|
||||
|
||||
This pass can't be executed as stand alone pass from pass manager, because
|
||||
in between inlining and this fixup the verify_flow_info would fail. */
|
||||
|
||||
unsigned int
|
||||
execute_fixup_cfg (void)
|
||||
{
|
||||
basic_block bb;
|
||||
gimple_stmt_iterator gsi;
|
||||
int todo = gimple_in_ssa_p (cfun) ? TODO_verify_ssa : 0;
|
||||
gcov_type count_scale;
|
||||
edge e;
|
||||
edge_iterator ei;
|
||||
|
||||
count_scale
|
||||
= GCOV_COMPUTE_SCALE (cgraph_get_node (current_function_decl)->count,
|
||||
ENTRY_BLOCK_PTR->count);
|
||||
|
||||
ENTRY_BLOCK_PTR->count = cgraph_get_node (current_function_decl)->count;
|
||||
EXIT_BLOCK_PTR->count = apply_scale (EXIT_BLOCK_PTR->count,
|
||||
count_scale);
|
||||
|
||||
FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
|
||||
e->count = apply_scale (e->count, count_scale);
|
||||
|
||||
FOR_EACH_BB (bb)
|
||||
{
|
||||
bb->count = apply_scale (bb->count, count_scale);
|
||||
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
|
||||
{
|
||||
gimple stmt = gsi_stmt (gsi);
|
||||
tree decl = is_gimple_call (stmt)
|
||||
? gimple_call_fndecl (stmt)
|
||||
: NULL;
|
||||
if (decl)
|
||||
{
|
||||
int flags = gimple_call_flags (stmt);
|
||||
if (flags & (ECF_CONST | ECF_PURE | ECF_LOOPING_CONST_OR_PURE))
|
||||
{
|
||||
if (gimple_purge_dead_abnormal_call_edges (bb))
|
||||
todo |= TODO_cleanup_cfg;
|
||||
|
||||
if (gimple_in_ssa_p (cfun))
|
||||
{
|
||||
todo |= TODO_update_ssa | TODO_cleanup_cfg;
|
||||
update_stmt (stmt);
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & ECF_NORETURN
|
||||
&& fixup_noreturn_call (stmt))
|
||||
todo |= TODO_cleanup_cfg;
|
||||
}
|
||||
|
||||
if (maybe_clean_eh_stmt (stmt)
|
||||
&& gimple_purge_dead_eh_edges (bb))
|
||||
todo |= TODO_cleanup_cfg;
|
||||
}
|
||||
|
||||
FOR_EACH_EDGE (e, ei, bb->succs)
|
||||
e->count = apply_scale (e->count, count_scale);
|
||||
|
||||
/* If we have a basic block with no successors that does not
|
||||
end with a control statement or a noreturn call end it with
|
||||
a call to __builtin_unreachable. This situation can occur
|
||||
when inlining a noreturn call that does in fact return. */
|
||||
if (EDGE_COUNT (bb->succs) == 0)
|
||||
{
|
||||
gimple stmt = last_stmt (bb);
|
||||
if (!stmt
|
||||
|| (!is_ctrl_stmt (stmt)
|
||||
&& (!is_gimple_call (stmt)
|
||||
|| (gimple_call_flags (stmt) & ECF_NORETURN) == 0)))
|
||||
{
|
||||
stmt = gimple_build_call
|
||||
(builtin_decl_implicit (BUILT_IN_UNREACHABLE), 0);
|
||||
gimple_stmt_iterator gsi = gsi_last_bb (bb);
|
||||
gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count_scale != REG_BR_PROB_BASE)
|
||||
compute_function_frequency ();
|
||||
|
||||
/* We just processed all calls. */
|
||||
if (cfun->gimple_df)
|
||||
vec_free (MODIFIED_NORETURN_CALLS (cfun));
|
||||
|
||||
/* Dump a textual representation of the flowgraph. */
|
||||
if (dump_file)
|
||||
gimple_dump_cfg (dump_file, dump_flags);
|
||||
|
||||
if (current_loops
|
||||
&& (todo & TODO_cleanup_cfg))
|
||||
loops_state_set (LOOPS_NEED_FIXUP);
|
||||
|
||||
return todo;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
const pass_data pass_data_fixup_cfg =
|
||||
{
|
||||
GIMPLE_PASS, /* type */
|
||||
"*free_cfg_annotations", /* name */
|
||||
OPTGROUP_NONE, /* optinfo_flags */
|
||||
false, /* has_gate */
|
||||
true, /* has_execute */
|
||||
TV_NONE, /* tv_id */
|
||||
PROP_cfg, /* properties_required */
|
||||
0, /* properties_provided */
|
||||
0, /* properties_destroyed */
|
||||
0, /* todo_flags_start */
|
||||
0, /* todo_flags_finish */
|
||||
};
|
||||
|
||||
class pass_fixup_cfg : public gimple_opt_pass
|
||||
{
|
||||
public:
|
||||
pass_fixup_cfg (gcc::context *ctxt)
|
||||
: gimple_opt_pass (pass_data_fixup_cfg, ctxt)
|
||||
{}
|
||||
|
||||
/* opt_pass methods: */
|
||||
opt_pass * clone () { return new pass_fixup_cfg (m_ctxt); }
|
||||
unsigned int execute () { return execute_fixup_cfg (); }
|
||||
|
||||
}; // class pass_fixup_cfg
|
||||
|
||||
} // anon namespace
|
||||
|
||||
gimple_opt_pass *
|
||||
make_pass_fixup_cfg (gcc::context *ctxt)
|
||||
{
|
||||
return new pass_fixup_cfg (ctxt);
|
||||
}
|
||||
|
||||
/* Garbage collection support for edge_def. */
|
||||
|
||||
|
|
|
@ -52,6 +52,8 @@ tree_is_chrec (const_tree expr)
|
|||
}
|
||||
|
||||
|
||||
enum ev_direction {EV_DIR_GROWS, EV_DIR_DECREASES, EV_DIR_UNKNOWN};
|
||||
enum ev_direction scev_direction (const_tree);
|
||||
|
||||
/* Chrec folding functions. */
|
||||
extern tree chrec_fold_plus (tree, tree, tree);
|
||||
|
@ -72,6 +74,8 @@ extern tree hide_evolution_in_other_loops_than_loop (tree, unsigned);
|
|||
extern tree reset_evolution_in_loop (unsigned, tree, tree);
|
||||
extern tree chrec_merge (tree, tree);
|
||||
extern void for_each_scev_op (tree *, bool (*) (tree *, void *), void *);
|
||||
extern bool convert_affine_scev (struct loop *, tree, tree *, tree *, gimple,
|
||||
bool);
|
||||
|
||||
/* Observers. */
|
||||
extern bool eq_evolutions_p (const_tree, const_tree);
|
||||
|
|
|
@ -406,6 +406,7 @@ extern bool dr_may_alias_p (const struct data_reference *,
|
|||
const struct data_reference *, bool);
|
||||
extern bool dr_equal_offsets_p (struct data_reference *,
|
||||
struct data_reference *);
|
||||
extern void tree_check_data_deps (void);
|
||||
|
||||
|
||||
/* Return true when the base objects of data references A and B are
|
||||
|
|
|
@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "langhooks.h"
|
||||
#include "tree-iterator.h"
|
||||
#include "tree-pretty-print.h"
|
||||
#include "tree-flow.h"
|
||||
|
||||
static unsigned int queue (dump_info_p, const_tree, int);
|
||||
static void dump_index (dump_info_p, unsigned int);
|
||||
|
|
|
@ -90,7 +90,4 @@ extern void queue_and_dump_type (dump_info_p, const_tree);
|
|||
extern void dump_function (int, tree);
|
||||
extern int dump_flag (dump_info_p, int, const_tree);
|
||||
|
||||
/* In tree-cfg.c */
|
||||
extern void dump_function_to_file (tree, FILE *, int);
|
||||
|
||||
#endif /* ! GCC_TREE_DUMP_H */
|
||||
|
|
166
gcc/tree-flow.h
166
gcc/tree-flow.h
|
@ -87,120 +87,77 @@ extern void free_omp_regions (void);
|
|||
void omp_expand_local (basic_block);
|
||||
tree copy_var_decl (tree, tree, tree);
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Function prototypes
|
||||
---------------------------------------------------------------------------*/
|
||||
/* In tree-cfg.c */
|
||||
|
||||
/* Location to track pending stmt for edge insertion. */
|
||||
#define PENDING_STMT(e) ((e)->insns.g)
|
||||
|
||||
extern void delete_tree_cfg_annotations (void);
|
||||
extern bool stmt_ends_bb_p (gimple);
|
||||
extern bool is_ctrl_stmt (gimple);
|
||||
extern bool is_ctrl_altering_stmt (gimple);
|
||||
extern bool simple_goto_p (gimple);
|
||||
extern bool stmt_can_make_abnormal_goto (gimple);
|
||||
extern basic_block single_noncomplex_succ (basic_block bb);
|
||||
extern void gimple_dump_bb (FILE *, basic_block, int, int);
|
||||
extern void gimple_debug_bb (basic_block);
|
||||
extern basic_block gimple_debug_bb_n (int);
|
||||
extern void gimple_dump_cfg (FILE *, int);
|
||||
extern void gimple_debug_cfg (int);
|
||||
extern void dump_cfg_stats (FILE *);
|
||||
extern void dot_cfg (void);
|
||||
extern void debug_cfg_stats (void);
|
||||
extern void debug_loops (int);
|
||||
extern void debug_loop (struct loop *, int);
|
||||
extern void debug (struct loop &ref);
|
||||
extern void debug (struct loop *ptr);
|
||||
extern void debug_verbose (struct loop &ref);
|
||||
extern void debug_verbose (struct loop *ptr);
|
||||
extern void debug_loop_num (unsigned, int);
|
||||
extern void print_loops (FILE *, int);
|
||||
extern void print_loops_bb (FILE *, basic_block, int, int);
|
||||
extern void init_empty_tree_cfg_for_function (struct function *);
|
||||
extern void init_empty_tree_cfg (void);
|
||||
extern void fold_cond_expr_cond (void);
|
||||
extern void start_recording_case_labels (void);
|
||||
extern void end_recording_case_labels (void);
|
||||
extern basic_block label_to_block_fn (struct function *, tree);
|
||||
#define label_to_block(t) (label_to_block_fn (cfun, t))
|
||||
extern void make_abnormal_goto_edges (basic_block, bool);
|
||||
extern void cleanup_dead_labels (void);
|
||||
extern void group_case_labels_stmt (gimple);
|
||||
extern void group_case_labels (void);
|
||||
extern void replace_uses_by (tree, tree);
|
||||
extern basic_block single_noncomplex_succ (basic_block bb);
|
||||
extern void notice_special_calls (gimple);
|
||||
extern void clear_special_calls (void);
|
||||
extern edge find_taken_edge (basic_block, tree);
|
||||
extern void gimple_debug_bb (basic_block);
|
||||
extern basic_block gimple_debug_bb_n (int);
|
||||
extern void gimple_debug_cfg (int);
|
||||
extern void gimple_dump_cfg (FILE *, int);
|
||||
extern void dump_cfg_stats (FILE *);
|
||||
extern void debug_cfg_stats (void);
|
||||
extern bool stmt_can_make_abnormal_goto (gimple);
|
||||
extern bool is_ctrl_stmt (gimple);
|
||||
extern bool is_ctrl_altering_stmt (gimple);
|
||||
extern bool simple_goto_p (gimple);
|
||||
extern bool stmt_ends_bb_p (gimple);
|
||||
extern void delete_tree_cfg_annotations (void);
|
||||
extern gimple first_stmt (basic_block);
|
||||
extern gimple last_stmt (basic_block);
|
||||
extern gimple last_and_only_stmt (basic_block);
|
||||
extern edge find_taken_edge (basic_block, tree);
|
||||
extern basic_block label_to_block_fn (struct function *, tree);
|
||||
#define label_to_block(t) (label_to_block_fn (cfun, t))
|
||||
extern void notice_special_calls (gimple);
|
||||
extern void clear_special_calls (void);
|
||||
extern void verify_gimple_in_seq (gimple_seq);
|
||||
extern void verify_gimple_in_cfg (struct function *);
|
||||
extern tree gimple_block_label (basic_block);
|
||||
extern void extract_true_false_edges_from_block (basic_block, edge *, edge *);
|
||||
extern void add_phi_args_after_copy_bb (basic_block);
|
||||
extern void add_phi_args_after_copy (basic_block *, unsigned, edge);
|
||||
extern bool gimple_duplicate_sese_region (edge, edge, basic_block *, unsigned,
|
||||
basic_block *, bool);
|
||||
extern bool gimple_duplicate_sese_tail (edge, edge, basic_block *, unsigned,
|
||||
basic_block *);
|
||||
extern void gather_blocks_in_sese_region (basic_block entry, basic_block exit,
|
||||
vec<basic_block> *bbs_p);
|
||||
extern void add_phi_args_after_copy_bb (basic_block);
|
||||
extern void add_phi_args_after_copy (basic_block *, unsigned, edge);
|
||||
extern basic_block move_sese_region_to_fn (struct function *, basic_block,
|
||||
basic_block, tree);
|
||||
extern void dump_function_to_file (tree, FILE *, int);
|
||||
extern void debug_function (tree, int) ;
|
||||
extern void print_loops_bb (FILE *, basic_block, int, int);
|
||||
extern void print_loops (FILE *, int);
|
||||
extern void debug (struct loop &ref);
|
||||
extern void debug (struct loop *ptr);
|
||||
extern void debug_verbose (struct loop &ref);
|
||||
extern void debug_verbose (struct loop *ptr);
|
||||
extern void debug_loops (int);
|
||||
extern void debug_loop (struct loop *, int);
|
||||
extern void debug_loop_num (unsigned, int);
|
||||
void remove_edge_and_dominated_blocks (edge);
|
||||
extern bool gimple_purge_dead_eh_edges (basic_block);
|
||||
extern bool gimple_purge_all_dead_eh_edges (const_bitmap);
|
||||
extern bool gimple_purge_dead_abnormal_call_edges (basic_block);
|
||||
extern bool gimple_purge_all_dead_abnormal_call_edges (const_bitmap);
|
||||
extern tree gimplify_build1 (gimple_stmt_iterator *, enum tree_code,
|
||||
tree, tree);
|
||||
extern tree gimplify_build2 (gimple_stmt_iterator *, enum tree_code,
|
||||
tree, tree, tree);
|
||||
extern tree gimplify_build3 (gimple_stmt_iterator *, enum tree_code,
|
||||
tree, tree, tree, tree);
|
||||
extern void init_empty_tree_cfg (void);
|
||||
extern void init_empty_tree_cfg_for_function (struct function *);
|
||||
extern void fold_cond_expr_cond (void);
|
||||
extern void make_abnormal_goto_edges (basic_block, bool);
|
||||
extern void replace_uses_by (tree, tree);
|
||||
extern void start_recording_case_labels (void);
|
||||
extern void end_recording_case_labels (void);
|
||||
extern basic_block move_sese_region_to_fn (struct function *, basic_block,
|
||||
basic_block, tree);
|
||||
void remove_edge_and_dominated_blocks (edge);
|
||||
bool tree_node_can_be_shared (tree);
|
||||
|
||||
|
||||
|
||||
/* In tree-ssa-loop*.c */
|
||||
|
||||
unsigned tree_predictive_commoning (void);
|
||||
bool parallelize_loops (void);
|
||||
|
||||
bool convert_affine_scev (struct loop *, tree, tree *, tree *, gimple, bool);
|
||||
|
||||
enum ev_direction {EV_DIR_GROWS, EV_DIR_DECREASES, EV_DIR_UNKNOWN};
|
||||
enum ev_direction scev_direction (const_tree);
|
||||
|
||||
struct loop *slpeel_tree_duplicate_loop_to_edge_cfg (struct loop *, edge);
|
||||
|
||||
/* In tree-ssa-threadedge.c */
|
||||
extern void threadedge_initialize_values (void);
|
||||
extern void threadedge_finalize_values (void);
|
||||
extern vec<tree> ssa_name_values;
|
||||
#define SSA_NAME_VALUE(x) \
|
||||
(SSA_NAME_VERSION (x) < ssa_name_values.length () \
|
||||
? ssa_name_values[SSA_NAME_VERSION (x)] \
|
||||
: NULL_TREE)
|
||||
extern void set_ssa_name_value (tree, tree);
|
||||
extern bool potentially_threadable_block (basic_block);
|
||||
extern void thread_across_edge (gimple, edge, bool,
|
||||
vec<tree> *, tree (*) (gimple, gimple));
|
||||
extern void propagate_threaded_block_debug_into (basic_block, basic_block);
|
||||
|
||||
/* In tree-loop-linear.c */
|
||||
extern void linear_transform_loops (void);
|
||||
extern unsigned perfect_loop_nest_depth (struct loop *);
|
||||
|
||||
/* In graphite.c */
|
||||
extern void graphite_transform_loops (void);
|
||||
|
||||
/* In tree-data-ref.c */
|
||||
extern void tree_check_data_deps (void);
|
||||
extern tree gimplify_build2 (gimple_stmt_iterator *, enum tree_code,
|
||||
tree, tree, tree);
|
||||
extern tree gimplify_build1 (gimple_stmt_iterator *, enum tree_code,
|
||||
tree, tree);
|
||||
extern void extract_true_false_edges_from_block (basic_block, edge *, edge *);
|
||||
extern unsigned int execute_fixup_cfg (void);
|
||||
|
||||
/* In gimplify.c */
|
||||
tree force_gimple_operand_1 (tree, gimple_seq *, gimple_predicate, tree);
|
||||
|
@ -212,34 +169,5 @@ tree force_gimple_operand_gsi (gimple_stmt_iterator *, tree, bool, tree,
|
|||
bool, enum gsi_iterator_update);
|
||||
tree gimple_fold_indirect_ref (tree);
|
||||
|
||||
/* In tree-ssa-live.c */
|
||||
extern void remove_unused_locals (void);
|
||||
extern void dump_scope_blocks (FILE *, int);
|
||||
extern void debug_scope_blocks (int);
|
||||
extern void debug_scope_block (tree, int);
|
||||
|
||||
/* In tree-ssa-address.c */
|
||||
|
||||
/* Description of a memory address. */
|
||||
|
||||
struct mem_address
|
||||
{
|
||||
tree symbol, base, index, step, offset;
|
||||
};
|
||||
|
||||
struct affine_tree_combination;
|
||||
tree create_mem_ref (gimple_stmt_iterator *, tree,
|
||||
struct affine_tree_combination *, tree, tree, tree, bool);
|
||||
rtx addr_for_mem_ref (struct mem_address *, addr_space_t, bool);
|
||||
void get_address_description (tree, struct mem_address *);
|
||||
tree maybe_fold_tmr (tree);
|
||||
|
||||
unsigned int execute_fixup_cfg (void);
|
||||
|
||||
/* In ipa-pure-const.c */
|
||||
void warn_function_noreturn (tree);
|
||||
|
||||
/* In tree-parloops.c */
|
||||
bool parallelized_function_p (tree);
|
||||
|
||||
#endif /* _TREE_FLOW_H */
|
||||
|
|
|
@ -127,143 +127,4 @@ make_pass_cleanup_cfg_post_optimizing (gcc::context *ctxt)
|
|||
return new pass_cleanup_cfg_post_optimizing (ctxt);
|
||||
}
|
||||
|
||||
/* IPA passes, compilation of earlier functions or inlining
|
||||
might have changed some properties, such as marked functions nothrow,
|
||||
pure, const or noreturn.
|
||||
Remove redundant edges and basic blocks, and create new ones if necessary.
|
||||
|
||||
This pass can't be executed as stand alone pass from pass manager, because
|
||||
in between inlining and this fixup the verify_flow_info would fail. */
|
||||
|
||||
unsigned int
|
||||
execute_fixup_cfg (void)
|
||||
{
|
||||
basic_block bb;
|
||||
gimple_stmt_iterator gsi;
|
||||
int todo = gimple_in_ssa_p (cfun) ? TODO_verify_ssa : 0;
|
||||
gcov_type count_scale;
|
||||
edge e;
|
||||
edge_iterator ei;
|
||||
|
||||
count_scale
|
||||
= GCOV_COMPUTE_SCALE (cgraph_get_node (current_function_decl)->count,
|
||||
ENTRY_BLOCK_PTR->count);
|
||||
|
||||
ENTRY_BLOCK_PTR->count = cgraph_get_node (current_function_decl)->count;
|
||||
EXIT_BLOCK_PTR->count = apply_scale (EXIT_BLOCK_PTR->count,
|
||||
count_scale);
|
||||
|
||||
FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
|
||||
e->count = apply_scale (e->count, count_scale);
|
||||
|
||||
FOR_EACH_BB (bb)
|
||||
{
|
||||
bb->count = apply_scale (bb->count, count_scale);
|
||||
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
|
||||
{
|
||||
gimple stmt = gsi_stmt (gsi);
|
||||
tree decl = is_gimple_call (stmt)
|
||||
? gimple_call_fndecl (stmt)
|
||||
: NULL;
|
||||
if (decl)
|
||||
{
|
||||
int flags = gimple_call_flags (stmt);
|
||||
if (flags & (ECF_CONST | ECF_PURE | ECF_LOOPING_CONST_OR_PURE))
|
||||
{
|
||||
if (gimple_purge_dead_abnormal_call_edges (bb))
|
||||
todo |= TODO_cleanup_cfg;
|
||||
|
||||
if (gimple_in_ssa_p (cfun))
|
||||
{
|
||||
todo |= TODO_update_ssa | TODO_cleanup_cfg;
|
||||
update_stmt (stmt);
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & ECF_NORETURN
|
||||
&& fixup_noreturn_call (stmt))
|
||||
todo |= TODO_cleanup_cfg;
|
||||
}
|
||||
|
||||
if (maybe_clean_eh_stmt (stmt)
|
||||
&& gimple_purge_dead_eh_edges (bb))
|
||||
todo |= TODO_cleanup_cfg;
|
||||
}
|
||||
|
||||
FOR_EACH_EDGE (e, ei, bb->succs)
|
||||
e->count = apply_scale (e->count, count_scale);
|
||||
|
||||
/* If we have a basic block with no successors that does not
|
||||
end with a control statement or a noreturn call end it with
|
||||
a call to __builtin_unreachable. This situation can occur
|
||||
when inlining a noreturn call that does in fact return. */
|
||||
if (EDGE_COUNT (bb->succs) == 0)
|
||||
{
|
||||
gimple stmt = last_stmt (bb);
|
||||
if (!stmt
|
||||
|| (!is_ctrl_stmt (stmt)
|
||||
&& (!is_gimple_call (stmt)
|
||||
|| (gimple_call_flags (stmt) & ECF_NORETURN) == 0)))
|
||||
{
|
||||
stmt = gimple_build_call
|
||||
(builtin_decl_implicit (BUILT_IN_UNREACHABLE), 0);
|
||||
gimple_stmt_iterator gsi = gsi_last_bb (bb);
|
||||
gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count_scale != REG_BR_PROB_BASE)
|
||||
compute_function_frequency ();
|
||||
|
||||
/* We just processed all calls. */
|
||||
if (cfun->gimple_df)
|
||||
vec_free (MODIFIED_NORETURN_CALLS (cfun));
|
||||
|
||||
/* Dump a textual representation of the flowgraph. */
|
||||
if (dump_file)
|
||||
gimple_dump_cfg (dump_file, dump_flags);
|
||||
|
||||
if (current_loops
|
||||
&& (todo & TODO_cleanup_cfg))
|
||||
loops_state_set (LOOPS_NEED_FIXUP);
|
||||
|
||||
return todo;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
const pass_data pass_data_fixup_cfg =
|
||||
{
|
||||
GIMPLE_PASS, /* type */
|
||||
"*free_cfg_annotations", /* name */
|
||||
OPTGROUP_NONE, /* optinfo_flags */
|
||||
false, /* has_gate */
|
||||
true, /* has_execute */
|
||||
TV_NONE, /* tv_id */
|
||||
PROP_cfg, /* properties_required */
|
||||
0, /* properties_provided */
|
||||
0, /* properties_destroyed */
|
||||
0, /* todo_flags_start */
|
||||
0, /* todo_flags_finish */
|
||||
};
|
||||
|
||||
class pass_fixup_cfg : public gimple_opt_pass
|
||||
{
|
||||
public:
|
||||
pass_fixup_cfg (gcc::context *ctxt)
|
||||
: gimple_opt_pass (pass_data_fixup_cfg, ctxt)
|
||||
{}
|
||||
|
||||
/* opt_pass methods: */
|
||||
opt_pass * clone () { return new pass_fixup_cfg (m_ctxt); }
|
||||
unsigned int execute () { return execute_fixup_cfg (); }
|
||||
|
||||
}; // class pass_fixup_cfg
|
||||
|
||||
} // anon namespace
|
||||
|
||||
gimple_opt_pass *
|
||||
make_pass_fixup_cfg (gcc::context *ctxt)
|
||||
{
|
||||
return new pass_fixup_cfg (ctxt);
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "langhooks.h"
|
||||
#include "tree-vectorizer.h"
|
||||
#include "tree-hasher.h"
|
||||
#include "tree-parloops.h"
|
||||
|
||||
/* This pass tries to distribute iterations of loops into several threads.
|
||||
The implementation is straightforward -- for each loop we test whether its
|
||||
|
@ -2240,4 +2241,62 @@ parallelize_loops (void)
|
|||
return changed;
|
||||
}
|
||||
|
||||
/* Parallelization. */
|
||||
|
||||
static bool
|
||||
gate_tree_parallelize_loops (void)
|
||||
{
|
||||
return flag_tree_parallelize_loops > 1;
|
||||
}
|
||||
|
||||
static unsigned
|
||||
tree_parallelize_loops (void)
|
||||
{
|
||||
if (number_of_loops (cfun) <= 1)
|
||||
return 0;
|
||||
|
||||
if (parallelize_loops ())
|
||||
return TODO_cleanup_cfg | TODO_rebuild_alias;
|
||||
return 0;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
const pass_data pass_data_parallelize_loops =
|
||||
{
|
||||
GIMPLE_PASS, /* type */
|
||||
"parloops", /* name */
|
||||
OPTGROUP_LOOP, /* optinfo_flags */
|
||||
true, /* has_gate */
|
||||
true, /* has_execute */
|
||||
TV_TREE_PARALLELIZE_LOOPS, /* tv_id */
|
||||
( PROP_cfg | PROP_ssa ), /* properties_required */
|
||||
0, /* properties_provided */
|
||||
0, /* properties_destroyed */
|
||||
0, /* todo_flags_start */
|
||||
TODO_verify_flow, /* todo_flags_finish */
|
||||
};
|
||||
|
||||
class pass_parallelize_loops : public gimple_opt_pass
|
||||
{
|
||||
public:
|
||||
pass_parallelize_loops (gcc::context *ctxt)
|
||||
: gimple_opt_pass (pass_data_parallelize_loops, ctxt)
|
||||
{}
|
||||
|
||||
/* opt_pass methods: */
|
||||
bool gate () { return gate_tree_parallelize_loops (); }
|
||||
unsigned int execute () { return tree_parallelize_loops (); }
|
||||
|
||||
}; // class pass_parallelize_loops
|
||||
|
||||
} // anon namespace
|
||||
|
||||
gimple_opt_pass *
|
||||
make_pass_parallelize_loops (gcc::context *ctxt)
|
||||
{
|
||||
return new pass_parallelize_loops (ctxt);
|
||||
}
|
||||
|
||||
|
||||
#include "gt-tree-parloops.h"
|
||||
|
|
26
gcc/tree-parloops.h
Normal file
26
gcc/tree-parloops.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
/* Header file for loop autoparallelization.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_TREE_PARLOOPS_H
|
||||
#define GCC_TREE_PARLOOPS_H
|
||||
|
||||
extern bool parallelized_function_p (tree);
|
||||
extern bool parallelize_loops (void);
|
||||
|
||||
#endif /* GCC_TREE_PARLOOPS_H */
|
|
@ -2563,3 +2563,60 @@ tree_predictive_commoning (void)
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Predictive commoning Pass. */
|
||||
|
||||
static unsigned
|
||||
run_tree_predictive_commoning (void)
|
||||
{
|
||||
if (!current_loops)
|
||||
return 0;
|
||||
|
||||
return tree_predictive_commoning ();
|
||||
}
|
||||
|
||||
static bool
|
||||
gate_tree_predictive_commoning (void)
|
||||
{
|
||||
return flag_predictive_commoning != 0;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
const pass_data pass_data_predcom =
|
||||
{
|
||||
GIMPLE_PASS, /* type */
|
||||
"pcom", /* name */
|
||||
OPTGROUP_LOOP, /* optinfo_flags */
|
||||
true, /* has_gate */
|
||||
true, /* has_execute */
|
||||
TV_PREDCOM, /* tv_id */
|
||||
PROP_cfg, /* properties_required */
|
||||
0, /* properties_provided */
|
||||
0, /* properties_destroyed */
|
||||
0, /* todo_flags_start */
|
||||
TODO_update_ssa_only_virtuals, /* todo_flags_finish */
|
||||
};
|
||||
|
||||
class pass_predcom : public gimple_opt_pass
|
||||
{
|
||||
public:
|
||||
pass_predcom (gcc::context *ctxt)
|
||||
: gimple_opt_pass (pass_data_predcom, ctxt)
|
||||
{}
|
||||
|
||||
/* opt_pass methods: */
|
||||
bool gate () { return gate_tree_predictive_commoning (); }
|
||||
unsigned int execute () { return run_tree_predictive_commoning (); }
|
||||
|
||||
}; // class pass_predcom
|
||||
|
||||
} // anon namespace
|
||||
|
||||
gimple_opt_pass *
|
||||
make_pass_predcom (gcc::context *ctxt)
|
||||
{
|
||||
return new pass_predcom (ctxt);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "ggc.h"
|
||||
#include "target.h"
|
||||
#include "expmed.h"
|
||||
#include "tree-ssa-address.h"
|
||||
|
||||
/* TODO -- handling of symbols (according to Richard Hendersons
|
||||
comments, http://gcc.gnu.org/ml/gcc-patches/2005-04/msg00949.html):
|
||||
|
@ -173,6 +174,13 @@ gen_addr_rtx (enum machine_mode address_mode,
|
|||
*addr = const0_rtx;
|
||||
}
|
||||
|
||||
/* Description of a memory address. */
|
||||
|
||||
struct mem_address
|
||||
{
|
||||
tree symbol, base, index, step, offset;
|
||||
};
|
||||
|
||||
/* Returns address for TARGET_MEM_REF with parameters given by ADDR
|
||||
in address space AS.
|
||||
If REALLY_EXPAND is false, just make fake registers instead
|
||||
|
@ -256,6 +264,17 @@ addr_for_mem_ref (struct mem_address *addr, addr_space_t as,
|
|||
return address;
|
||||
}
|
||||
|
||||
/* implement addr_for_mem_ref() directly from a tree, which avoids exporting
|
||||
the mem_address structure. */
|
||||
|
||||
rtx
|
||||
addr_for_mem_ref (tree exp, addr_space_t as, bool really_expand)
|
||||
{
|
||||
struct mem_address addr;
|
||||
get_address_description (exp, &addr);
|
||||
return addr_for_mem_ref (&addr, as, really_expand);
|
||||
}
|
||||
|
||||
/* Returns address of MEM_REF in TYPE. */
|
||||
|
||||
tree
|
||||
|
|
32
gcc/tree-ssa-address.h
Normal file
32
gcc/tree-ssa-address.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
/* Header file for memory address lowering and mode selection.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_TREE_SSA_ADDRESS_H
|
||||
#define GCC_TREE_SSA_ADDRESS_H
|
||||
|
||||
extern rtx addr_for_mem_ref (struct mem_address *, addr_space_t, bool);
|
||||
extern rtx addr_for_mem_ref (tree exp, addr_space_t as, bool really_expand);
|
||||
extern void get_address_description (tree, struct mem_address *);
|
||||
extern tree tree_mem_ref_addr (tree, tree);
|
||||
tree create_mem_ref (gimple_stmt_iterator *, tree,
|
||||
struct affine_tree_combination *, tree, tree, tree, bool);
|
||||
extern void copy_ref_info (tree, tree);
|
||||
tree maybe_fold_tmr (tree);
|
||||
|
||||
#endif /* GCC_TREE_SSA_ADDRESS_H */
|
|
@ -902,7 +902,6 @@ tree_ssa_dominator_optimize (void)
|
|||
|
||||
/* Free the value-handle array. */
|
||||
threadedge_finalize_values ();
|
||||
ssa_name_values.release ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -70,12 +70,16 @@ typedef struct _var_map
|
|||
|
||||
extern var_map init_var_map (int);
|
||||
extern void delete_var_map (var_map);
|
||||
extern void dump_var_map (FILE *, var_map);
|
||||
extern void debug (_var_map &ref);
|
||||
extern void debug (_var_map *ptr);
|
||||
extern int var_union (var_map, tree, tree);
|
||||
extern void partition_view_normal (var_map, bool);
|
||||
extern void partition_view_bitmap (var_map, bitmap, bool);
|
||||
extern void dump_scope_blocks (FILE *, int);
|
||||
extern void debug_scope_block (tree, int);
|
||||
extern void debug_scope_blocks (int);
|
||||
extern void remove_unused_locals (void);
|
||||
extern void dump_var_map (FILE *, var_map);
|
||||
extern void debug (_var_map &ref);
|
||||
extern void debug (_var_map *ptr);
|
||||
#ifdef ENABLE_CHECKING
|
||||
extern void register_ssa_partition_check (tree ssa_var);
|
||||
#endif
|
||||
|
@ -241,16 +245,15 @@ typedef struct tree_live_info_d
|
|||
} *tree_live_info_p;
|
||||
|
||||
|
||||
extern tree_live_info_p calculate_live_ranges (var_map);
|
||||
extern void calculate_live_on_exit (tree_live_info_p);
|
||||
extern void delete_tree_live_info (tree_live_info_p);
|
||||
|
||||
#define LIVEDUMP_ENTRY 0x01
|
||||
#define LIVEDUMP_EXIT 0x02
|
||||
#define LIVEDUMP_ALL (LIVEDUMP_ENTRY | LIVEDUMP_EXIT)
|
||||
extern void dump_live_info (FILE *, tree_live_info_p, int);
|
||||
extern void delete_tree_live_info (tree_live_info_p);
|
||||
extern void calculate_live_on_exit (tree_live_info_p);
|
||||
extern tree_live_info_p calculate_live_ranges (var_map);
|
||||
extern void debug (tree_live_info_d &ref);
|
||||
extern void debug (tree_live_info_d *ptr);
|
||||
extern void dump_live_info (FILE *, tree_live_info_p, int);
|
||||
|
||||
|
||||
/* Return TRUE if P is marked as a global in LIVE. */
|
||||
|
|
|
@ -134,61 +134,6 @@ make_pass_tree_loop_init (gcc::context *ctxt)
|
|||
return new pass_tree_loop_init (ctxt);
|
||||
}
|
||||
|
||||
/* Predictive commoning. */
|
||||
|
||||
static unsigned
|
||||
run_tree_predictive_commoning (void)
|
||||
{
|
||||
if (!current_loops)
|
||||
return 0;
|
||||
|
||||
return tree_predictive_commoning ();
|
||||
}
|
||||
|
||||
static bool
|
||||
gate_tree_predictive_commoning (void)
|
||||
{
|
||||
return flag_predictive_commoning != 0;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
const pass_data pass_data_predcom =
|
||||
{
|
||||
GIMPLE_PASS, /* type */
|
||||
"pcom", /* name */
|
||||
OPTGROUP_LOOP, /* optinfo_flags */
|
||||
true, /* has_gate */
|
||||
true, /* has_execute */
|
||||
TV_PREDCOM, /* tv_id */
|
||||
PROP_cfg, /* properties_required */
|
||||
0, /* properties_provided */
|
||||
0, /* properties_destroyed */
|
||||
0, /* todo_flags_start */
|
||||
TODO_update_ssa_only_virtuals, /* todo_flags_finish */
|
||||
};
|
||||
|
||||
class pass_predcom : public gimple_opt_pass
|
||||
{
|
||||
public:
|
||||
pass_predcom (gcc::context *ctxt)
|
||||
: gimple_opt_pass (pass_data_predcom, ctxt)
|
||||
{}
|
||||
|
||||
/* opt_pass methods: */
|
||||
bool gate () { return gate_tree_predictive_commoning (); }
|
||||
unsigned int execute () { return run_tree_predictive_commoning (); }
|
||||
|
||||
}; // class pass_predcom
|
||||
|
||||
} // anon namespace
|
||||
|
||||
gimple_opt_pass *
|
||||
make_pass_predcom (gcc::context *ctxt)
|
||||
{
|
||||
return new pass_predcom (ctxt);
|
||||
}
|
||||
|
||||
/* Loop autovectorization. */
|
||||
|
||||
static unsigned int
|
||||
|
@ -244,110 +189,6 @@ make_pass_vectorize (gcc::context *ctxt)
|
|||
return new pass_vectorize (ctxt);
|
||||
}
|
||||
|
||||
/* GRAPHITE optimizations. */
|
||||
|
||||
static unsigned int
|
||||
graphite_transforms (void)
|
||||
{
|
||||
if (!current_loops)
|
||||
return 0;
|
||||
|
||||
graphite_transform_loops ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool
|
||||
gate_graphite_transforms (void)
|
||||
{
|
||||
/* Enable -fgraphite pass if any one of the graphite optimization flags
|
||||
is turned on. */
|
||||
if (flag_loop_block
|
||||
|| flag_loop_interchange
|
||||
|| flag_loop_strip_mine
|
||||
|| flag_graphite_identity
|
||||
|| flag_loop_parallelize_all
|
||||
|| flag_loop_optimize_isl)
|
||||
flag_graphite = 1;
|
||||
|
||||
return flag_graphite != 0;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
const pass_data pass_data_graphite =
|
||||
{
|
||||
GIMPLE_PASS, /* type */
|
||||
"graphite0", /* name */
|
||||
OPTGROUP_LOOP, /* optinfo_flags */
|
||||
true, /* has_gate */
|
||||
false, /* has_execute */
|
||||
TV_GRAPHITE, /* tv_id */
|
||||
( PROP_cfg | PROP_ssa ), /* properties_required */
|
||||
0, /* properties_provided */
|
||||
0, /* properties_destroyed */
|
||||
0, /* todo_flags_start */
|
||||
0, /* todo_flags_finish */
|
||||
};
|
||||
|
||||
class pass_graphite : public gimple_opt_pass
|
||||
{
|
||||
public:
|
||||
pass_graphite (gcc::context *ctxt)
|
||||
: gimple_opt_pass (pass_data_graphite, ctxt)
|
||||
{}
|
||||
|
||||
/* opt_pass methods: */
|
||||
bool gate () { return gate_graphite_transforms (); }
|
||||
|
||||
}; // class pass_graphite
|
||||
|
||||
} // anon namespace
|
||||
|
||||
gimple_opt_pass *
|
||||
make_pass_graphite (gcc::context *ctxt)
|
||||
{
|
||||
return new pass_graphite (ctxt);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
const pass_data pass_data_graphite_transforms =
|
||||
{
|
||||
GIMPLE_PASS, /* type */
|
||||
"graphite", /* name */
|
||||
OPTGROUP_LOOP, /* optinfo_flags */
|
||||
true, /* has_gate */
|
||||
true, /* has_execute */
|
||||
TV_GRAPHITE_TRANSFORMS, /* tv_id */
|
||||
( PROP_cfg | PROP_ssa ), /* properties_required */
|
||||
0, /* properties_provided */
|
||||
0, /* properties_destroyed */
|
||||
0, /* todo_flags_start */
|
||||
0, /* todo_flags_finish */
|
||||
};
|
||||
|
||||
class pass_graphite_transforms : public gimple_opt_pass
|
||||
{
|
||||
public:
|
||||
pass_graphite_transforms (gcc::context *ctxt)
|
||||
: gimple_opt_pass (pass_data_graphite_transforms, ctxt)
|
||||
{}
|
||||
|
||||
/* opt_pass methods: */
|
||||
bool gate () { return gate_graphite_transforms (); }
|
||||
unsigned int execute () { return graphite_transforms (); }
|
||||
|
||||
}; // class pass_graphite_transforms
|
||||
|
||||
} // anon namespace
|
||||
|
||||
gimple_opt_pass *
|
||||
make_pass_graphite_transforms (gcc::context *ctxt)
|
||||
{
|
||||
return new pass_graphite_transforms (ctxt);
|
||||
}
|
||||
|
||||
/* Check the correctness of the data dependence analyzers. */
|
||||
|
||||
static unsigned int
|
||||
|
@ -501,63 +342,6 @@ make_pass_record_bounds (gcc::context *ctxt)
|
|||
return new pass_record_bounds (ctxt);
|
||||
}
|
||||
|
||||
/* Parallelization. */
|
||||
|
||||
static bool
|
||||
gate_tree_parallelize_loops (void)
|
||||
{
|
||||
return flag_tree_parallelize_loops > 1;
|
||||
}
|
||||
|
||||
static unsigned
|
||||
tree_parallelize_loops (void)
|
||||
{
|
||||
if (number_of_loops (cfun) <= 1)
|
||||
return 0;
|
||||
|
||||
if (parallelize_loops ())
|
||||
return TODO_cleanup_cfg | TODO_rebuild_alias;
|
||||
return 0;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
const pass_data pass_data_parallelize_loops =
|
||||
{
|
||||
GIMPLE_PASS, /* type */
|
||||
"parloops", /* name */
|
||||
OPTGROUP_LOOP, /* optinfo_flags */
|
||||
true, /* has_gate */
|
||||
true, /* has_execute */
|
||||
TV_TREE_PARALLELIZE_LOOPS, /* tv_id */
|
||||
( PROP_cfg | PROP_ssa ), /* properties_required */
|
||||
0, /* properties_provided */
|
||||
0, /* properties_destroyed */
|
||||
0, /* todo_flags_start */
|
||||
TODO_verify_flow, /* todo_flags_finish */
|
||||
};
|
||||
|
||||
class pass_parallelize_loops : public gimple_opt_pass
|
||||
{
|
||||
public:
|
||||
pass_parallelize_loops (gcc::context *ctxt)
|
||||
: gimple_opt_pass (pass_data_parallelize_loops, ctxt)
|
||||
{}
|
||||
|
||||
/* opt_pass methods: */
|
||||
bool gate () { return gate_tree_parallelize_loops (); }
|
||||
unsigned int execute () { return tree_parallelize_loops (); }
|
||||
|
||||
}; // class pass_parallelize_loops
|
||||
|
||||
} // anon namespace
|
||||
|
||||
gimple_opt_pass *
|
||||
make_pass_parallelize_loops (gcc::context *ctxt)
|
||||
{
|
||||
return new pass_parallelize_loops (ctxt);
|
||||
}
|
||||
|
||||
/* Induction variable optimizations. */
|
||||
|
||||
static unsigned int
|
||||
|
|
36
gcc/tree-ssa-threadedge.h
Normal file
36
gcc/tree-ssa-threadedge.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
/* Header file for SSA jump threading.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_TREE_SSA_THREADEDGE_H
|
||||
#define GCC_TREE_SSA_THREADEDGE_H
|
||||
|
||||
extern vec<tree> ssa_name_values;
|
||||
#define SSA_NAME_VALUE(x) \
|
||||
(SSA_NAME_VERSION (x) < ssa_name_values.length () \
|
||||
? ssa_name_values[SSA_NAME_VERSION (x)] \
|
||||
: NULL_TREE)
|
||||
extern void set_ssa_name_value (tree, tree);
|
||||
extern void threadedge_initialize_values (void);
|
||||
extern void threadedge_finalize_values (void);
|
||||
extern bool potentially_threadable_block (basic_block);
|
||||
extern void propagate_threaded_block_debug_into (basic_block, basic_block);
|
||||
extern void thread_across_edge (gimple, edge, bool,
|
||||
vec<tree> *, tree (*) (gimple, gimple));
|
||||
|
||||
#endif /* GCC_TREE_SSA_THREADEDGE_H */
|
|
@ -28,6 +28,8 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "tree-ssanames.h"
|
||||
#include "tree-ssa-dom.h"
|
||||
#include "tree-flow.h"
|
||||
#include "tree-ssa-threadedge.h"
|
||||
#include "tree-ssa-address.h"
|
||||
|
||||
/* Mapping for redirected edges. */
|
||||
struct _edge_var_map {
|
||||
|
|
|
@ -899,6 +899,7 @@ extern LOC vect_location;
|
|||
in tree-vect-loop-manip.c. */
|
||||
extern void slpeel_make_loop_iterate_ntimes (struct loop *, tree);
|
||||
extern bool slpeel_can_duplicate_loop_p (const struct loop *, const_edge);
|
||||
struct loop *slpeel_tree_duplicate_loop_to_edge_cfg (struct loop *, edge);
|
||||
extern void vect_loop_versioning (loop_vec_info, unsigned int, bool);
|
||||
extern void vect_do_peeling_for_loop_bound (loop_vec_info, tree *,
|
||||
unsigned int, bool);
|
||||
|
|
|
@ -4737,10 +4737,6 @@ extern unsigned int tree_decl_map_hash (const void *);
|
|||
#define tree_vec_map_hash tree_decl_map_hash
|
||||
#define tree_vec_map_marked_p tree_map_base_marked_p
|
||||
|
||||
/* In tree-ssa-address.c. */
|
||||
extern tree tree_mem_ref_addr (tree, tree);
|
||||
extern void copy_ref_info (tree, tree);
|
||||
|
||||
/* In tree-vrp.c */
|
||||
extern bool ssa_name_nonnegative_p (const_tree);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue