diff options
author | Andrew MacLeod <amacleod@redhat.com> | 2013-10-09 13:09:23 +0000 |
---|---|---|
committer | Andrew Macleod <amacleod@gcc.gnu.org> | 2013-10-09 13:09:23 +0000 |
commit | 713438778be52a0cb0533fad271c05481435b519 (patch) | |
tree | daafe0156356e7c30b23700b33e51ef2d3acc1a2 /gcc/tree-ssa-loop-im.c | |
parent | 826cacfe24c4643799d85f07b25d15a0d3b76bc0 (diff) | |
download | gcc-713438778be52a0cb0533fad271c05481435b519.zip gcc-713438778be52a0cb0533fad271c05481435b519.tar.gz gcc-713438778be52a0cb0533fad271c05481435b519.tar.bz2 |
tree-flow.h: Move some protoypes.
* tree-flow.h: Move some protoypes. Include new tree-ssa-loop.h.
(struct affine_iv, struct tree_niter_desc): Move to tree-ssa-loop.h.
(enum move_pos): Move to tree-ssa-loop-im.h
* cfgloop.h: Move some prototypes.
(gcov_type_to_double_int): relocate from tree-ssa-loop.niter.c.
* tree-flow-inline.h (loop_containing_stmt): Move to tree-ssa-loop.h.
* tree-ssa-loop.h: New File. Include other tree-ssa-loop-*.h files.
(struct affine_iv, struct tree_niter_desc): Relocate from tree-flow.h.
(loop_containing_stmt): Relocate from tree-flow-inline.h.
* tree-ssa-loop-ch.c: (do_while_loop_p): Make static.
* tree-ssa-loop-im.c (for_each_index): Move to tree-ssa-loop.c.
(enum move_pos): Relocate here.
(lsm_tmp_name_add, gen_lsm_tmp_name, get_lsm_tmp_name): Move to
tree-ssa-loop.c.
(execute_sm_if_changed_flag_set): Change get_lsm_tmp_name call.
(tree_ssa_loop_im, gate_tree_ssa_loop_im, pass_data_lim, make_pass_lim):
Relocate here from tree-ssa-loop.c.
* tree-ssa-loop-ivcanon.c (tree_num_loop_insns): Move to
tree-ssa-loop.c.
(loop_edge_to_cancel, unloop_loops): Make static.
(tree_ssa_loop_ivcanon, gate_tree_ssa_loop_ivcanon, pass_data_iv_canon,
make_pass_iv_canon): Relocate from tree-ssa-loop.c.
(tree_complete_unroll, gate_tree_complete_unroll,
pass_data_complete_unroll, make_pass_complete_unroll): Relocate here.
(tree_complete_unroll_inner, gate_tree_complete_unroll_inner,
pass_data_complete_unrolli, make_pass_complete_unrolli): Relocate here.
* tree-ssa-loop-ivopts.c: Remove local prototypes.
(stmt_invariant_in_loop_p): Remove unused function.
* tree-ssa-loop-ivopts.h: New file. Add prototypes.
* tree-ssa-loop-manip.h: New file. Add prototypes.
* tree-ssa-loop-niter.c (record_niter_bound): Move to cfgloop.c.
(gcov_type_to_double_int): Move to cfgloop.h.
(double_int_cmp, bound_index,
estimate_numbers_of_iterations_loop): Make static.
(estimated_loop_iterations): Factor out get_estimated_loop_iterations.
(max_loop_iterations): Factor out get_max_loop_iterations.
(estimated_loop_iterations_int, max_stmt_executions_int): Move to
cfgloop.c.
* tree-ssa-loop-niter.h: New file. Add prototypes.
* tree-ssa-loop-prefetch.c (tree_ssa_loop_prefetch,
gate_tree_ssa_loop_prefetch, pass_data_loop_prefetch,
make_pass_loop_prefetch): Relocate from tree-ssa-loop.c.
* tree-ssa-loop-unswitch.c (tree_ssa_loop_unswitch,
gate_tree_ssa_loop_unswitch, pass_data_tree_unswitch,
make_pass_tree_unswitch): Relocate from tree-ssa-loop.c.
* tree-ssa-loop.c (tree_ssa_loop_im, gate_tree_ssa_loop_im,
pass_data_lim, make_pass_lim): Move to tree-ssa-loop-im.c.
(tree_ssa_loop_unswitch, gate_tree_ssa_loop_unswitch,
pass_data_tree_unswitch, make_pass_tree_unswitch): Move.
(tree_ssa_loop_ivcanon, gate_tree_ssa_loop_ivcanon, pass_data_iv_canon,
make_pass_iv_canon, tree_complete_unroll, gate_tree_complete_unroll,
pass_data_complete_unroll, make_pass_complete_unroll,
tree_complete_unroll_inner, gate_tree_complete_unroll_inner,
pass_data_complete_unrolli, make_pass_complete_unrolli): Move to
tree-ssa-loop-ivcanon.c.
(tree_ssa_loop_prefetch, gate_tree_ssa_loop_prefetch,
pass_data_loop_prefetch, make_pass_loop_prefetch): Move to
tree-ssa-loop-prefetch.c.
(for_each_index, lsm_tmp_name_add, gen_lsm_tmp_name): Relocate from
tree-ssa-loop-im.c.
(get_lsm_tmp_name): Relocate and add suffix parameter.
(tree_num_loop_insns): Relocate from tree-ssa-ivcanon.c.
* tree-scalar-evolution.h (simple_iv): Don't use affive_iv typedef.
* cfgloop.c (record_niter_bound, estimated_loop_iterations_int,
max_stmt_executions_int): Move from tree-ssa-loop-niter.c.
(get_estimated_loop_iterations): Factor out accessor from
estimated_loop_iterations in tree-ssa-loop-niter.c.
(get_max_loop_iterations): Factor out accessor from _max_loop_iterations
in tree-ssa-niter.c.
* loop-unroll.c (decide_unroll_constant_iterations,
decide_unroll_runtime_iterations, decide_peel_simple,
decide_unroll_stupid): Use new get_* accessors.
From-SVN: r203317
Diffstat (limited to 'gcc/tree-ssa-loop-im.c')
-rw-r--r-- | gcc/tree-ssa-loop-im.c | 275 |
1 files changed, 67 insertions, 208 deletions
diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c index fc25528..84f50cd 100644 --- a/gcc/tree-ssa-loop-im.c +++ b/gcc/tree-ssa-loop-im.c @@ -242,98 +242,16 @@ clear_lim_data (gimple stmt) *p = NULL; } -/* Calls CBCK for each index in memory reference ADDR_P. There are two - kinds situations handled; in each of these cases, the memory reference - and DATA are passed to the callback: - Access to an array: ARRAY_{RANGE_}REF (base, index). In this case we also - pass the pointer to the index to the callback. - - Pointer dereference: INDIRECT_REF (addr). In this case we also pass the - pointer to addr to the callback. - - If the callback returns false, the whole search stops and false is returned. - Otherwise the function returns true after traversing through the whole - reference *ADDR_P. */ - -bool -for_each_index (tree *addr_p, bool (*cbck) (tree, tree *, void *), void *data) -{ - tree *nxt, *idx; - - for (; ; addr_p = nxt) - { - switch (TREE_CODE (*addr_p)) - { - case SSA_NAME: - return cbck (*addr_p, addr_p, data); - - case MEM_REF: - nxt = &TREE_OPERAND (*addr_p, 0); - return cbck (*addr_p, nxt, data); - - case BIT_FIELD_REF: - case VIEW_CONVERT_EXPR: - case REALPART_EXPR: - case IMAGPART_EXPR: - nxt = &TREE_OPERAND (*addr_p, 0); - break; - - case COMPONENT_REF: - /* If the component has varying offset, it behaves like index - as well. */ - idx = &TREE_OPERAND (*addr_p, 2); - if (*idx - && !cbck (*addr_p, idx, data)) - return false; - - nxt = &TREE_OPERAND (*addr_p, 0); - break; +/* The possibilities of statement movement. */ +enum move_pos + { + MOVE_IMPOSSIBLE, /* No movement -- side effect expression. */ + MOVE_PRESERVE_EXECUTION, /* Must not cause the non-executed statement + become executed -- memory accesses, ... */ + MOVE_POSSIBLE /* Unlimited movement. */ + }; - case ARRAY_REF: - case ARRAY_RANGE_REF: - nxt = &TREE_OPERAND (*addr_p, 0); - if (!cbck (*addr_p, &TREE_OPERAND (*addr_p, 1), data)) - return false; - break; - - case VAR_DECL: - case PARM_DECL: - case CONST_DECL: - case STRING_CST: - case RESULT_DECL: - case VECTOR_CST: - case COMPLEX_CST: - case INTEGER_CST: - case REAL_CST: - case FIXED_CST: - case CONSTRUCTOR: - return true; - - case ADDR_EXPR: - gcc_assert (is_gimple_min_invariant (*addr_p)); - return true; - - case TARGET_MEM_REF: - idx = &TMR_BASE (*addr_p); - if (*idx - && !cbck (*addr_p, idx, data)) - return false; - idx = &TMR_INDEX (*addr_p); - if (*idx - && !cbck (*addr_p, idx, data)) - return false; - idx = &TMR_INDEX2 (*addr_p); - if (*idx - && !cbck (*addr_p, idx, data)) - return false; - return true; - - default: - gcc_unreachable (); - } - } -} /* If it is possible to hoist the statement STMT unconditionally, returns MOVE_POSSIBLE. @@ -1741,122 +1659,6 @@ first_mem_ref_loc (struct loop *loop, mem_ref_p ref) return locp; } -/* The name and the length of the currently generated variable - for lsm. */ -#define MAX_LSM_NAME_LENGTH 40 -static char lsm_tmp_name[MAX_LSM_NAME_LENGTH + 1]; -static int lsm_tmp_name_length; - -/* Adds S to lsm_tmp_name. */ - -static void -lsm_tmp_name_add (const char *s) -{ - int l = strlen (s) + lsm_tmp_name_length; - if (l > MAX_LSM_NAME_LENGTH) - return; - - strcpy (lsm_tmp_name + lsm_tmp_name_length, s); - lsm_tmp_name_length = l; -} - -/* Stores the name for temporary variable that replaces REF to - lsm_tmp_name. */ - -static void -gen_lsm_tmp_name (tree ref) -{ - const char *name; - - switch (TREE_CODE (ref)) - { - case MEM_REF: - case TARGET_MEM_REF: - gen_lsm_tmp_name (TREE_OPERAND (ref, 0)); - lsm_tmp_name_add ("_"); - break; - - case ADDR_EXPR: - gen_lsm_tmp_name (TREE_OPERAND (ref, 0)); - break; - - case BIT_FIELD_REF: - case VIEW_CONVERT_EXPR: - case ARRAY_RANGE_REF: - gen_lsm_tmp_name (TREE_OPERAND (ref, 0)); - break; - - case REALPART_EXPR: - gen_lsm_tmp_name (TREE_OPERAND (ref, 0)); - lsm_tmp_name_add ("_RE"); - break; - - case IMAGPART_EXPR: - gen_lsm_tmp_name (TREE_OPERAND (ref, 0)); - lsm_tmp_name_add ("_IM"); - break; - - case COMPONENT_REF: - gen_lsm_tmp_name (TREE_OPERAND (ref, 0)); - lsm_tmp_name_add ("_"); - name = get_name (TREE_OPERAND (ref, 1)); - if (!name) - name = "F"; - lsm_tmp_name_add (name); - break; - - case ARRAY_REF: - gen_lsm_tmp_name (TREE_OPERAND (ref, 0)); - lsm_tmp_name_add ("_I"); - break; - - case SSA_NAME: - case VAR_DECL: - case PARM_DECL: - name = get_name (ref); - if (!name) - name = "D"; - lsm_tmp_name_add (name); - break; - - case STRING_CST: - lsm_tmp_name_add ("S"); - break; - - case RESULT_DECL: - lsm_tmp_name_add ("R"); - break; - - case INTEGER_CST: - /* Nothing. */ - break; - - default: - gcc_unreachable (); - } -} - -/* Determines name for temporary variable that replaces REF. - The name is accumulated into the lsm_tmp_name variable. - N is added to the name of the temporary. */ - -char * -get_lsm_tmp_name (tree ref, unsigned n) -{ - char ns[2]; - - lsm_tmp_name_length = 0; - gen_lsm_tmp_name (ref); - lsm_tmp_name_add ("_lsm"); - if (n < 10) - { - ns[0] = '0' + n; - ns[1] = 0; - lsm_tmp_name_add (ns); - } - return lsm_tmp_name; -} - struct prev_flag_edges { /* Edge to insert new flag comparison code. */ edge append_cond_position; @@ -2026,8 +1828,7 @@ static tree execute_sm_if_changed_flag_set (struct loop *loop, mem_ref_p ref) { tree flag; - char *str = get_lsm_tmp_name (ref->mem.ref, ~0); - lsm_tmp_name_add ("_flag"); + char *str = get_lsm_tmp_name (ref->mem.ref, ~0, "_flag"); flag = create_tmp_reg (boolean_type_node, str); for_all_locs_in_loop (loop, ref, sm_set_flag_if_changed (flag)); return flag; @@ -2639,3 +2440,61 @@ tree_ssa_lim (void) return todo; } + +/* Loop invariant motion pass. */ + +static unsigned int +tree_ssa_loop_im (void) +{ + if (number_of_loops (cfun) <= 1) + return 0; + + return tree_ssa_lim (); +} + +static bool +gate_tree_ssa_loop_im (void) +{ + return flag_tree_loop_im != 0; +} + +namespace { + +const pass_data pass_data_lim = +{ + GIMPLE_PASS, /* type */ + "lim", /* name */ + OPTGROUP_LOOP, /* optinfo_flags */ + true, /* has_gate */ + true, /* has_execute */ + TV_LIM, /* tv_id */ + PROP_cfg, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ +}; + +class pass_lim : public gimple_opt_pass +{ +public: + pass_lim (gcc::context *ctxt) + : gimple_opt_pass (pass_data_lim, ctxt) + {} + + /* opt_pass methods: */ + opt_pass * clone () { return new pass_lim (m_ctxt); } + bool gate () { return gate_tree_ssa_loop_im (); } + unsigned int execute () { return tree_ssa_loop_im (); } + +}; // class pass_lim + +} // anon namespace + +gimple_opt_pass * +make_pass_lim (gcc::context *ctxt) +{ + return new pass_lim (ctxt); +} + + |