diff options
author | rakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-12-14 02:05:20 +0000 |
---|---|---|
committer | rakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-12-14 02:05:20 +0000 |
commit | d3610beab162bbb9b18ffd643cd412dac23b6da3 (patch) | |
tree | 33e4fecfec131da30950f9a5e548ab0f2c428746 /gcc/tree-ssa-address.c | |
parent | 4cbb97104ed0bc23c27f67354fa426a8b118fec3 (diff) | |
download | gcc-d3610beab162bbb9b18ffd643cd412dac23b6da3.tar.gz |
* tree-ssa-loop-ivopts.c: Include tree-affine.h.
(divide): Removed.
(constant_multiple_of): Fix order of operators for division.
(aff_combination_const, aff_combination_elt, aff_combination_scale,
aff_combination_add_elt, aff_combination_add, aff_combination_convert,
tree_to_aff_combination, add_elt_to_tree, unshare_aff_combination,
aff_combination_to_tree): Moved to tree-affine.c and made to work with
double_int coefficients.
(get_computation_aff, get_computation_at): Work with double_int
coefficients.
(get_computation_cost_at): Do not use divide.
(rewrite_use_nonlinear_expr, rewrite_use_address, rewrite_use_compare):
Assert that expressing the computation did not fail.
* tree-ssa-address.c: Include tree-affine.h.
(add_to_parts, most_expensive_mult_to_index, addr_to_parts,
create_mem_ref): Work with double_int coefficients.
* tree-affine.c: New file.
* tree-affine.h: New file.
* tree-flow.h (struct affine_tree_combination): Removed.
* Makefile.in (tree-affine.o): Add.
(tree-ssa-address.o, tree-ssa-loop-ivopts.o): Add tree-affine.h
dependency.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@119854 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-address.c')
-rw-r--r-- | gcc/tree-ssa-address.c | 94 |
1 files changed, 56 insertions, 38 deletions
diff --git a/gcc/tree-ssa-address.c b/gcc/tree-ssa-address.c index c3394498964..eb39370f0d8 100644 --- a/gcc/tree-ssa-address.c +++ b/gcc/tree-ssa-address.c @@ -42,6 +42,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA #include "recog.h" #include "expr.h" #include "ggc.h" +#include "tree-affine.h" /* TODO -- handling of symbols (according to Richard Hendersons comments, http://gcc.gnu.org/ml/gcc-patches/2005-04/msg00949.html): @@ -346,25 +347,20 @@ fixed_address_object_p (tree obj) construct. */ static void -add_to_parts (struct mem_address *parts, tree type, tree elt, - unsigned HOST_WIDE_INT coef) +add_to_parts (struct mem_address *parts, tree type, tree elt) { + tree elt_core = elt; + STRIP_NOPS (elt_core); + /* Check if this is a symbol. */ if (!parts->symbol - && coef == 1 - && TREE_CODE (elt) == ADDR_EXPR - && fixed_address_object_p (TREE_OPERAND (elt, 0))) + && TREE_CODE (elt_core) == ADDR_EXPR + && fixed_address_object_p (TREE_OPERAND (elt_core, 0))) { - parts->symbol = TREE_OPERAND (elt, 0); + parts->symbol = TREE_OPERAND (elt_core, 0); return; } - if (coef != 1) - elt = fold_build2 (MULT_EXPR, type, fold_convert (type, elt), - build_int_cst_type (type, coef)); - else - elt = fold_convert (type, elt); - if (!parts->base) { parts->base = elt; @@ -388,52 +384,69 @@ add_to_parts (struct mem_address *parts, tree type, tree elt, static void most_expensive_mult_to_index (struct mem_address *parts, tree type, - struct affine_tree_combination *addr) + aff_tree *addr) { - unsigned HOST_WIDE_INT best_mult = 0; + HOST_WIDE_INT coef; + double_int best_mult, amult, amult_neg; unsigned best_mult_cost = 0, acost; tree mult_elt = NULL_TREE, elt; unsigned i, j; + enum tree_code op_code; + best_mult = double_int_zero; for (i = 0; i < addr->n; i++) { + if (!double_int_fits_in_shwi_p (addr->elts[i].coef)) + continue; + /* FIXME: Should use the correct memory mode rather than Pmode. */ - if (addr->coefs[i] == 1 - || !multiplier_allowed_in_address_p (addr->coefs[i], Pmode)) + + coef = double_int_to_shwi (addr->elts[i].coef); + if (coef == 1 + || !multiplier_allowed_in_address_p (coef, Pmode)) continue; - - acost = multiply_by_cost (addr->coefs[i], Pmode); + + acost = multiply_by_cost (coef, Pmode); if (acost > best_mult_cost) { best_mult_cost = acost; - best_mult = addr->coefs[i]; + best_mult = addr->elts[i].coef; } } - if (!best_mult) + if (!best_mult_cost) return; + /* Collect elements multiplied by best_mult. */ for (i = j = 0; i < addr->n; i++) { - if (addr->coefs[i] != best_mult) + amult = addr->elts[i].coef; + amult_neg = double_int_ext_for_comb (double_int_neg (amult), addr); + + if (double_int_equal_p (amult, best_mult)) + op_code = PLUS_EXPR; + else if (double_int_equal_p (amult_neg, best_mult)) + op_code = MINUS_EXPR; + else { - addr->coefs[j] = addr->coefs[i]; addr->elts[j] = addr->elts[i]; j++; continue; } - - elt = fold_convert (type, addr->elts[i]); - if (!mult_elt) + + elt = fold_convert (type, addr->elts[i].val); + if (mult_elt) + mult_elt = fold_build2 (op_code, type, mult_elt, elt); + else if (op_code == PLUS_EXPR) mult_elt = elt; else - mult_elt = fold_build2 (PLUS_EXPR, type, mult_elt, elt); + mult_elt = fold_build1 (NEGATE_EXPR, type, elt); } addr->n = j; - + parts->index = mult_elt; - parts->step = build_int_cst_type (type, best_mult); + parts->step = double_int_to_tree (type, best_mult); } /* Splits address ADDR into PARTS. @@ -442,13 +455,13 @@ most_expensive_mult_to_index (struct mem_address *parts, tree type, to PARTS. Some architectures do not support anything but single register in address, possibly with a small integer offset; while create_mem_ref will simplify the address to an acceptable shape - later, it would be a small bit more efficient to know that asking - for complicated addressing modes is useless. */ + later, it would be more efficient to know that asking for complicated + addressing modes is useless. */ static void -addr_to_parts (struct affine_tree_combination *addr, tree type, - struct mem_address *parts) +addr_to_parts (aff_tree *addr, tree type, struct mem_address *parts) { + tree part; unsigned i; parts->symbol = NULL_TREE; @@ -456,8 +469,8 @@ addr_to_parts (struct affine_tree_combination *addr, tree type, parts->index = NULL_TREE; parts->step = NULL_TREE; - if (addr->offset) - parts->offset = build_int_cst_type (type, addr->offset); + if (!double_int_zero_p (addr->offset)) + parts->offset = double_int_to_tree (type, addr->offset); else parts->offset = NULL_TREE; @@ -467,9 +480,15 @@ addr_to_parts (struct affine_tree_combination *addr, tree type, /* Then try to process the remaining elements. */ for (i = 0; i < addr->n; i++) - add_to_parts (parts, type, addr->elts[i], addr->coefs[i]); + { + part = fold_convert (type, addr->elts[i].val); + if (!double_int_one_p (addr->elts[i].coef)) + part = fold_build2 (MULT_EXPR, type, part, + double_int_to_tree (type, addr->elts[i].coef)); + add_to_parts (parts, type, part); + } if (addr->rest) - add_to_parts (parts, type, addr->rest, 1); + add_to_parts (parts, type, addr->rest); } /* Force the PARTS to register. */ @@ -490,8 +509,7 @@ gimplify_mem_ref_parts (block_stmt_iterator *bsi, struct mem_address *parts) of created memory reference. */ tree -create_mem_ref (block_stmt_iterator *bsi, tree type, - struct affine_tree_combination *addr) +create_mem_ref (block_stmt_iterator *bsi, tree type, aff_tree *addr) { tree mem_ref, tmp; tree addr_type = build_pointer_type (type); |