X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Ftree-predcom.c;h=de147e7ec96269d49d4909ec96b27366afe9098b;hb=72350d7baa0fbcf2fcc4aa82bc7d228a7f38734d;hp=5d8bf4d27042eccf106e0e6f97b0b9030e93cb0b;hpb=286fa50886ae02104bc82d300ec2379b478f917e;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/tree-predcom.c b/gcc/tree-predcom.c index 5d8bf4d2704..de147e7ec96 100644 --- a/gcc/tree-predcom.c +++ b/gcc/tree-predcom.c @@ -1,18 +1,19 @@ /* Predictive commoning. - Copyright (C) 2005, 2007, 2008, 2009 Free Software Foundation, Inc. - + Copyright (C) 2005, 2007, 2008, 2009, 2010 + 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 . */ @@ -29,7 +30,7 @@ along with GCC; see the file COPYING3. If not see and if needed, we could also take register pressure into account. Let us demonstrate what is done on an example: - + for (i = 0; i < 100; i++) { a[i+2] = a[i] + a[i+1]; @@ -63,7 +64,7 @@ along with GCC; see the file COPYING3. If not see making the further transformations simpler. Also, the shorter chains need the same number of registers, but may require lower unrolling factor in order to get rid of the copies on the loop latch. - + In our example, we get the following chains (the chain for c is invalid). a[i]{read,+0}, a[i+1]{read,-1}, a[i+2]{write,-2} @@ -76,7 +77,7 @@ along with GCC; see the file COPYING3. If not see with the smallest positive distance to the read. Then, we remove the references that are not used in any of these chains, discard the empty groups, and propagate all the links so that they point to the - single root reference of the chain (adjusting their distance + single root reference of the chain (adjusting their distance appropriately). Some extra care needs to be taken for references with step 0. In our example (the numbers indicate the distance of the reuse), @@ -132,7 +133,7 @@ along with GCC; see the file COPYING3. If not see times. The stores to RN (R0) in the copies of the loop body are periodically replaced with R0, R1, ... (R1, R2, ...), so that they can be coalesced and the copies can be eliminated. - + TODO -- copy propagation and other optimizations may change the live ranges of the temporary registers and prevent them from being coalesced; this may increase the register pressure. @@ -197,7 +198,8 @@ along with GCC; see the file COPYING3. If not see #include "tree-scalar-evolution.h" #include "tree-chrec.h" #include "params.h" -#include "diagnostic.h" +#include "tree-pretty-print.h" +#include "gimple-pretty-print.h" #include "tree-pass.h" #include "tree-affine.h" #include "tree-inline.h" @@ -206,7 +208,7 @@ along with GCC; see the file COPYING3. If not see references. */ #define MAX_DISTANCE (target_avail_regs < 16 ? 4 : 8) - + /* Data references (or phi nodes that carry data reference values across loop iterations). */ @@ -704,7 +706,7 @@ split_data_refs_to_components (struct loop *loop, struct component *comp_list = NULL, *comp; dref dataref; basic_block last_always_executed = last_always_executed_block (loop); - + for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++) { if (!DR_REF (dr)) @@ -754,7 +756,7 @@ split_data_refs_to_components (struct loop *loop, && (ia == bad || ib == bad || !determine_offset (dra, drb, &dummy_off))) continue; - + merge_comps (comp_father, comp_size, ia, ib); } @@ -808,7 +810,7 @@ end: /* Returns true if the component COMP satisfies the conditions described in 2) at the beginning of this file. LOOP is the current loop. */ - + static bool suitable_component_p (struct loop *loop, struct component *comp) { @@ -859,7 +861,7 @@ suitable_component_p (struct loop *loop, struct component *comp) return true; } - + /* Check the conditions on references inside each of components COMPS, and remove the unsuitable components from the list. The new list of components is returned. The conditions are described in 2) at @@ -1180,6 +1182,7 @@ determine_roots_comp (struct loop *loop, unsigned i; dref a; chain_p chain = NULL; + double_int last_ofs = double_int_zero; /* Invariants are handled specially. */ if (comp->comp_step == RS_INVARIANT) @@ -1194,13 +1197,20 @@ determine_roots_comp (struct loop *loop, for (i = 0; VEC_iterate (dref, comp->refs, i, a); i++) { - if (!chain || !DR_IS_READ (a->ref)) + if (!chain || !DR_IS_READ (a->ref) + || double_int_ucmp (uhwi_to_double_int (MAX_DISTANCE), + double_int_add (a->offset, + double_int_neg (last_ofs))) <= 0) { if (nontrivial_chain_p (chain)) - VEC_safe_push (chain_p, heap, *chains, chain); + { + add_looparound_copies (loop, chain); + VEC_safe_push (chain_p, heap, *chains, chain); + } else release_chain (chain); chain = make_rooted_chain (a); + last_ofs = a->offset; continue; } @@ -1255,7 +1265,7 @@ replace_ref_with (gimple stmt, tree new_tree, bool set, bool in_lhs) gsi_insert_before (&bsi, new_stmt, GSI_NEW_STMT); return; } - + /* Since the reference is of gimple_reg type, it should only appear as lhs or rhs of modify statement. */ gcc_assert (is_gimple_assign (stmt)); @@ -1275,7 +1285,7 @@ replace_ref_with (gimple stmt, tree new_tree, bool set, bool in_lhs) if (in_lhs) { /* We have statement - + OLD = VAL If OLD is a memory reference, then VAL is gimple_val, and we transform @@ -1284,7 +1294,7 @@ replace_ref_with (gimple stmt, tree new_tree, bool set, bool in_lhs) OLD = VAL NEW = VAL - Otherwise, we are replacing a combination chain, + Otherwise, we are replacing a combination chain, VAL is the expression that performs the combination, and OLD is an SSA name. In this case, we transform the assignment to @@ -1338,9 +1348,11 @@ ref_at_iteration (struct loop *loop, tree ref, int iter) else if (!INDIRECT_REF_P (ref)) return unshare_expr (ref); - if (TREE_CODE (ref) == INDIRECT_REF) + if (INDIRECT_REF_P (ref)) { - ret = build1 (INDIRECT_REF, TREE_TYPE (ref), NULL_TREE); + /* Take care for INDIRECT_REF and MISALIGNED_INDIRECT_REF at + the same time. */ + ret = copy_node (ref); idx = TREE_OPERAND (ref, 0); idx_p = &TREE_OPERAND (ret, 0); } @@ -1449,13 +1461,9 @@ static tree predcom_tmp_var (tree ref, unsigned i, bitmap tmp_vars) { tree type = TREE_TYPE (ref); - tree var = create_tmp_var (type, get_lsm_tmp_name (ref, i)); - /* We never access the components of the temporary variable in predictive commoning. */ - if (TREE_CODE (type) == COMPLEX_TYPE - || TREE_CODE (type) == VECTOR_TYPE) - DECL_GIMPLE_REG_P (var) = 1; + tree var = create_tmp_reg (type, get_lsm_tmp_name (ref, i)); add_referenced_var (var); bitmap_set_bit (tmp_vars, DECL_UID (var)); @@ -1496,7 +1504,7 @@ initialize_root_vars (struct loop *loop, chain_p chain, bitmap tmp_vars) } if (reuse_first) VEC_quick_push (tree, chain->vars, VEC_index (tree, chain->vars, 0)); - + for (i = 0; VEC_iterate (tree, chain->vars, i, var); i++) VEC_replace (tree, chain->vars, i, make_ssa_name (var, NULL)); @@ -1512,8 +1520,8 @@ initialize_root_vars (struct loop *loop, chain_p chain, bitmap tmp_vars) phi = create_phi_node (var, loop->header); SSA_NAME_DEF_STMT (var) = phi; - add_phi_arg (phi, init, entry); - add_phi_arg (phi, next, latch); + add_phi_arg (phi, init, entry, UNKNOWN_LOCATION); + add_phi_arg (phi, next, latch, UNKNOWN_LOCATION); } } @@ -1561,12 +1569,12 @@ initialize_root_vars_lm (struct loop *loop, dref root, bool written, VEC_quick_push (tree, *vars, var); if (written) VEC_quick_push (tree, *vars, VEC_index (tree, *vars, 0)); - + for (i = 0; VEC_iterate (tree, *vars, i, var); i++) VEC_replace (tree, *vars, i, make_ssa_name (var, NULL)); var = VEC_index (tree, *vars, 0); - + init = force_gimple_operand (init, &stmts, written, NULL_TREE); if (stmts) gsi_insert_seq_on_edge_immediate (entry, stmts); @@ -1576,8 +1584,8 @@ initialize_root_vars_lm (struct loop *loop, dref root, bool written, next = VEC_index (tree, *vars, 1); phi = create_phi_node (var, loop->header); SSA_NAME_DEF_STMT (var) = phi; - add_phi_arg (phi, init, entry); - add_phi_arg (phi, next, latch); + add_phi_arg (phi, init, entry, UNKNOWN_LOCATION); + add_phi_arg (phi, next, latch, UNKNOWN_LOCATION); } else { @@ -1604,7 +1612,7 @@ execute_load_motion (struct loop *loop, chain_p chain, bitmap tmp_vars) for (i = 0; VEC_iterate (dref, chain->refs, i, a); i++) if (!DR_IS_READ (a->ref)) n_writes++; - + /* If there are no reads in the loop, there is nothing to do. */ if (n_writes == VEC_length (dref, chain->refs)) return; @@ -1630,7 +1638,7 @@ execute_load_motion (struct loop *loop, chain_p chain, bitmap tmp_vars) else ridx = 1; } - + replace_ref_with (a->stmt, VEC_index (tree, vars, ridx), !is_read, !is_read); } @@ -1700,7 +1708,7 @@ remove_stmt (gimple stmt) while (1) { gimple_stmt_iterator bsi; - + bsi = gsi_for_stmt (stmt); name = gimple_assign_lhs (stmt); @@ -1804,7 +1812,7 @@ execute_pred_commoning (struct loop *loop, VEC (chain_p, heap) *chains, else execute_pred_commoning_chain (loop, chain, tmp_vars); } - + update_ssa (TODO_update_ssa_only_virtuals); } @@ -1879,7 +1887,6 @@ base_names_in_chain_on (struct loop *loop, tree name, tree var) { gimple stmt, phi; imm_use_iterator iter; - edge e; SSA_NAME_VAR (name) = var; @@ -1898,11 +1905,6 @@ base_names_in_chain_on (struct loop *loop, tree name, tree var) if (!phi) return; - if (gimple_bb (phi) == loop->header) - e = loop_latch_edge (loop); - else - e = single_pred_edge (gimple_bb (stmt)); - name = PHI_RESULT (phi); SSA_NAME_VAR (name) = var; } @@ -2204,12 +2206,12 @@ reassociate_to_the_same_stmt (tree name1, tree name2) /* Insert the new statement combining NAME1 and NAME2 before S1, and combine it with the rhs of S1. */ - var = create_tmp_var (type, "predreastmp"); + var = create_tmp_reg (type, "predreastmp"); add_referenced_var (var); new_name = make_ssa_name (var, NULL); new_stmt = gimple_build_assign_with_ops (code, new_name, name1, name2); - var = create_tmp_var (type, "predreastmp"); + var = create_tmp_reg (type, "predreastmp"); add_referenced_var (var); tmp_name = make_ssa_name (var, NULL); @@ -2267,7 +2269,7 @@ combine_chains (chain_p ch1, chain_p ch2) tree rslt_type = NULL_TREE; if (ch1 == ch2) - return false; + return NULL; if (ch1->length != ch2->length) return NULL; @@ -2400,7 +2402,7 @@ prepare_initializers_chain (struct loop *loop, chain_p chain) init = ref_at_iteration (loop, DR_REF (dr), (int) i - n); if (!init) return false; - + if (!chain->all_always_accessed && tree_could_trap_p (init)) return false; @@ -2522,7 +2524,7 @@ tree_predictive_commoning_loop (struct loop *loop) dta.chains = chains; dta.tmp_vars = tmp_vars; - + update_ssa (TODO_update_ssa_only_virtuals); /* Cfg manipulations performed in tree_transform_and_unroll_loop before