diff options
author | amacleod <amacleod@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-11-14 19:39:38 +0000 |
---|---|---|
committer | amacleod <amacleod@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-11-14 19:39:38 +0000 |
commit | e795d6e1ee8dd07622360c17bccdf047d632b95b (patch) | |
tree | c74c4d1bb5473fdc2c9d6c2a6ad1153f0c1c25de /gcc/gimplify.c | |
parent | 983454618104a3e8beefa2fc56d7d3413d4b8b59 (diff) | |
download | gcc-e795d6e1ee8dd07622360c17bccdf047d632b95b.tar.gz |
* gimplify-be.h: New file. Add prototypes.
* gimplify.h: Don't include gimple.h.
(struct gimplify_hasher, struct gimplify_ctx, is_gimple_sizepos,
gimplify_hasher::hash, gimplify_hasher::equal): Relocate from gimple.h.
* gimple.h (struct gimplify_hasher, gimplify_hasher::hash,
gimplify_hasher::equal, struct gimplify_ctx, is_gimple_sizepos): Move
to gimplify.h.
(enum gsi_iterator_update): Move to gimple-iterator.h.
* gimple-iterator.h (enum gsi_iterator_update): Relocate from gimple.h.
* gimplify-be.c: New File.
(force_gimple_operand_1, force_gimple_operand,
force_gimple_operand_gsi_1, force_gimple_operand_gsi): Relocate from
gimplify.c.
* gimplify.c (force_gimple_operand_1, force_gimple_operand,
force_gimple_operand_gsi_1, force_gimple_operand_gsi): Move to
gimplify-be.c.
* Makefile.in (OBJS): Add gimplify-be.o
* asan.c: Include only gimplify.h, gimplify-be.h, and/or gimple.h as
required.
* cfgloopmanip.c: Likewise.
* cgraphunit.c: Likewise.
* cilk-common.c: Likewise.
* fold-const.c: Likewise.
* function.c: Likewise.
* gimple-expr.c: Likewise.
* gimple-fold.c: Likewise.
* gimple-ssa-strength-reduction.c: Likewise.
* gimple.c: Likewise.
* graphite-clast-to-gimple.c: Likewise.
* graphite-sese-to-poly.c: Likewise.
* ipa-prop.c: Likewise.
* ipa-split.c: Likewise.
* ipa.c: Likewise.
* langhooks.c: Likewise.
* omp-low.c: Likewise.
* sese.c: Likewise.
* stor-layout.c: Likewise.
* targhooks.c: Likewise.
* trans-mem.c: Likewise.
* tree-affine.c: Likewise.
* tree-cfg.c: Likewise.
* tree-cfgcleanup.c: Likewise.
* tree-complex.c: Likewise.
* tree-if-conv.c: Likewise.
* tree-inline.c: Likewise.
* tree-loop-distribution.c: Likewise.
* tree-nested.c: Likewise.
* tree-parloops.c: Likewise.
* tree-predcom.c: Likewise.
* tree-profile.c: Likewise.
* tree-scalar-evolution.c: Likewise.
* tree-sra.c: Likewise.
* tree-ssa-address.c: Likewise.
* tree-ssa-ccp.c: Likewise.
* tree-ssa-dce.c: Likewise.
* tree-ssa-forwprop.c: Likewise.
* tree-ssa-ifcombine.c: Likewise.
* tree-ssa-loop-im.c: Likewise.
* tree-ssa-loop-ivopts.c: Likewise.
* tree-ssa-loop-manip.c: Likewise.
* tree-ssa-loop-niter.c: Likewise.
* tree-ssa-loop-prefetch.c: Likewise.
* tree-ssa-loop-unswitch.c: Likewise.
* tree-ssa-math-opts.c: Likewise.
* tree-ssa-phiopt.c: Likewise.
* tree-ssa-phiprop.c: Likewise.
* tree-ssa-pre.c: Likewise.
* tree-ssa-propagate.c: Likewise.
* tree-ssa-reassoc.c: Likewise.
* tree-ssa-sccvn.c: Likewise.
* tree-ssa-strlen.c: Likewise.
* tree-ssa.c: Likewise.
* tree-switch-conversion.c: Likewise.
* tree-tailcall.c: Likewise.
* tree-vect-data-refs.c: Likewise.
* tree-vect-generic.c: Likewise.
* tree-vect-loop-manip.c: Likewise.
* tree-vect-loop.c: Likewise.
* tree-vect-patterns.c: Likewise.
* tree-vect-stmts.c: Likewise.
* tree.c: Likewise.
* tsan.c: Likewise.
* value-prof.c: Likewise.
* config/aarch64/aarch64.c: Likewise.
* config/alpha/alpha.c: Likewise.
* config/darwin.c: Likewise.
* config/i386/i386.c: Likewise.
* config/ia64/ia64.c: Likewise.
* config/mep/mep.c: Likewise.
* config/mips/mips.c: Likewise.
* config/rs6000/rs6000.c: Likewise.
* config/s390/s390.c: Likewise.
* config/sh/sh.c: Likewise.
* config/sparc/sparc.c: Likewise.
* config/spu/spu.c: Likewise.
* config/stormy16/stormy16.c: Likewise.
* config/tilegx/tilegx.c: Likewise.
* config/tilepro/tilepro.c: Likewise.
* config/xtensa/xtensa.c: Likewise.
* c/c-typeck.c: Include only gimplify.h and gimple.h as needed.
* c-family/c-common.c: Likewise.
* c-family/c-gimplify.c: Likewise.
* c-family/cilk.c: Likewise.
* cp/class.c: Include only gimplify.h and gimple.h as needed.
* cp/cp-gimplify.c: Likewise.
* cp/error.c: Likewise.
* cp/init.c: Likewise.
* cp/optimize.c: Likewise.
* cp/pt.c: Likewise.
* cp/semantics.c: Likewise.
* cp/tree.c: Likewise.
* cp/vtable-class-hierarchy.c: Likewise.
* fortran/trans-expr.c: Include only gimplify.h and gimple.h as needed.
* fortran/trans-openmp.c: Likewise.
* go/go-lang.c: Include only gimplify.h and gimple.h as needed.
* java/java-gimplify.c: Include only gimplify.h and gimple.h as needed.
* objc/objc-act.c: Include only gimplify.h and gimple.h as needed.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@204812 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/gimplify.c')
-rw-r--r-- | gcc/gimplify.c | 325 |
1 files changed, 32 insertions, 293 deletions
diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 3253f861958..4e6f44898ba 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -23,8 +23,8 @@ along with GCC; see the file COPYING3. If not see #include "config.h" #include "system.h" #include "coretypes.h" -#include "tm.h" #include "tree.h" +#include "gimple.h" #include "gimplify.h" #include "gimple-iterator.h" #include "tree-iterator.h" @@ -37,24 +37,15 @@ along with GCC; see the file COPYING3. If not see #include "tree-cfg.h" #include "tree-ssanames.h" #include "tree-ssa.h" -#include "timevar.h" -#include "hashtab.h" -#include "flags.h" -#include "function.h" -#include "ggc.h" #include "diagnostic-core.h" #include "target.h" -#include "pointer-set.h" #include "splay-tree.h" -#include "vec.h" #include "omp-low.h" #include "gimple-low.h" #include "cilk.h" #include "langhooks-def.h" /* FIXME: for lhd_set_decl_assembler_name */ #include "tree-pass.h" /* FIXME: only for PROP_gimple_any */ -#include "expr.h" -#include "tm_p.h" enum gimplify_omp_var_data { @@ -102,7 +93,7 @@ struct gimplify_omp_ctx bool combined_loop; }; -static struct gimplify_ctx *gimplify_ctxp; +struct gimplify_ctx *gimplify_ctxp; static struct gimplify_omp_ctx *gimplify_omp_ctxp; @@ -3393,7 +3384,7 @@ gimplify_init_ctor_eval (tree object, vec<constructor_elt, va_gc> *elts, /* Return the appropriate RHS predicate for this LHS. */ -static gimple_predicate +gimple_predicate rhs_predicate_for (tree lhs) { if (is_gimple_reg (lhs)) @@ -8590,287 +8581,6 @@ gimplify_function_tree (tree fndecl) pop_cfun (); } -/* Some transformations like inlining may invalidate the GIMPLE form - for operands. This function traverses all the operands in STMT and - gimplifies anything that is not a valid gimple operand. Any new - GIMPLE statements are inserted before *GSI_P. */ - -void -gimple_regimplify_operands (gimple stmt, gimple_stmt_iterator *gsi_p) -{ - size_t i, num_ops; - tree lhs; - gimple_seq pre = NULL; - gimple post_stmt = NULL; - struct gimplify_ctx gctx; - - push_gimplify_context (&gctx); - gimplify_ctxp->into_ssa = gimple_in_ssa_p (cfun); - - switch (gimple_code (stmt)) - { - case GIMPLE_COND: - gimplify_expr (gimple_cond_lhs_ptr (stmt), &pre, NULL, - is_gimple_val, fb_rvalue); - gimplify_expr (gimple_cond_rhs_ptr (stmt), &pre, NULL, - is_gimple_val, fb_rvalue); - break; - case GIMPLE_SWITCH: - gimplify_expr (gimple_switch_index_ptr (stmt), &pre, NULL, - is_gimple_val, fb_rvalue); - break; - case GIMPLE_OMP_ATOMIC_LOAD: - gimplify_expr (gimple_omp_atomic_load_rhs_ptr (stmt), &pre, NULL, - is_gimple_val, fb_rvalue); - break; - case GIMPLE_ASM: - { - size_t i, noutputs = gimple_asm_noutputs (stmt); - const char *constraint, **oconstraints; - bool allows_mem, allows_reg, is_inout; - - oconstraints - = (const char **) alloca ((noutputs) * sizeof (const char *)); - for (i = 0; i < noutputs; i++) - { - tree op = gimple_asm_output_op (stmt, i); - constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op))); - oconstraints[i] = constraint; - parse_output_constraint (&constraint, i, 0, 0, &allows_mem, - &allows_reg, &is_inout); - gimplify_expr (&TREE_VALUE (op), &pre, NULL, - is_inout ? is_gimple_min_lval : is_gimple_lvalue, - fb_lvalue | fb_mayfail); - } - for (i = 0; i < gimple_asm_ninputs (stmt); i++) - { - tree op = gimple_asm_input_op (stmt, i); - constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op))); - parse_input_constraint (&constraint, 0, 0, noutputs, 0, - oconstraints, &allows_mem, &allows_reg); - if (TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (op))) && allows_mem) - allows_reg = 0; - if (!allows_reg && allows_mem) - gimplify_expr (&TREE_VALUE (op), &pre, NULL, - is_gimple_lvalue, fb_lvalue | fb_mayfail); - else - gimplify_expr (&TREE_VALUE (op), &pre, NULL, - is_gimple_asm_val, fb_rvalue); - } - } - break; - default: - /* NOTE: We start gimplifying operands from last to first to - make sure that side-effects on the RHS of calls, assignments - and ASMs are executed before the LHS. The ordering is not - important for other statements. */ - num_ops = gimple_num_ops (stmt); - for (i = num_ops; i > 0; i--) - { - tree op = gimple_op (stmt, i - 1); - if (op == NULL_TREE) - continue; - if (i == 1 && (is_gimple_call (stmt) || is_gimple_assign (stmt))) - gimplify_expr (&op, &pre, NULL, is_gimple_lvalue, fb_lvalue); - else if (i == 2 - && is_gimple_assign (stmt) - && num_ops == 2 - && get_gimple_rhs_class (gimple_expr_code (stmt)) - == GIMPLE_SINGLE_RHS) - gimplify_expr (&op, &pre, NULL, - rhs_predicate_for (gimple_assign_lhs (stmt)), - fb_rvalue); - else if (i == 2 && is_gimple_call (stmt)) - { - if (TREE_CODE (op) == FUNCTION_DECL) - continue; - gimplify_expr (&op, &pre, NULL, is_gimple_call_addr, fb_rvalue); - } - else - gimplify_expr (&op, &pre, NULL, is_gimple_val, fb_rvalue); - gimple_set_op (stmt, i - 1, op); - } - - lhs = gimple_get_lhs (stmt); - /* If the LHS changed it in a way that requires a simple RHS, - create temporary. */ - if (lhs && !is_gimple_reg (lhs)) - { - bool need_temp = false; - - if (is_gimple_assign (stmt) - && num_ops == 2 - && get_gimple_rhs_class (gimple_expr_code (stmt)) - == GIMPLE_SINGLE_RHS) - gimplify_expr (gimple_assign_rhs1_ptr (stmt), &pre, NULL, - rhs_predicate_for (gimple_assign_lhs (stmt)), - fb_rvalue); - else if (is_gimple_reg (lhs)) - { - if (is_gimple_reg_type (TREE_TYPE (lhs))) - { - if (is_gimple_call (stmt)) - { - i = gimple_call_flags (stmt); - if ((i & ECF_LOOPING_CONST_OR_PURE) - || !(i & (ECF_CONST | ECF_PURE))) - need_temp = true; - } - if (stmt_can_throw_internal (stmt)) - need_temp = true; - } - } - else - { - if (is_gimple_reg_type (TREE_TYPE (lhs))) - need_temp = true; - else if (TYPE_MODE (TREE_TYPE (lhs)) != BLKmode) - { - if (is_gimple_call (stmt)) - { - tree fndecl = gimple_call_fndecl (stmt); - - if (!aggregate_value_p (TREE_TYPE (lhs), fndecl) - && !(fndecl && DECL_RESULT (fndecl) - && DECL_BY_REFERENCE (DECL_RESULT (fndecl)))) - need_temp = true; - } - else - need_temp = true; - } - } - if (need_temp) - { - tree temp = create_tmp_reg (TREE_TYPE (lhs), NULL); - if (gimple_in_ssa_p (cfun)) - temp = make_ssa_name (temp, NULL); - gimple_set_lhs (stmt, temp); - post_stmt = gimple_build_assign (lhs, temp); - } - } - break; - } - - if (!gimple_seq_empty_p (pre)) - gsi_insert_seq_before (gsi_p, pre, GSI_SAME_STMT); - if (post_stmt) - gsi_insert_after (gsi_p, post_stmt, GSI_NEW_STMT); - - pop_gimplify_context (NULL); -} - -/* Expand EXPR to list of gimple statements STMTS. GIMPLE_TEST_F specifies - the predicate that will hold for the result. If VAR is not NULL, make the - base variable of the final destination be VAR if suitable. */ - -tree -force_gimple_operand_1 (tree expr, gimple_seq *stmts, - gimple_predicate gimple_test_f, tree var) -{ - enum gimplify_status ret; - struct gimplify_ctx gctx; - location_t saved_location; - - *stmts = NULL; - - /* gimple_test_f might be more strict than is_gimple_val, make - sure we pass both. Just checking gimple_test_f doesn't work - because most gimple predicates do not work recursively. */ - if (is_gimple_val (expr) - && (*gimple_test_f) (expr)) - return expr; - - push_gimplify_context (&gctx); - gimplify_ctxp->into_ssa = gimple_in_ssa_p (cfun); - gimplify_ctxp->allow_rhs_cond_expr = true; - saved_location = input_location; - input_location = UNKNOWN_LOCATION; - - if (var) - { - if (gimplify_ctxp->into_ssa - && is_gimple_reg (var)) - var = make_ssa_name (var, NULL); - expr = build2 (MODIFY_EXPR, TREE_TYPE (var), var, expr); - } - - if (TREE_CODE (expr) != MODIFY_EXPR - && TREE_TYPE (expr) == void_type_node) - { - gimplify_and_add (expr, stmts); - expr = NULL_TREE; - } - else - { - ret = gimplify_expr (&expr, stmts, NULL, gimple_test_f, fb_rvalue); - gcc_assert (ret != GS_ERROR); - } - - input_location = saved_location; - pop_gimplify_context (NULL); - - return expr; -} - -/* Expand EXPR to list of gimple statements STMTS. If SIMPLE is true, - force the result to be either ssa_name or an invariant, otherwise - just force it to be a rhs expression. If VAR is not NULL, make the - base variable of the final destination be VAR if suitable. */ - -tree -force_gimple_operand (tree expr, gimple_seq *stmts, bool simple, tree var) -{ - return force_gimple_operand_1 (expr, stmts, - simple ? is_gimple_val : is_gimple_reg_rhs, - var); -} - -/* Invoke force_gimple_operand_1 for EXPR with parameters GIMPLE_TEST_F - and VAR. If some statements are produced, emits them at GSI. - If BEFORE is true. the statements are appended before GSI, otherwise - they are appended after it. M specifies the way GSI moves after - insertion (GSI_SAME_STMT or GSI_CONTINUE_LINKING are the usual values). */ - -tree -force_gimple_operand_gsi_1 (gimple_stmt_iterator *gsi, tree expr, - gimple_predicate gimple_test_f, - tree var, bool before, - enum gsi_iterator_update m) -{ - gimple_seq stmts; - - expr = force_gimple_operand_1 (expr, &stmts, gimple_test_f, var); - - if (!gimple_seq_empty_p (stmts)) - { - if (before) - gsi_insert_seq_before (gsi, stmts, m); - else - gsi_insert_seq_after (gsi, stmts, m); - } - - return expr; -} - -/* Invoke force_gimple_operand_1 for EXPR with parameter VAR. - If SIMPLE is true, force the result to be either ssa_name or an invariant, - otherwise just force it to be a rhs expression. If some statements are - produced, emits them at GSI. If BEFORE is true, the statements are - appended before GSI, otherwise they are appended after it. M specifies - the way GSI moves after insertion (GSI_SAME_STMT or GSI_CONTINUE_LINKING - are the usual values). */ - -tree -force_gimple_operand_gsi (gimple_stmt_iterator *gsi, tree expr, - bool simple_p, tree var, bool before, - enum gsi_iterator_update m) -{ - return force_gimple_operand_gsi_1 (gsi, expr, - simple_p - ? is_gimple_val : is_gimple_reg_rhs, - var, before, m); -} - /* Return a dummy expression of type TYPE in order to keep going after an error. */ @@ -8991,3 +8701,32 @@ gimplify_assign (tree dst, tree src, gimple_seq *seq_p) return gimple_seq_last_stmt (*seq_p); } +inline hashval_t +gimplify_hasher::hash (const value_type *p) +{ + tree t = p->val; + return iterative_hash_expr (t, 0); +} + +inline bool +gimplify_hasher::equal (const value_type *p1, const compare_type *p2) +{ + tree t1 = p1->val; + tree t2 = p2->val; + enum tree_code code = TREE_CODE (t1); + + if (TREE_CODE (t2) != code + || TREE_TYPE (t1) != TREE_TYPE (t2)) + return false; + + if (!operand_equal_p (t1, t2, 0)) + return false; + +#ifdef ENABLE_CHECKING + /* Only allow them to compare equal if they also hash equal; otherwise + results are nondeterminate, and we fail bootstrap comparison. */ + gcc_assert (hash (p1) == hash (p2)); +#endif + + return true; +} |