/* Induction variable optimizations.
- Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of GCC.
#include "params.h"
#include "langhooks.h"
#include "tree-affine.h"
+#include "target.h"
/* The infinite cost. */
#define INFTY 10000000
contains_abnormal_ssa_name_p (tree expr)
{
enum tree_code code;
- enum tree_code_class class;
+ enum tree_code_class codeclass;
if (!expr)
return false;
code = TREE_CODE (expr);
- class = TREE_CODE_CLASS (code);
+ codeclass = TREE_CODE_CLASS (code);
if (code == SSA_NAME)
return SSA_NAME_OCCURS_IN_ABNORMAL_PHI (expr) != 0;
idx_contains_abnormal_ssa_name_p,
NULL);
- switch (class)
+ switch (codeclass)
{
case tcc_binary:
case tcc_comparison:
*pointer_map_insert (data->niters, exit) = niter;
}
else
- niter = *slot;
+ niter = (tree) *slot;
return niter;
}
determine_base_object (tree expr)
{
enum tree_code code = TREE_CODE (expr);
- tree base, obj, op0, op1;
+ tree base, obj;
/* If this is a pointer casted to any type, we need to determine
the base object for the pointer; so handle conversions before
return fold_convert (ptr_type_node,
build_fold_addr_expr (base));
+ case POINTER_PLUS_EXPR:
+ return determine_base_object (TREE_OPERAND (expr, 0));
+
case PLUS_EXPR:
case MINUS_EXPR:
- op0 = determine_base_object (TREE_OPERAND (expr, 0));
- op1 = determine_base_object (TREE_OPERAND (expr, 1));
-
- if (!op1)
- return op0;
-
- if (!op0)
- return (code == PLUS_EXPR
- ? op1
- : fold_build1 (NEGATE_EXPR, ptr_type_node, op1));
-
- return fold_build2 (code, ptr_type_node, op0, op1);
+ /* Pointer addition is done solely using POINTER_PLUS_EXPR. */
+ gcc_unreachable ();
default:
return fold_convert (ptr_type_node, expr);
if (!EXPR_P (expr) && !GIMPLE_STMT_P (expr))
return false;
- len = TREE_CODE_LENGTH (TREE_CODE (expr));
+ len = TREE_OPERAND_LENGTH (expr);
for (i = 0; i < len; i++)
if (!expr_invariant_in_loop_p (loop, TREE_OPERAND (expr, i)))
return false;
static bool
idx_find_step (tree base, tree *idx, void *data)
{
- struct ifs_ivopts_data *dta = data;
+ struct ifs_ivopts_data *dta = (struct ifs_ivopts_data *) data;
struct iv *iv;
tree step, iv_base, iv_step, lbound, off;
struct loop *loop = dta->ivopts_data->current_loop;
static bool
idx_record_use (tree base, tree *idx,
- void *data)
+ void *vdata)
{
+ struct ivopts_data *data = (struct ivopts_data *) vdata;
find_interesting_uses_op (data, *idx);
if (TREE_CODE (base) == ARRAY_REF)
{
static tree
find_depends (tree *expr_p, int *ws ATTRIBUTE_UNUSED, void *data)
{
- bitmap *depends_on = data;
+ bitmap *depends_on = (bitmap *) data;
struct version_info *info;
if (TREE_CODE (*expr_p) != SSA_NAME)
{
const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (obj));
x = gen_rtx_SYMBOL_REF (Pmode, name);
+ SET_SYMBOL_REF_DECL (x, obj);
+ x = gen_rtx_MEM (DECL_MODE (obj), x);
+ targetm.encode_section_info (obj, x, true);
}
else
- x = gen_raw_REG (Pmode, (*regno)++);
+ {
+ x = gen_raw_REG (Pmode, (*regno)++);
+ x = gen_rtx_MEM (DECL_MODE (obj), x);
+ }
- return gen_rtx_MEM (DECL_MODE (obj), x);
+ return x;
}
/* Prepares decl_rtl for variables referred in *EXPR_P. Callback for
{
tree obj = NULL_TREE;
rtx x = NULL_RTX;
- int *regno = data;
+ int *regno = (int *) data;
switch (TREE_CODE (*expr_p))
{
static hashval_t
mbc_entry_hash (const void *entry)
{
- const struct mbc_entry *e = entry;
+ const struct mbc_entry *e = (const struct mbc_entry *) entry;
return 57 * (hashval_t) e->mode + (hashval_t) (e->cst % 877);
}
static int
mbc_entry_eq (const void *entry1, const void *entry2)
{
- const struct mbc_entry *e1 = entry1;
- const struct mbc_entry *e2 = entry2;
+ const struct mbc_entry *e1 = (const struct mbc_entry *) entry1;
+ const struct mbc_entry *e2 = (const struct mbc_entry *) entry2;
return (e1->mode == e2->mode
&& e1->cst == e2->cst);
if (sym_p)
{
base = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (""));
+ /* ??? We can run into trouble with some backends by presenting
+ it with symbols which havn't been properly passed through
+ targetm.encode_section_info. By setting the local bit, we
+ enhance the probability of things working. */
+ SYMBOL_REF_FLAGS (base) = SYMBOL_FLAG_LOCAL;
+
if (off_p)
base = gen_rtx_fmt_e (CONST, Pmode,
gen_rtx_fmt_ee (PLUS, Pmode,
if (!costs_initialized)
{
- tree var = create_tmp_var_raw (integer_type_node, "test_var");
- rtx x = gen_rtx_MEM (DECL_MODE (var),
- gen_rtx_SYMBOL_REF (Pmode, "test_var"));
- tree addr;
tree type = build_pointer_type (integer_type_node);
+ tree var, addr;
+ rtx x;
+
+ var = create_tmp_var_raw (integer_type_node, "test_var");
+ TREE_STATIC (var) = 1;
+ x = produce_memory_decl_rtl (var, NULL);
+ SET_DECL_RTL (var, x);
integer_cost = computation_cost (build_int_cst (integer_type_node,
2000));
- SET_DECL_RTL (var, x);
- TREE_STATIC (var) = 1;
addr = build1 (ADDR_EXPR, type, var);
symbol_cost = computation_cost (addr) + 1;
address_cost
- = computation_cost (build2 (PLUS_EXPR, type,
+ = computation_cost (build2 (POINTER_PLUS_EXPR, type,
addr,
- build_int_cst (type, 2000))) + 1;
+ build_int_cst (sizetype, 2000))) + 1;
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "force_expr_to_var_cost:\n");
switch (TREE_CODE (expr))
{
+ case POINTER_PLUS_EXPR:
case PLUS_EXPR:
case MINUS_EXPR:
case MULT_EXPR:
mode = TYPE_MODE (TREE_TYPE (expr));
switch (TREE_CODE (expr))
{
+ case POINTER_PLUS_EXPR:
case PLUS_EXPR:
case MINUS_EXPR:
cost = add_cost (mode);
static unsigned
ivopts_global_cost_for_size (struct ivopts_data *data, unsigned size)
{
- return global_cost_for_size (size, data->regs_used, n_iv_uses (data));
+ /* We add size to the cost, so that we prefer eliminating ivs
+ if possible. */
+ return size + estimate_reg_pressure_cost (size, data->regs_used);
}
/* For each size of the induction variable set determine the penalty. */
{
fprintf (dump_file, "Global costs:\n");
fprintf (dump_file, " target_avail_regs %d\n", target_avail_regs);
- fprintf (dump_file, " target_small_cost %d\n", target_small_cost);
- fprintf (dump_file, " target_pres_cost %d\n", target_pres_cost);
+ fprintf (dump_file, " target_reg_cost %d\n", target_reg_cost);
fprintf (dump_file, " target_spill_cost %d\n", target_spill_cost);
}
{
tree comp;
tree op, stmts, tgt, ass;
- block_stmt_iterator bsi, pbsi;
+ block_stmt_iterator bsi;
/* An important special case -- if we are asked to express value of
the original iv by itself, just exit; there is no need to
if (name_info (data, tgt)->preserve_biv)
return;
- pbsi = bsi = bsi_start (bb_for_stmt (use->stmt));
- while (!bsi_end_p (pbsi)
- && TREE_CODE (bsi_stmt (pbsi)) == LABEL_EXPR)
- {
- bsi = pbsi;
- bsi_next (&pbsi);
- }
+ bsi = bsi_after_labels (bb_for_stmt (use->stmt));
break;
case GIMPLE_MODIFY_STMT:
}
op = force_gimple_operand (comp, &stmts, false, SSA_NAME_VAR (tgt));
+ if (stmts)
+ bsi_insert_before (&bsi, stmts, BSI_SAME_STMT);
if (TREE_CODE (use->stmt) == PHI_NODE)
{
- if (stmts)
- bsi_insert_after (&bsi, stmts, BSI_CONTINUE_LINKING);
- ass = build2_gimple (GIMPLE_MODIFY_STMT, tgt, op);
- bsi_insert_after (&bsi, ass, BSI_NEW_STMT);
+ ass = build_gimple_modify_stmt (tgt, op);
+ bsi_insert_before (&bsi, ass, BSI_SAME_STMT);
remove_statement (use->stmt, false);
SSA_NAME_DEF_STMT (tgt) = ass;
}
else
- {
- if (stmts)
- bsi_insert_before (&bsi, stmts, BSI_SAME_STMT);
- GIMPLE_STMT_OPERAND (use->stmt, 1) = op;
- }
+ GIMPLE_STMT_OPERAND (use->stmt, 1) = op;
}
/* Replaces ssa name in index IDX by its basic variable. Callback for