X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Ftree-ssa-reassoc.c;h=32a66eb00153e30426f2e7e26e276211bb4bae5e;hb=0305c755745c1d24fb688d9b5bb540c4232417b7;hp=879e5702e92b32d6c30b6984a0761d6747d4d729;hpb=5f9acd886b17be8693b8c0b4591b274763915d33;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c index 879e5702e92..32a66eb0015 100644 --- a/gcc/tree-ssa-reassoc.c +++ b/gcc/tree-ssa-reassoc.c @@ -38,6 +38,7 @@ Boston, MA 02110-1301, USA. */ #include "alloc-pool.h" #include "vec.h" #include "langhooks.h" +#include "pointer-set.h" /* This is a simple global reassociation pass. It is, in part, based on the LLVM pass of the same name (They do some things more/less @@ -179,68 +180,38 @@ static alloc_pool operand_entry_pool; /* Starting rank number for a given basic block, so that we can rank operations using unmovable instructions in that BB based on the bb depth. */ -static unsigned int *bb_rank; +static long *bb_rank; /* Operand->rank hashtable. */ -static htab_t operand_rank; +static struct pointer_map_t *operand_rank; /* Look up the operand rank structure for expression E. */ -static operand_entry_t +static inline long find_operand_rank (tree e) { - void **slot; - struct operand_entry vrd; - - vrd.op = e; - slot = htab_find_slot (operand_rank, &vrd, NO_INSERT); - if (!slot) - return NULL; - return ((operand_entry_t) *slot); + void **slot = pointer_map_contains (operand_rank, e); + return slot ? (long) *slot : -1; } /* Insert {E,RANK} into the operand rank hashtable. */ -static void -insert_operand_rank (tree e, unsigned int rank) +static inline void +insert_operand_rank (tree e, long rank) { void **slot; - operand_entry_t new_pair = pool_alloc (operand_entry_pool); - - new_pair->op = e; - new_pair->rank = rank; - slot = htab_find_slot (operand_rank, new_pair, INSERT); - gcc_assert (*slot == NULL); - *slot = new_pair; -} - -/* Return the hash value for a operand rank structure */ - -static hashval_t -operand_entry_hash (const void *p) -{ - const operand_entry_t vr = (operand_entry_t) p; - return iterative_hash_expr (vr->op, 0); -} - -/* Return true if two operand rank structures are equal. */ - -static int -operand_entry_eq (const void *p1, const void *p2) -{ - const operand_entry_t vr1 = (operand_entry_t) p1; - const operand_entry_t vr2 = (operand_entry_t) p2; - return vr1->op == vr2->op; + gcc_assert (rank > 0); + slot = pointer_map_insert (operand_rank, e); + gcc_assert (!*slot); + *slot = (void *) rank; } /* Given an expression E, return the rank of the expression. */ -static unsigned int +static long get_rank (tree e) { - operand_entry_t vr; - /* Constants have rank 0. */ if (is_gimple_min_invariant (e)) return 0; @@ -260,37 +231,39 @@ get_rank (tree e) { tree stmt; tree rhs; - unsigned int rank, maxrank; + long rank, maxrank; int i; + int n; if (TREE_CODE (SSA_NAME_VAR (e)) == PARM_DECL - && e == default_def (SSA_NAME_VAR (e))) - return find_operand_rank (e)->rank; + && SSA_NAME_IS_DEFAULT_DEF (e)) + return find_operand_rank (e); stmt = SSA_NAME_DEF_STMT (e); if (bb_for_stmt (stmt) == NULL) return 0; - if (TREE_CODE (stmt) != MODIFY_EXPR + if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT || !ZERO_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_DEFS)) return bb_rank[bb_for_stmt (stmt)->index]; /* If we already have a rank for this expression, use that. */ - vr = find_operand_rank (e); - if (vr) - return vr->rank; + rank = find_operand_rank (e); + if (rank != -1) + return rank; /* Otherwise, find the maximum rank for the operands, or the bb rank, whichever is less. */ rank = 0; maxrank = bb_rank[bb_for_stmt(stmt)->index]; - rhs = TREE_OPERAND (stmt, 1); - if (TREE_CODE_LENGTH (TREE_CODE (rhs)) == 0) + rhs = GIMPLE_STMT_OPERAND (stmt, 1); + n = TREE_OPERAND_LENGTH (rhs); + if (n == 0) rank = MAX (rank, get_rank (rhs)); else { for (i = 0; - i < TREE_CODE_LENGTH (TREE_CODE (rhs)) + i < n && TREE_OPERAND (rhs, i) && rank != maxrank; i++) @@ -301,7 +274,7 @@ get_rank (tree e) { fprintf (dump_file, "Rank for "); print_generic_expr (dump_file, e, 0); - fprintf (dump_file, " is %d\n", (rank + 1)); + fprintf (dump_file, " is %ld\n", (rank + 1)); } /* Note the rank in the hashtable so we don't recompute it. */ @@ -378,9 +351,9 @@ static bool is_reassociable_op (tree stmt, enum tree_code code) { if (!IS_EMPTY_STMT (stmt) - && TREE_CODE (stmt) == MODIFY_EXPR - && TREE_CODE (TREE_OPERAND (stmt, 1)) == code - && has_single_use (TREE_OPERAND (stmt, 0))) + && TREE_CODE (stmt) == GIMPLE_MODIFY_STMT + && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == code + && has_single_use (GIMPLE_STMT_OPERAND (stmt, 0))) return true; return false; } @@ -395,10 +368,10 @@ get_unary_op (tree name, enum tree_code opcode) tree stmt = SSA_NAME_DEF_STMT (name); tree rhs; - if (TREE_CODE (stmt) != MODIFY_EXPR) + if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT) return NULL_TREE; - rhs = TREE_OPERAND (stmt, 1); + rhs = GIMPLE_STMT_OPERAND (stmt, 1); if (TREE_CODE (rhs) == opcode) return TREE_OPERAND (rhs, 0); return NULL_TREE; @@ -417,8 +390,8 @@ eliminate_duplicate_pair (enum tree_code opcode, operand_entry_t last) { - /* If we have two of the same op, and the opcode is & or |, we can - eliminate one of them. + /* If we have two of the same op, and the opcode is & |, min, or max, + we can eliminate one of them. If we have two of the same op, and the opcode is ^, we can eliminate both of them. */ @@ -426,13 +399,15 @@ eliminate_duplicate_pair (enum tree_code opcode, { switch (opcode) { + case MAX_EXPR: + case MIN_EXPR: case BIT_IOR_EXPR: case BIT_AND_EXPR: if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "Equivalence: "); print_generic_expr (dump_file, curr->op, 0); - fprintf (dump_file, " [&|] "); + fprintf (dump_file, " [&|minmax] "); print_generic_expr (dump_file, last->op, 0); fprintf (dump_file, " -> "); print_generic_stmt (dump_file, last->op, 0); @@ -812,7 +787,7 @@ static bool is_phi_for_stmt (tree stmt, tree operand) { tree def_stmt; - tree lhs = TREE_OPERAND (stmt, 0); + tree lhs = GIMPLE_STMT_OPERAND (stmt, 0); use_operand_p arg_p; ssa_op_iter i; @@ -837,7 +812,7 @@ static void rewrite_expr_tree (tree stmt, unsigned int opindex, VEC(operand_entry_t, heap) * ops) { - tree rhs = TREE_OPERAND (stmt, 1); + tree rhs = GIMPLE_STMT_OPERAND (stmt, 1); operand_entry_t oe; /* If we have three operands left, then we want to make sure the one @@ -950,7 +925,7 @@ static void linearize_expr (tree stmt) { block_stmt_iterator bsinow, bsirhs; - tree rhs = TREE_OPERAND (stmt, 1); + tree rhs = GIMPLE_STMT_OPERAND (stmt, 1); enum tree_code rhscode = TREE_CODE (rhs); tree binrhs = SSA_NAME_DEF_STMT (TREE_OPERAND (rhs, 1)); tree binlhs = SSA_NAME_DEF_STMT (TREE_OPERAND (rhs, 0)); @@ -963,11 +938,12 @@ linearize_expr (tree stmt) bsirhs = bsi_for_stmt (binrhs); bsi_move_before (&bsirhs, &bsinow); - TREE_OPERAND (rhs, 1) = TREE_OPERAND (TREE_OPERAND (binrhs, 1), 0); + TREE_OPERAND (rhs, 1) = TREE_OPERAND (GIMPLE_STMT_OPERAND (binrhs, 1), 0); if (TREE_CODE (TREE_OPERAND (rhs, 1)) == SSA_NAME) newbinrhs = SSA_NAME_DEF_STMT (TREE_OPERAND (rhs, 1)); - TREE_OPERAND (TREE_OPERAND (binrhs, 1), 0) = TREE_OPERAND (binlhs, 0); - TREE_OPERAND (rhs, 0) = TREE_OPERAND (binrhs, 0); + TREE_OPERAND (GIMPLE_STMT_OPERAND (binrhs, 1), 0) + = GIMPLE_STMT_OPERAND (binlhs, 0); + TREE_OPERAND (rhs, 0) = GIMPLE_STMT_OPERAND (binrhs, 0); if (dump_file && (dump_flags & TDF_DETAILS)) { @@ -989,7 +965,7 @@ linearize_expr (tree stmt) } -/* If LHS has a single immediate use that is a MODIFY_EXPR, return +/* If LHS has a single immediate use that is a GIMPLE_MODIFY_STMT, return it. Otherwise, return NULL. */ static tree @@ -1003,7 +979,7 @@ get_single_immediate_use (tree lhs) { if (TREE_CODE (immusestmt) == RETURN_EXPR) immusestmt = TREE_OPERAND (immusestmt, 0); - if (TREE_CODE (immusestmt) == MODIFY_EXPR) + if (TREE_CODE (immusestmt) == GIMPLE_MODIFY_STMT) return immusestmt; } return NULL_TREE; @@ -1030,13 +1006,13 @@ negate_value (tree tonegate, block_stmt_iterator *bsi) /* If we are trying to negate a name, defined by an add, negate the add operands instead. */ if (TREE_CODE (tonegate) == SSA_NAME - && TREE_CODE (negatedef) == MODIFY_EXPR - && TREE_CODE (TREE_OPERAND (negatedef, 0)) == SSA_NAME - && num_imm_uses (TREE_OPERAND (negatedef, 0)) == 1 - && TREE_CODE (TREE_OPERAND (negatedef, 1)) == PLUS_EXPR) + && TREE_CODE (negatedef) == GIMPLE_MODIFY_STMT + && TREE_CODE (GIMPLE_STMT_OPERAND (negatedef, 0)) == SSA_NAME + && has_single_use (GIMPLE_STMT_OPERAND (negatedef, 0)) + && TREE_CODE (GIMPLE_STMT_OPERAND (negatedef, 1)) == PLUS_EXPR) { block_stmt_iterator bsi; - tree binop = TREE_OPERAND (negatedef, 1); + tree binop = GIMPLE_STMT_OPERAND (negatedef, 1); bsi = bsi_for_stmt (negatedef); TREE_OPERAND (binop, 0) = negate_value (TREE_OPERAND (binop, 0), @@ -1045,7 +1021,7 @@ negate_value (tree tonegate, block_stmt_iterator *bsi) TREE_OPERAND (binop, 1) = negate_value (TREE_OPERAND (binop, 1), &bsi); update_stmt (negatedef); - return TREE_OPERAND (negatedef, 0); + return GIMPLE_STMT_OPERAND (negatedef, 0); } tonegate = fold_build1 (NEGATE_EXPR, TREE_TYPE (tonegate), tonegate); @@ -1066,8 +1042,8 @@ static bool should_break_up_subtract (tree stmt) { - tree lhs = TREE_OPERAND (stmt, 0); - tree rhs = TREE_OPERAND (stmt, 1); + tree lhs = GIMPLE_STMT_OPERAND (stmt, 0); + tree rhs = GIMPLE_STMT_OPERAND (stmt, 1); tree binlhs = TREE_OPERAND (rhs, 0); tree binrhs = TREE_OPERAND (rhs, 1); tree immusestmt; @@ -1082,7 +1058,7 @@ should_break_up_subtract (tree stmt) if (TREE_CODE (lhs) == SSA_NAME && (immusestmt = get_single_immediate_use (lhs)) - && TREE_CODE (TREE_OPERAND (immusestmt, 1)) == PLUS_EXPR) + && TREE_CODE (GIMPLE_STMT_OPERAND (immusestmt, 1)) == PLUS_EXPR) return true; return false; @@ -1093,7 +1069,7 @@ should_break_up_subtract (tree stmt) static void break_up_subtract (tree stmt, block_stmt_iterator *bsi) { - tree rhs = TREE_OPERAND (stmt, 1); + tree rhs = GIMPLE_STMT_OPERAND (stmt, 1); if (dump_file && (dump_flags & TDF_DETAILS)) { @@ -1101,7 +1077,7 @@ break_up_subtract (tree stmt, block_stmt_iterator *bsi) print_generic_stmt (dump_file, stmt, 0); } - TREE_SET_CODE (TREE_OPERAND (stmt, 1), PLUS_EXPR); + TREE_SET_CODE (GIMPLE_STMT_OPERAND (stmt, 1), PLUS_EXPR); TREE_OPERAND (rhs, 1) = negate_value (TREE_OPERAND (rhs, 1), bsi); update_stmt (stmt); @@ -1114,7 +1090,7 @@ static void linearize_expr_tree (VEC(operand_entry_t, heap) **ops, tree stmt) { block_stmt_iterator bsinow, bsilhs; - tree rhs = TREE_OPERAND (stmt, 1); + tree rhs = GENERIC_TREE_OPERAND (stmt, 1); tree binrhs = TREE_OPERAND (rhs, 1); tree binlhs = TREE_OPERAND (rhs, 0); tree binlhsdef, binrhsdef; @@ -1178,7 +1154,7 @@ linearize_expr_tree (VEC(operand_entry_t, heap) **ops, tree stmt) else if (binrhsisreassoc) { linearize_expr (stmt); - gcc_assert (rhs == TREE_OPERAND (stmt, 1)); + gcc_assert (rhs == GIMPLE_STMT_OPERAND (stmt, 1)); binlhs = TREE_OPERAND (rhs, 0); binrhs = TREE_OPERAND (rhs, 1); } @@ -1211,15 +1187,15 @@ repropagate_negates (void) Force the negate operand to the RHS of the PLUS_EXPR, then transform the PLUS_EXPR into a MINUS_EXPR. */ if (user - && TREE_CODE (user) == MODIFY_EXPR - && TREE_CODE (TREE_OPERAND (user, 1)) == PLUS_EXPR) + && TREE_CODE (user) == GIMPLE_MODIFY_STMT + && TREE_CODE (GIMPLE_STMT_OPERAND (user, 1)) == PLUS_EXPR) { - tree rhs = TREE_OPERAND (user, 1); + tree rhs = GIMPLE_STMT_OPERAND (user, 1); /* If the negated operand appears on the LHS of the PLUS_EXPR, exchange the operands of the PLUS_EXPR to force the negated operand to the RHS of the PLUS_EXPR. */ - if (TREE_OPERAND (TREE_OPERAND (user, 1), 0) == negate) + if (TREE_OPERAND (GIMPLE_STMT_OPERAND (user, 1), 0) == negate) { tree temp = TREE_OPERAND (rhs, 0); TREE_OPERAND (rhs, 0) = TREE_OPERAND (rhs, 1); @@ -1228,7 +1204,7 @@ repropagate_negates (void) /* Now transform the PLUS_EXPR into a MINUS_EXPR and replace the RHS of the PLUS_EXPR with the operand of the NEGATE_EXPR. */ - if (TREE_OPERAND (TREE_OPERAND (user, 1), 1) == negate) + if (TREE_OPERAND (GIMPLE_STMT_OPERAND (user, 1), 1) == negate) { TREE_SET_CODE (rhs, MINUS_EXPR); TREE_OPERAND (rhs, 1) = get_unary_op (negate, NEGATE_EXPR); @@ -1263,10 +1239,10 @@ break_up_subtract_bb (basic_block bb) { tree stmt = bsi_stmt (bsi); - if (TREE_CODE (stmt) == MODIFY_EXPR) + if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT) { - tree lhs = TREE_OPERAND (stmt, 0); - tree rhs = TREE_OPERAND (stmt, 1); + tree lhs = GIMPLE_STMT_OPERAND (stmt, 0); + tree rhs = GIMPLE_STMT_OPERAND (stmt, 1); TREE_VISITED (stmt) = 0; /* If unsafe math optimizations we can do reassociation for @@ -1306,10 +1282,10 @@ reassociate_bb (basic_block bb) { tree stmt = bsi_stmt (bsi); - if (TREE_CODE (stmt) == MODIFY_EXPR) + if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT) { - tree lhs = TREE_OPERAND (stmt, 0); - tree rhs = TREE_OPERAND (stmt, 1); + tree lhs = GIMPLE_STMT_OPERAND (stmt, 0); + tree rhs = GIMPLE_STMT_OPERAND (stmt, 1); /* If this was part of an already processed tree, we don't need to touch it again. */ @@ -1331,7 +1307,7 @@ reassociate_bb (basic_block bb) /* There may be no immediate uses left by the time we get here because we may have eliminated them all. */ - if (TREE_CODE (lhs) == SSA_NAME && num_imm_uses (lhs) == 0) + if (TREE_CODE (lhs) == SSA_NAME && has_zero_uses (lhs)) continue; TREE_VISITED (stmt) = 1; @@ -1349,14 +1325,15 @@ reassociate_bb (basic_block bb) fprintf (dump_file, "Transforming "); print_generic_expr (dump_file, rhs, 0); } - TREE_OPERAND (stmt, 1) = VEC_last (operand_entry_t, ops)->op; + GIMPLE_STMT_OPERAND (stmt, 1) + = VEC_last (operand_entry_t, ops)->op; update_stmt (stmt); if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, " into "); print_generic_stmt (dump_file, - TREE_OPERAND (stmt, 1), 0); + GIMPLE_STMT_OPERAND (stmt, 1), 0); } } else @@ -1413,9 +1390,9 @@ static void init_reassoc (void) { int i; - unsigned int rank = 2; + long rank = 2; tree param; - int *bbs = xmalloc ((last_basic_block + 1) * sizeof (int)); + int *bbs = XNEWVEC (int, last_basic_block + 1); memset (&reassociate_stats, 0, sizeof (reassociate_stats)); @@ -1425,19 +1402,17 @@ init_reassoc (void) /* Reverse RPO (Reverse Post Order) will give us something where deeper loops come later. */ pre_and_rev_post_order_compute (NULL, bbs, false); - bb_rank = xcalloc (last_basic_block + 1, sizeof (unsigned int)); - - operand_rank = htab_create (511, operand_entry_hash, - operand_entry_eq, 0); + bb_rank = XCNEWVEC (long, last_basic_block + 1); + operand_rank = pointer_map_create (); /* Give each argument a distinct rank. */ for (param = DECL_ARGUMENTS (current_function_decl); param; param = TREE_CHAIN (param)) { - if (default_def (param) != NULL) + if (gimple_default_def (cfun, param) != NULL) { - tree def = default_def (param); + tree def = gimple_default_def (cfun, param); insert_operand_rank (def, ++rank); } } @@ -1445,7 +1420,7 @@ init_reassoc (void) /* Give the chain decl a distinct rank. */ if (cfun->static_chain_decl != NULL) { - tree def = default_def (cfun->static_chain_decl); + tree def = gimple_default_def (cfun, cfun->static_chain_decl); if (def != NULL) insert_operand_rank (def, ++rank); } @@ -1479,8 +1454,8 @@ fini_reassoc (void) fprintf (dump_file, "Statements rewritten: %d\n", reassociate_stats.rewritten); } - htab_delete (operand_rank); + pointer_map_destroy (operand_rank); free_alloc_pool (operand_entry_pool); free (bb_rank); VEC_free (tree, heap, broken_up_subtracts); @@ -1489,7 +1464,7 @@ fini_reassoc (void) /* Gate and execute functions for Reassociation. */ -static void +static unsigned int execute_reassoc (void) { init_reassoc (); @@ -1498,6 +1473,7 @@ execute_reassoc (void) repropagate_negates (); fini_reassoc (); + return 0; } struct tree_opt_pass pass_reassoc =