diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-07-28 14:33:56 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-07-28 14:33:56 +0000 |
commit | 75a70cf95f65fe9204b15ad9aba31c571381d224 (patch) | |
tree | 2926705dd533a8904679724ab1cec40dfee45094 /gcc/tree-ssa-reassoc.c | |
parent | d0a9db40355cf570989e2aca92ab2060df234926 (diff) | |
download | gcc-75a70cf95f65fe9204b15ad9aba31c571381d224.tar.gz |
2008-07-28 Richard Guenther <rguenther@suse.de>
Merge from gimple-tuples-branch.
* ChangeLog.tuples: ChangeLog from gimple-tuples-branch.
* gimple.def: New file.
* gsstruct.def: Likewise.
* gimple-iterator.c: Likewise.
* gimple-pretty-print.c: Likewise.
* tree-gimple.c: Removed. Merged into ...
* gimple.c: ... here. New file.
* tree-gimple.h: Removed. Merged into ...
* gimple.h: ... here. New file.
* Makefile.in: Add dependencies on GIMPLE_H and tree-iterator.h.
* configure.ac: Added support for ENABLE_GIMPLE_CHECKING and the
--enable-checking=gimple flag.
* config.in: Likewise.
* configure: Regenerated.
* tree-ssa-operands.h: Tuplified.
* tree-vrp.c: Likewise.
* tree-loop-linear.c: Likewise.
* tree-into-ssa.c: Likewise.
* tree-ssa-loop-im.c: Likewise.
* tree-dump.c: Likewise.
* tree-complex.c: Likewise.
* cgraphbuild.c: Likewise.
* tree-ssa-threadupdate.c: Likewise.
* tree-ssa-loop-niter.c: Likewise.
* tree-pretty-print.c: Likewise.
* tracer.c: Likewise.
* gengtype.c: Likewise.
* tree-loop-distribution.c: Likewise.
* tree-ssa-loop-unswitch.c: Likewise.
* cgraph.c: Likewise.
* cgraph.h: Likewise.
* tree-ssa-loop-manip.c: Likewise.
* value-prof.c: Likewise.
* tree-ssa-loop-ch.c: Likewise.
* tree-tailcall.c: Likewise.
* value-prof.h: Likewise.
* tree.c: Likewise.
* tree.h: Likewise.
* tree-pass.h: Likewise.
* ipa-cp.c: Likewise.
* tree-scalar-evolution.c: Likewise.
* tree-scalar-evolution.h: Likewise.
* target.h: Likewise.
* lambda-mat.c: Likewise.
* tree-phinodes.c: Likewise.
* diagnostic.h: Likewise.
* builtins.c: Likewise.
* tree-ssa-alias-warnings.c: Likewise.
* cfghooks.c: Likewise.
* fold-const.c: Likewise.
* cfghooks.h: Likewise.
* omp-low.c: Likewise.
* tree-ssa-dse.c: Likewise.
* ipa-reference.c: Likewise.
* tree-ssa-uncprop.c: Likewise.
* toplev.c: Likewise.
* tree-gimple.c: Likewise.
* tree-gimple.h: Likewise.
* tree-chrec.c: Likewise.
* tree-chrec.h: Likewise.
* tree-ssa-sccvn.c: Likewise.
* tree-ssa-sccvn.h: Likewise.
* cgraphunit.c: Likewise.
* tree-ssa-copyrename.c: Likewise.
* tree-ssa-ccp.c: Likewise.
* tree-ssa-loop-ivopts.c: Likewise.
* tree-nomudflap.c: Likewise.
* tree-call-cdce.c: Likewise.
* ipa-pure-const.c: Likewise.
* c-format.c: Likewise.
* tree-stdarg.c: Likewise.
* tree-ssa-math-opts.c: Likewise.
* tree-ssa-dom.c: Likewise.
* tree-nrv.c: Likewise.
* tree-ssa-propagate.c: Likewise.
* ipa-utils.c: Likewise.
* tree-ssa-propagate.h: Likewise.
* tree-ssa-alias.c: Likewise.
* gimple-low.c: Likewise.
* tree-ssa-sink.c: Likewise.
* ipa-inline.c: Likewise.
* c-semantics.c: Likewise.
* dwarf2out.c: Likewise.
* expr.c: Likewise.
* tree-ssa-loop-ivcanon.c: Likewise.
* predict.c: Likewise.
* tree-ssa-loop.c: Likewise.
* tree-parloops.c: Likewise.
* tree-ssa-address.c: Likewise.
* tree-ssa-ifcombine.c: Likewise.
* matrix-reorg.c: Likewise.
* c-decl.c: Likewise.
* tree-eh.c: Likewise.
* c-pretty-print.c: Likewise.
* lambda-trans.c: Likewise.
* function.c: Likewise.
* langhooks.c: Likewise.
* ebitmap.h: Likewise.
* tree-vectorizer.c: Likewise.
* function.h: Likewise.
* langhooks.h: Likewise.
* tree-vectorizer.h: Likewise.
* ipa-type-escape.c: Likewise.
* ipa-type-escape.h: Likewise.
* domwalk.c: Likewise.
* tree-if-conv.c: Likewise.
* profile.c: Likewise.
* domwalk.h: Likewise.
* tree-data-ref.c: Likewise.
* tree-data-ref.h: Likewise.
* tree-flow-inline.h: Likewise.
* tree-affine.c: Likewise.
* tree-vect-analyze.c: Likewise.
* c-typeck.c: Likewise.
* gimplify.c: Likewise.
* coretypes.h: Likewise.
* tree-ssa-phiopt.c: Likewise.
* calls.c: Likewise.
* tree-ssa-coalesce.c: Likewise.
* tree.def: Likewise.
* tree-dfa.c: Likewise.
* except.c: Likewise.
* except.h: Likewise.
* cfgexpand.c: Likewise.
* tree-cfgcleanup.c: Likewise.
* tree-ssa-pre.c: Likewise.
* tree-ssa-live.c: Likewise.
* tree-sra.c: Likewise.
* tree-ssa-live.h: Likewise.
* tree-predcom.c: Likewise.
* lambda.h: Likewise.
* tree-mudflap.c: Likewise.
* ipa-prop.c: Likewise.
* print-tree.c: Likewise.
* tree-ssa-copy.c: Likewise.
* ipa-prop.h: Likewise.
* tree-ssa-forwprop.c: Likewise.
* ggc-page.c: Likewise.
* c-omp.c: Likewise.
* tree-ssa-dce.c: Likewise.
* tree-vect-patterns.c: Likewise.
* tree-ssa-ter.c: Likewise.
* tree-nested.c: Likewise.
* tree-ssa.c: Likewise.
* lambda-code.c: Likewise.
* tree-ssa-loop-prefetch.c: Likewise.
* tree-inline.c: Likewise.
* tree-inline.h: Likewise.
* tree-iterator.c: Likewise.
* tree-optimize.c: Likewise.
* tree-ssa-phiprop.c: Likewise.
* tree-vect-transform.c: Likewise.
* tree-object-size.c: Likewise.
* tree-outof-ssa.c: Likewise.
* cfgloop.c: Likewise.
* system.h: Likewise.
* tree-profile.c: Likewise.
* cfgloop.h: Likewise.
* c-gimplify.c: Likewise.
* c-common.c: Likewise.
* tree-vect-generic.c: Likewise.
* tree-flow.h: Likewise.
* c-common.h: Likewise.
* basic-block.h: Likewise.
* tree-ssa-structalias.c: Likewise.
* tree-switch-conversion.c: Likewise.
* tree-ssa-structalias.h: Likewise.
* tree-cfg.c: Likewise.
* passes.c: Likewise.
* ipa-struct-reorg.c: Likewise.
* ipa-struct-reorg.h: Likewise.
* tree-ssa-reassoc.c: Likewise.
* cfgrtl.c: Likewise.
* varpool.c: Likewise.
* stmt.c: Likewise.
* tree-ssanames.c: Likewise.
* tree-ssa-threadedge.c: Likewise.
* langhooks-def.h: Likewise.
* tree-ssa-operands.c: Likewise.
* config/alpha/alpha.c: Likewise.
* config/frv/frv.c: Likewise.
* config/s390/s390.c: Likewise.
* config/m32c/m32c.c: Likewise.
* config/m32c/m32c-protos.h: Likewise.
* config/spu/spu.c: Likewise.
* config/sparc/sparc.c: Likewise.
* config/i386/i386.c: Likewise.
* config/sh/sh.c: Likewise.
* config/xtensa/xtensa.c: Likewise.
* config/stormy16/stormy16.c: Likewise.
* config/ia64/ia64.c: Likewise.
* config/rs6000/rs6000.c: Likewise.
* config/pa/pa.c: Likewise.
* config/mips/mips.c: Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@138207 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-reassoc.c')
-rw-r--r-- | gcc/tree-ssa-reassoc.c | 409 |
1 files changed, 216 insertions, 193 deletions
diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c index 5fcaa7bbb16..a3facd8baa1 100644 --- a/gcc/tree-ssa-reassoc.c +++ b/gcc/tree-ssa-reassoc.c @@ -29,7 +29,7 @@ along with GCC; see the file COPYING3. If not see #include "diagnostic.h" #include "tree-inline.h" #include "tree-flow.h" -#include "tree-gimple.h" +#include "gimple.h" #include "tree-dump.h" #include "timevar.h" #include "tree-iterator.h" @@ -230,23 +230,21 @@ get_rank (tree e) if (TREE_CODE (e) == SSA_NAME) { - tree stmt; - tree rhs; + gimple stmt; long rank, maxrank; - int i; - int n; + int i, n; if (TREE_CODE (SSA_NAME_VAR (e)) == PARM_DECL && SSA_NAME_IS_DEFAULT_DEF (e)) return find_operand_rank (e); stmt = SSA_NAME_DEF_STMT (e); - if (bb_for_stmt (stmt) == NULL) + if (gimple_bb (stmt) == NULL) return 0; - if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT + if (!is_gimple_assign (stmt) || !ZERO_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_DEFS)) - return bb_rank[bb_for_stmt (stmt)->index]; + return bb_rank[gimple_bb (stmt)->index]; /* If we already have a rank for this expression, use that. */ rank = find_operand_rank (e); @@ -256,19 +254,28 @@ get_rank (tree e) /* 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 = GIMPLE_STMT_OPERAND (stmt, 1); - n = TREE_OPERAND_LENGTH (rhs); - if (n == 0) - rank = MAX (rank, get_rank (rhs)); + maxrank = bb_rank[gimple_bb(stmt)->index]; + if (gimple_assign_single_p (stmt)) + { + tree rhs = gimple_assign_rhs1 (stmt); + n = TREE_OPERAND_LENGTH (rhs); + if (n == 0) + rank = MAX (rank, get_rank (rhs)); + else + { + for (i = 0; + i < n && TREE_OPERAND (rhs, i) && rank != maxrank; i++) + rank = MAX(rank, get_rank (TREE_OPERAND (rhs, i))); + } + } else { - for (i = 0; - i < n - && TREE_OPERAND (rhs, i) - && rank != maxrank; - i++) - rank = MAX(rank, get_rank (TREE_OPERAND (rhs, i))); + n = gimple_num_ops (stmt); + for (i = 1; i < n && rank != maxrank; i++) + { + gcc_assert (gimple_op (stmt, i)); + rank = MAX(rank, get_rank (gimple_op (stmt, i))); + } } if (dump_file && (dump_flags & TDF_DETAILS)) @@ -349,21 +356,21 @@ add_to_ops_vec (VEC(operand_entry_t, heap) **ops, tree op) operation with tree code CODE, and is inside LOOP. */ static bool -is_reassociable_op (tree stmt, enum tree_code code, struct loop *loop) +is_reassociable_op (gimple stmt, enum tree_code code, struct loop *loop) { - basic_block bb; + basic_block bb = gimple_bb (stmt); - if (IS_EMPTY_STMT (stmt)) + if (gimple_bb (stmt) == NULL) return false; - bb = bb_for_stmt (stmt); if (!flow_bb_inside_loop_p (loop, bb)) return false; - if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT - && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == code - && has_single_use (GIMPLE_STMT_OPERAND (stmt, 0))) + if (is_gimple_assign (stmt) + && gimple_assign_rhs_code (stmt) == code + && has_single_use (gimple_assign_lhs (stmt))) return true; + return false; } @@ -374,15 +381,13 @@ is_reassociable_op (tree stmt, enum tree_code code, struct loop *loop) static tree get_unary_op (tree name, enum tree_code opcode) { - tree stmt = SSA_NAME_DEF_STMT (name); - tree rhs; + gimple stmt = SSA_NAME_DEF_STMT (name); - if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT) + if (!is_gimple_assign (stmt)) return NULL_TREE; - rhs = GIMPLE_STMT_OPERAND (stmt, 1); - if (TREE_CODE (rhs) == opcode) - return TREE_OPERAND (rhs, 0); + if (gimple_assign_rhs_code (stmt) == opcode) + return gimple_assign_rhs1 (stmt); return NULL_TREE; } @@ -806,18 +811,20 @@ optimize_ops_list (enum tree_code opcode, update" operation. */ static bool -is_phi_for_stmt (tree stmt, tree operand) +is_phi_for_stmt (gimple stmt, tree operand) { - tree def_stmt; - tree lhs = GIMPLE_STMT_OPERAND (stmt, 0); + gimple def_stmt; + tree lhs; use_operand_p arg_p; ssa_op_iter i; if (TREE_CODE (operand) != SSA_NAME) return false; + lhs = gimple_assign_lhs (stmt); + def_stmt = SSA_NAME_DEF_STMT (operand); - if (TREE_CODE (def_stmt) != PHI_NODE) + if (gimple_code (def_stmt) != GIMPLE_PHI) return false; FOR_EACH_PHI_ARG (arg_p, def_stmt, i, SSA_OP_USE) @@ -831,10 +838,11 @@ is_phi_for_stmt (tree stmt, tree operand) order. */ static void -rewrite_expr_tree (tree stmt, unsigned int opindex, +rewrite_expr_tree (gimple stmt, unsigned int opindex, VEC(operand_entry_t, heap) * ops) { - tree rhs = GIMPLE_STMT_OPERAND (stmt, 1); + tree rhs1 = gimple_assign_rhs1 (stmt); + tree rhs2 = gimple_assign_rhs2 (stmt); operand_entry_t oe; /* If we have three operands left, then we want to make sure the one @@ -897,24 +905,22 @@ rewrite_expr_tree (tree stmt, unsigned int opindex, oe1 = VEC_index (operand_entry_t, ops, opindex); oe2 = VEC_index (operand_entry_t, ops, opindex + 1); - if (TREE_OPERAND (rhs, 0) != oe1->op - || TREE_OPERAND (rhs, 1) != oe2->op) + if (rhs1 != oe1->op || rhs2 != oe2->op) { - if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "Transforming "); - print_generic_expr (dump_file, rhs, 0); + print_gimple_stmt (dump_file, stmt, 0, 0); } - TREE_OPERAND (rhs, 0) = oe1->op; - TREE_OPERAND (rhs, 1) = oe2->op; + gimple_assign_set_rhs1 (stmt, oe1->op); + gimple_assign_set_rhs2 (stmt, oe2->op); update_stmt (stmt); if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, " into "); - print_generic_stmt (dump_file, rhs, 0); + print_gimple_stmt (dump_file, stmt, 0, 0); } } @@ -927,28 +933,27 @@ rewrite_expr_tree (tree stmt, unsigned int opindex, /* Rewrite the next operator. */ oe = VEC_index (operand_entry_t, ops, opindex); - if (oe->op != TREE_OPERAND (rhs, 1)) + if (oe->op != rhs2) { if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "Transforming "); - print_generic_expr (dump_file, rhs, 0); + print_gimple_stmt (dump_file, stmt, 0, 0); } - TREE_OPERAND (rhs, 1) = oe->op; + gimple_assign_set_rhs2 (stmt, oe->op); update_stmt (stmt); if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, " into "); - print_generic_stmt (dump_file, rhs, 0); + print_gimple_stmt (dump_file, stmt, 0, 0); } } /* Recurse on the LHS of the binary operator, which is guaranteed to be the non-leaf side. */ - rewrite_expr_tree (SSA_NAME_DEF_STMT (TREE_OPERAND (rhs, 0)), - opindex + 1, ops); + rewrite_expr_tree (SSA_NAME_DEF_STMT (rhs1), opindex + 1, ops); } /* Transform STMT, which is really (A +B) + (C + D) into the left @@ -956,114 +961,114 @@ rewrite_expr_tree (tree stmt, unsigned int opindex, Recurse on D if necessary. */ static void -linearize_expr (tree stmt) +linearize_expr (gimple stmt) { - block_stmt_iterator bsinow, bsirhs; - 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)); - tree newbinrhs = NULL_TREE; + gimple_stmt_iterator gsinow, gsirhs; + gimple binlhs = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt)); + gimple binrhs = SSA_NAME_DEF_STMT (gimple_assign_rhs2 (stmt)); + enum tree_code rhscode = gimple_assign_rhs_code (stmt); + gimple newbinrhs = NULL; struct loop *loop = loop_containing_stmt (stmt); - gcc_assert (is_reassociable_op (binlhs, TREE_CODE (rhs), loop) - && is_reassociable_op (binrhs, TREE_CODE (rhs), loop)); + gcc_assert (is_reassociable_op (binlhs, rhscode, loop) + && is_reassociable_op (binrhs, rhscode, loop)); + + gsinow = gsi_for_stmt (stmt); + gsirhs = gsi_for_stmt (binrhs); + gsi_move_before (&gsirhs, &gsinow); - bsinow = bsi_for_stmt (stmt); - bsirhs = bsi_for_stmt (binrhs); - bsi_move_before (&bsirhs, &bsinow); + gimple_assign_set_rhs2 (stmt, gimple_assign_rhs1 (binrhs)); + gimple_assign_set_rhs1 (binrhs, gimple_assign_lhs (binlhs)); + gimple_assign_set_rhs1 (stmt, gimple_assign_lhs (binrhs)); - 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 (GIMPLE_STMT_OPERAND (binrhs, 1), 0) - = GIMPLE_STMT_OPERAND (binlhs, 0); - TREE_OPERAND (rhs, 0) = GIMPLE_STMT_OPERAND (binrhs, 0); + if (TREE_CODE (gimple_assign_rhs2 (stmt)) == SSA_NAME) + newbinrhs = SSA_NAME_DEF_STMT (gimple_assign_rhs2 (stmt)); if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "Linearized: "); - print_generic_stmt (dump_file, rhs, 0); + print_gimple_stmt (dump_file, stmt, 0, 0); } reassociate_stats.linearized++; update_stmt (binrhs); update_stmt (binlhs); update_stmt (stmt); - TREE_VISITED (binrhs) = 1; - TREE_VISITED (binlhs) = 1; - TREE_VISITED (stmt) = 1; + + gimple_set_visited (stmt, true); + gimple_set_visited (binlhs, true); + gimple_set_visited (binrhs, true); /* Tail recurse on the new rhs if it still needs reassociation. */ if (newbinrhs && is_reassociable_op (newbinrhs, rhscode, loop)) + /* ??? This should probably be linearize_expr (newbinrhs) but I don't + want to change the algorithm while converting to tuples. */ linearize_expr (stmt); } -/* If LHS has a single immediate use that is a GIMPLE_MODIFY_STMT, return +/* If LHS has a single immediate use that is a GIMPLE_ASSIGN statement, return it. Otherwise, return NULL. */ -static tree +static gimple get_single_immediate_use (tree lhs) { use_operand_p immuse; - tree immusestmt; + gimple immusestmt; if (TREE_CODE (lhs) == SSA_NAME - && single_imm_use (lhs, &immuse, &immusestmt)) - { - if (TREE_CODE (immusestmt) == RETURN_EXPR) - immusestmt = TREE_OPERAND (immusestmt, 0); - if (TREE_CODE (immusestmt) == GIMPLE_MODIFY_STMT) - return immusestmt; - } - return NULL_TREE; + && single_imm_use (lhs, &immuse, &immusestmt) + && is_gimple_assign (immusestmt)) + return immusestmt; + + return NULL; } -static VEC(tree, heap) *broken_up_subtracts; +static VEC(tree, heap) *broken_up_subtracts; /* Recursively negate the value of TONEGATE, and return the SSA_NAME representing the negated value. Insertions of any necessary - instructions go before BSI. + instructions go before GSI. This function is recursive in that, if you hand it "a_5" as the value to negate, and a_5 is defined by "a_5 = b_3 + b_4", it will transform b_3 + b_4 into a_5 = -b_3 + -b_4. */ static tree -negate_value (tree tonegate, block_stmt_iterator *bsi) +negate_value (tree tonegate, gimple_stmt_iterator *gsi) { - tree negatedef = tonegate; + gimple negatedefstmt= NULL; tree resultofnegate; - if (TREE_CODE (tonegate) == SSA_NAME) - negatedef = SSA_NAME_DEF_STMT (tonegate); - /* If we are trying to negate a name, defined by an add, negate the add operands instead. */ + if (TREE_CODE (tonegate) == SSA_NAME) + negatedefstmt = SSA_NAME_DEF_STMT (tonegate); if (TREE_CODE (tonegate) == SSA_NAME - && 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) + && is_gimple_assign (negatedefstmt) + && TREE_CODE (gimple_assign_lhs (negatedefstmt)) == SSA_NAME + && has_single_use (gimple_assign_lhs (negatedefstmt)) + && gimple_assign_rhs_code (negatedefstmt) == PLUS_EXPR) { - block_stmt_iterator bsi; - tree binop = GIMPLE_STMT_OPERAND (negatedef, 1); - - bsi = bsi_for_stmt (negatedef); - TREE_OPERAND (binop, 0) = negate_value (TREE_OPERAND (binop, 0), - &bsi); - bsi = bsi_for_stmt (negatedef); - TREE_OPERAND (binop, 1) = negate_value (TREE_OPERAND (binop, 1), - &bsi); - update_stmt (negatedef); - return GIMPLE_STMT_OPERAND (negatedef, 0); + gimple_stmt_iterator gsi; + tree rhs1 = gimple_assign_rhs1 (negatedefstmt); + tree rhs2 = gimple_assign_rhs2 (negatedefstmt); + + gsi = gsi_for_stmt (negatedefstmt); + rhs1 = negate_value (rhs1, &gsi); + gimple_assign_set_rhs1 (negatedefstmt, rhs1); + + gsi = gsi_for_stmt (negatedefstmt); + rhs2 = negate_value (rhs2, &gsi); + gimple_assign_set_rhs2 (negatedefstmt, rhs2); + + update_stmt (negatedefstmt); + return gimple_assign_lhs (negatedefstmt); } tonegate = fold_build1 (NEGATE_EXPR, TREE_TYPE (tonegate), tonegate); - resultofnegate = force_gimple_operand_bsi (bsi, tonegate, true, - NULL_TREE, true, BSI_SAME_STMT); + resultofnegate = force_gimple_operand_gsi (gsi, tonegate, true, + NULL_TREE, true, GSI_SAME_STMT); VEC_safe_push (tree, heap, broken_up_subtracts, resultofnegate); return resultofnegate; - } /* Return true if we should break up the subtract in STMT into an add @@ -1073,14 +1078,12 @@ negate_value (tree tonegate, block_stmt_iterator *bsi) exposes the adds to reassociation. */ static bool -should_break_up_subtract (tree stmt) +should_break_up_subtract (gimple stmt) { - - 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; + tree lhs = gimple_assign_lhs (stmt); + tree binlhs = gimple_assign_rhs1 (stmt); + tree binrhs = gimple_assign_rhs2 (stmt); + gimple immusestmt; struct loop *loop = loop_containing_stmt (stmt); if (TREE_CODE (binlhs) == SSA_NAME @@ -1093,28 +1096,28 @@ should_break_up_subtract (tree stmt) if (TREE_CODE (lhs) == SSA_NAME && (immusestmt = get_single_immediate_use (lhs)) - && TREE_CODE (GIMPLE_STMT_OPERAND (immusestmt, 1)) == PLUS_EXPR) + && is_gimple_assign (immusestmt) + && gimple_assign_rhs_code (immusestmt) == PLUS_EXPR) return true; return false; - } /* Transform STMT from A - B into A + -B. */ static void -break_up_subtract (tree stmt, block_stmt_iterator *bsi) +break_up_subtract (gimple stmt, gimple_stmt_iterator *gsip) { - tree rhs = GIMPLE_STMT_OPERAND (stmt, 1); + tree rhs1 = gimple_assign_rhs1 (stmt); + tree rhs2 = gimple_assign_rhs2 (stmt); if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "Breaking up subtract "); - print_generic_stmt (dump_file, stmt, 0); + print_gimple_stmt (dump_file, stmt, 0, 0); } - TREE_SET_CODE (GIMPLE_STMT_OPERAND (stmt, 1), PLUS_EXPR); - TREE_OPERAND (rhs, 1) = negate_value (TREE_OPERAND (rhs, 1), bsi); - + rhs2 = negate_value (rhs2, gsip); + gimple_assign_set_rhs_with_ops (gsip, PLUS_EXPR, rhs1, rhs2); update_stmt (stmt); } @@ -1122,19 +1125,18 @@ break_up_subtract (tree stmt, block_stmt_iterator *bsi) Place the operands of the expression tree in the vector named OPS. */ static void -linearize_expr_tree (VEC(operand_entry_t, heap) **ops, tree stmt) +linearize_expr_tree (VEC(operand_entry_t, heap) **ops, gimple stmt) { - block_stmt_iterator bsinow, bsilhs; - tree rhs = GENERIC_TREE_OPERAND (stmt, 1); - tree binrhs = TREE_OPERAND (rhs, 1); - tree binlhs = TREE_OPERAND (rhs, 0); - tree binlhsdef, binrhsdef; + gimple_stmt_iterator gsinow, gsilhs; + tree binlhs = gimple_assign_rhs1 (stmt); + tree binrhs = gimple_assign_rhs2 (stmt); + gimple binlhsdef, binrhsdef; bool binlhsisreassoc = false; bool binrhsisreassoc = false; - enum tree_code rhscode = TREE_CODE (rhs); + enum tree_code rhscode = gimple_assign_rhs_code (stmt); struct loop *loop = loop_containing_stmt (stmt); - TREE_VISITED (stmt) = 1; + gimple_set_visited (stmt, true); if (TREE_CODE (binlhs) == SSA_NAME) { @@ -1168,17 +1170,18 @@ linearize_expr_tree (VEC(operand_entry_t, heap) **ops, tree stmt) if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "swapping operands of "); - print_generic_expr (dump_file, stmt, 0); + print_gimple_stmt (dump_file, stmt, 0, 0); } - swap_tree_operands (stmt, &TREE_OPERAND (rhs, 0), - &TREE_OPERAND (rhs, 1)); + swap_tree_operands (stmt, + gimple_assign_rhs1_ptr (stmt), + gimple_assign_rhs2_ptr (stmt)); update_stmt (stmt); if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, " is now "); - print_generic_stmt (dump_file, stmt, 0); + print_gimple_stmt (dump_file, stmt, 0, 0); } /* We want to make it so the lhs is always the reassociative op, @@ -1190,17 +1193,16 @@ linearize_expr_tree (VEC(operand_entry_t, heap) **ops, tree stmt) else if (binrhsisreassoc) { linearize_expr (stmt); - gcc_assert (rhs == GIMPLE_STMT_OPERAND (stmt, 1)); - binlhs = TREE_OPERAND (rhs, 0); - binrhs = TREE_OPERAND (rhs, 1); + binlhs = gimple_assign_rhs1 (stmt); + binrhs = gimple_assign_rhs2 (stmt); } gcc_assert (TREE_CODE (binrhs) != SSA_NAME || !is_reassociable_op (SSA_NAME_DEF_STMT (binrhs), rhscode, loop)); - bsinow = bsi_for_stmt (stmt); - bsilhs = bsi_for_stmt (SSA_NAME_DEF_STMT (binlhs)); - bsi_move_before (&bsilhs, &bsinow); + gsinow = gsi_for_stmt (stmt); + gsilhs = gsi_for_stmt (SSA_NAME_DEF_STMT (binlhs)); + gsi_move_before (&gsilhs, &gsinow); linearize_expr_tree (ops, SSA_NAME_DEF_STMT (binlhs)); add_to_ops_vec (ops, binrhs); } @@ -1216,7 +1218,7 @@ repropagate_negates (void) for (i = 0; VEC_iterate (tree, broken_up_subtracts, i, negate); i++) { - tree user = get_single_immediate_use (negate); + gimple user = get_single_immediate_use (negate); /* The negate operand can be either operand of a PLUS_EXPR (it can be the LHS if the RHS is a constant for example). @@ -1224,27 +1226,27 @@ 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) == GIMPLE_MODIFY_STMT - && TREE_CODE (GIMPLE_STMT_OPERAND (user, 1)) == PLUS_EXPR) + && is_gimple_assign (user) + && gimple_assign_rhs_code (user) == PLUS_EXPR) { - 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 (GIMPLE_STMT_OPERAND (user, 1), 0) == negate) + if (gimple_assign_rhs1 (user) == negate) { - tree temp = TREE_OPERAND (rhs, 0); - TREE_OPERAND (rhs, 0) = TREE_OPERAND (rhs, 1); - TREE_OPERAND (rhs, 1) = temp; + swap_tree_operands (user, + gimple_assign_rhs1_ptr (user), + gimple_assign_rhs2_ptr (user)); } /* 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 (GIMPLE_STMT_OPERAND (user, 1), 1) == negate) + if (gimple_assign_rhs2 (user) == negate) { - TREE_SET_CODE (rhs, MINUS_EXPR); - TREE_OPERAND (rhs, 1) = get_unary_op (negate, NEGATE_EXPR); + tree rhs1 = gimple_assign_rhs1 (user); + tree rhs2 = get_unary_op (negate, NEGATE_EXPR); + gimple_stmt_iterator gsi = gsi_for_stmt (user); + gimple_assign_set_rhs_with_ops (&gsi, MINUS_EXPR, rhs1, rhs2); update_stmt (user); } } @@ -1264,43 +1266,50 @@ repropagate_negates (void) k = t - q we want to break up k = t - q, but we won't until we've transformed q - = b - r, which won't be broken up until we transform b = c - d. */ + = b - r, which won't be broken up until we transform b = c - d. + + En passant, clear the GIMPLE visited flag on every statement. */ static void break_up_subtract_bb (basic_block bb) { - block_stmt_iterator bsi; + gimple_stmt_iterator gsi; basic_block son; - for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi)) + for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) { - tree stmt = bsi_stmt (bsi); + gimple stmt = gsi_stmt (gsi); + gimple_set_visited (stmt, false); - if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT) + /* Look for simple gimple subtract operations. */ + if (is_gimple_assign (stmt) + && gimple_assign_rhs_code (stmt) == MINUS_EXPR) { - tree lhs = GIMPLE_STMT_OPERAND (stmt, 0); - tree rhs = GIMPLE_STMT_OPERAND (stmt, 1); + tree lhs = gimple_assign_lhs (stmt); + tree rhs1 = gimple_assign_rhs1 (stmt); + tree rhs2 = gimple_assign_rhs2 (stmt); - TREE_VISITED (stmt) = 0; /* If associative-math we can do reassociation for non-integral types. Or, we can do reassociation for non-saturating fixed-point types. */ if ((!INTEGRAL_TYPE_P (TREE_TYPE (lhs)) - || !INTEGRAL_TYPE_P (TREE_TYPE (rhs))) - && (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (rhs)) - || !SCALAR_FLOAT_TYPE_P (TREE_TYPE(lhs)) + || !INTEGRAL_TYPE_P (TREE_TYPE (rhs1)) + || !INTEGRAL_TYPE_P (TREE_TYPE (rhs2))) + && (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (lhs)) + || !SCALAR_FLOAT_TYPE_P (TREE_TYPE(rhs1)) + || !SCALAR_FLOAT_TYPE_P (TREE_TYPE(rhs2)) || !flag_associative_math) - && (!NON_SAT_FIXED_POINT_TYPE_P (TREE_TYPE (rhs)) - || !NON_SAT_FIXED_POINT_TYPE_P (TREE_TYPE(lhs)))) + && (!NON_SAT_FIXED_POINT_TYPE_P (TREE_TYPE (lhs)) + || !NON_SAT_FIXED_POINT_TYPE_P (TREE_TYPE(rhs1)) + || !NON_SAT_FIXED_POINT_TYPE_P (TREE_TYPE(rhs2)))) continue; /* Check for a subtract used only in an addition. If this is the case, transform it into add of a negate for better reassociation. IE transform C = A-B into C = A + -B if C is only used in an addition. */ - if (TREE_CODE (rhs) == MINUS_EXPR) - if (should_break_up_subtract (stmt)) - break_up_subtract (stmt, &bsi); + if (should_break_up_subtract (stmt)) + break_up_subtract (stmt, &gsi); } } for (son = first_dom_son (CDI_DOMINATORS, bb); @@ -1315,36 +1324,48 @@ break_up_subtract_bb (basic_block bb) static void reassociate_bb (basic_block bb) { - block_stmt_iterator bsi; + gimple_stmt_iterator gsi; basic_block son; - for (bsi = bsi_last (bb); !bsi_end_p (bsi); bsi_prev (&bsi)) + for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi_prev (&gsi)) { - tree stmt = bsi_stmt (bsi); + gimple stmt = gsi_stmt (gsi); - if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT) + if (is_gimple_assign (stmt)) { - tree lhs = GIMPLE_STMT_OPERAND (stmt, 0); - tree rhs = GIMPLE_STMT_OPERAND (stmt, 1); + tree lhs, rhs1, rhs2; + enum tree_code rhs_code = gimple_assign_rhs_code (stmt); - /* If this was part of an already processed tree, we don't - need to touch it again. */ - if (TREE_VISITED (stmt)) + /* If this is not a gimple binary expression, there is + nothing for us to do with it. */ + if (get_gimple_rhs_class (rhs_code) != GIMPLE_BINARY_RHS) continue; + /* If this was part of an already processed statement, + we don't need to touch it again. */ + if (gimple_visited_p (stmt)) + continue; + + lhs = gimple_assign_lhs (stmt); + rhs1 = gimple_assign_rhs1 (stmt); + rhs2 = gimple_assign_rhs2 (stmt); + /* If associative-math we can do reassociation for non-integral types. Or, we can do reassociation for non-saturating fixed-point types. */ if ((!INTEGRAL_TYPE_P (TREE_TYPE (lhs)) - || !INTEGRAL_TYPE_P (TREE_TYPE (rhs))) - && (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (rhs)) - || !SCALAR_FLOAT_TYPE_P (TREE_TYPE(lhs)) + || !INTEGRAL_TYPE_P (TREE_TYPE (rhs1)) + || !INTEGRAL_TYPE_P (TREE_TYPE (rhs2))) + && (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (lhs)) + || !SCALAR_FLOAT_TYPE_P (TREE_TYPE(rhs1)) + || !SCALAR_FLOAT_TYPE_P (TREE_TYPE(rhs2)) || !flag_associative_math) - && (!NON_SAT_FIXED_POINT_TYPE_P (TREE_TYPE (rhs)) - || !NON_SAT_FIXED_POINT_TYPE_P (TREE_TYPE(lhs)))) + && (!NON_SAT_FIXED_POINT_TYPE_P (TREE_TYPE (lhs)) + || !NON_SAT_FIXED_POINT_TYPE_P (TREE_TYPE(rhs1)) + || !NON_SAT_FIXED_POINT_TYPE_P (TREE_TYPE(rhs2)))) continue; - if (associative_tree_code (TREE_CODE (rhs))) + if (associative_tree_code (rhs_code)) { VEC(operand_entry_t, heap) *ops = NULL; @@ -1353,30 +1374,31 @@ reassociate_bb (basic_block bb) if (TREE_CODE (lhs) == SSA_NAME && has_zero_uses (lhs)) continue; - TREE_VISITED (stmt) = 1; + gimple_set_visited (stmt, true); linearize_expr_tree (&ops, stmt); qsort (VEC_address (operand_entry_t, ops), VEC_length (operand_entry_t, ops), sizeof (operand_entry_t), sort_by_operand_rank); - optimize_ops_list (TREE_CODE (rhs), &ops); + optimize_ops_list (rhs_code, &ops); if (VEC_length (operand_entry_t, ops) == 1) { if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "Transforming "); - print_generic_expr (dump_file, rhs, 0); + print_gimple_stmt (dump_file, stmt, 0, 0); } - GIMPLE_STMT_OPERAND (stmt, 1) - = VEC_last (operand_entry_t, ops)->op; + + gimple_assign_set_rhs_from_tree (&gsi, + 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, - GIMPLE_STMT_OPERAND (stmt, 1), 0); + print_gimple_stmt (dump_file, stmt, 0, 0); } } else @@ -1408,7 +1430,7 @@ dump_ops_vector (FILE *file, VEC (operand_entry_t, heap) *ops) for (i = 0; VEC_iterate (operand_entry_t, ops, i, oe); i++) { fprintf (file, "Op %d -> rank: %d, tree: ", i, oe->rank); - print_generic_stmt (file, oe->op, 0); + print_generic_expr (file, oe->op, 0); } } @@ -1542,3 +1564,4 @@ struct gimple_opt_pass pass_reassoc = TODO_dump_func | TODO_ggc_collect | TODO_verify_ssa /* todo_flags_finish */ } }; + |