diff options
author | Richard Biener <rguenth@gcc.gnu.org> | 2008-07-28 14:33:56 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2008-07-28 14:33:56 +0000 |
commit | 726a989a8b74bf238a96029860bcf7ba14eff317 (patch) | |
tree | 2926705dd533a8904679724ab1cec40dfee45094 /gcc/tree-gimple.c | |
parent | 0d48657d7378a4b1cb25ed181bca8020eae520f1 (diff) | |
download | gcc-726a989a8b74bf238a96029860bcf7ba14eff317.zip gcc-726a989a8b74bf238a96029860bcf7ba14eff317.tar.gz gcc-726a989a8b74bf238a96029860bcf7ba14eff317.tar.bz2 |
backport: ChangeLog.tuples: ChangeLog from gimple-tuples-branch.
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.
From-SVN: r138207
Diffstat (limited to 'gcc/tree-gimple.c')
-rw-r--r-- | gcc/tree-gimple.c | 653 |
1 files changed, 0 insertions, 653 deletions
diff --git a/gcc/tree-gimple.c b/gcc/tree-gimple.c deleted file mode 100644 index 8b05f93..0000000 --- a/gcc/tree-gimple.c +++ /dev/null @@ -1,653 +0,0 @@ -/* Functions to analyze and validate GIMPLE trees. - Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 - Free Software Foundation, Inc. - Contributed by Diego Novillo <dnovillo@redhat.com> - Rewritten by Jason Merrill <jason@redhat.com> - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3, or (at your option) -any later version. - -GCC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "ggc.h" -#include "tm.h" -#include "tree.h" -#include "tree-gimple.h" -#include "tree-flow.h" -#include "output.h" -#include "rtl.h" -#include "expr.h" -#include "bitmap.h" - -/* For the definitive definition of GIMPLE, see doc/tree-ssa.texi. */ - -/* Validation of GIMPLE expressions. */ - -/* Return true if T is a GIMPLE RHS for an assignment to a temporary. */ - -bool -is_gimple_formal_tmp_rhs (tree t) -{ - enum tree_code code = TREE_CODE (t); - - switch (TREE_CODE_CLASS (code)) - { - case tcc_unary: - case tcc_binary: - case tcc_comparison: - return true; - - default: - break; - } - - switch (code) - { - case TRUTH_NOT_EXPR: - case TRUTH_AND_EXPR: - case TRUTH_OR_EXPR: - case TRUTH_XOR_EXPR: - case COND_EXPR: - case ADDR_EXPR: - case CALL_EXPR: - case CONSTRUCTOR: - case COMPLEX_EXPR: - case INTEGER_CST: - case REAL_CST: - case FIXED_CST: - case STRING_CST: - case COMPLEX_CST: - case VECTOR_CST: - case OBJ_TYPE_REF: - case ASSERT_EXPR: - return true; - - default: - break; - } - - return is_gimple_lvalue (t) || is_gimple_val (t); -} - -/* Returns true iff T is a valid RHS for an assignment to a renamed - user -- or front-end generated artificial -- variable. */ - -bool -is_gimple_reg_rhs (tree t) -{ - /* If the RHS of the GIMPLE_MODIFY_STMT may throw or make a nonlocal goto - and the LHS is a user variable, then we need to introduce a formal - temporary. This way the optimizers can determine that the user - variable is only modified if evaluation of the RHS does not throw. - - Don't force a temp of a non-renamable type; the copy could be - arbitrarily expensive. Instead we will generate a VDEF for - the assignment. */ - - if (is_gimple_reg_type (TREE_TYPE (t)) - && ((TREE_CODE (t) == CALL_EXPR && TREE_SIDE_EFFECTS (t)) - || tree_could_throw_p (t))) - return false; - - return is_gimple_formal_tmp_rhs (t); -} - -/* Returns true iff T is a valid RHS for an assignment to an un-renamed - LHS, or for a call argument. */ - -bool -is_gimple_mem_rhs (tree t) -{ - /* If we're dealing with a renamable type, either source or dest must be - a renamed variable. */ - if (is_gimple_reg_type (TREE_TYPE (t))) - return is_gimple_val (t); - else - return is_gimple_formal_tmp_rhs (t); -} - -/* Returns the appropriate RHS predicate for this LHS. */ - -gimple_predicate -rhs_predicate_for (tree lhs) -{ - if (is_gimple_formal_tmp_var (lhs)) - return is_gimple_formal_tmp_rhs; - else if (is_gimple_reg (lhs)) - return is_gimple_reg_rhs; - else - return is_gimple_mem_rhs; -} - -/* Return true if T is a valid LHS for a GIMPLE assignment expression. */ - -bool -is_gimple_lvalue (tree t) -{ - return (is_gimple_addressable (t) - || TREE_CODE (t) == WITH_SIZE_EXPR - /* These are complex lvalues, but don't have addresses, so they - go here. */ - || TREE_CODE (t) == BIT_FIELD_REF); -} - -/* Return true if T is a GIMPLE condition. */ - -bool -is_gimple_condexpr (tree t) -{ - return (is_gimple_val (t) || (COMPARISON_CLASS_P (t) - && !tree_could_trap_p (t) - && is_gimple_val (TREE_OPERAND (t, 0)) - && is_gimple_val (TREE_OPERAND (t, 1)))); -} - -/* Return true if T is something whose address can be taken. */ - -bool -is_gimple_addressable (tree t) -{ - return (is_gimple_id (t) || handled_component_p (t) - || INDIRECT_REF_P (t)); -} - -/* Return true if T is a valid gimple constant. */ - -bool -is_gimple_constant (const_tree t) -{ - switch (TREE_CODE (t)) - { - case INTEGER_CST: - case REAL_CST: - case FIXED_CST: - case STRING_CST: - case COMPLEX_CST: - case VECTOR_CST: - return true; - - /* Vector constant constructors are gimple invariant. */ - case CONSTRUCTOR: - if (TREE_TYPE (t) && TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE) - return TREE_CONSTANT (t); - else - return false; - - default: - return false; - } -} - -/* Return true if T is a gimple address. */ - -bool -is_gimple_address (const_tree t) -{ - tree op; - - if (TREE_CODE (t) != ADDR_EXPR) - return false; - - op = TREE_OPERAND (t, 0); - while (handled_component_p (op)) - { - if ((TREE_CODE (op) == ARRAY_REF - || TREE_CODE (op) == ARRAY_RANGE_REF) - && !is_gimple_val (TREE_OPERAND (op, 1))) - return false; - - op = TREE_OPERAND (op, 0); - } - - if (CONSTANT_CLASS_P (op) || INDIRECT_REF_P (op)) - return true; - - switch (TREE_CODE (op)) - { - case PARM_DECL: - case RESULT_DECL: - case LABEL_DECL: - case FUNCTION_DECL: - case VAR_DECL: - case CONST_DECL: - return true; - - default: - return false; - } -} - -/* Return true if T is a gimple invariant address. */ - -bool -is_gimple_invariant_address (const_tree t) -{ - tree op; - - if (TREE_CODE (t) != ADDR_EXPR) - return false; - - op = TREE_OPERAND (t, 0); - while (handled_component_p (op)) - { - switch (TREE_CODE (op)) - { - case ARRAY_REF: - case ARRAY_RANGE_REF: - if (!is_gimple_constant (TREE_OPERAND (op, 1)) - || TREE_OPERAND (op, 2) != NULL_TREE - || TREE_OPERAND (op, 3) != NULL_TREE) - return false; - break; - - case COMPONENT_REF: - if (TREE_OPERAND (op, 2) != NULL_TREE) - return false; - break; - - default:; - } - op = TREE_OPERAND (op, 0); - } - - return CONSTANT_CLASS_P (op) || decl_address_invariant_p (op); -} - -/* Return true if T is a GIMPLE minimal invariant. It's a restricted - form of function invariant. */ - -bool -is_gimple_min_invariant (const_tree t) -{ - if (TREE_CODE (t) == ADDR_EXPR) - return is_gimple_invariant_address (t); - - return is_gimple_constant (t); -} - -/* Return true if T looks like a valid GIMPLE statement. */ - -bool -is_gimple_stmt (tree t) -{ - const enum tree_code code = TREE_CODE (t); - - switch (code) - { - case NOP_EXPR: - /* The only valid NOP_EXPR is the empty statement. */ - return IS_EMPTY_STMT (t); - - case BIND_EXPR: - case COND_EXPR: - /* These are only valid if they're void. */ - return TREE_TYPE (t) == NULL || VOID_TYPE_P (TREE_TYPE (t)); - - case SWITCH_EXPR: - case GOTO_EXPR: - case RETURN_EXPR: - case LABEL_EXPR: - case CASE_LABEL_EXPR: - case TRY_CATCH_EXPR: - case TRY_FINALLY_EXPR: - case EH_FILTER_EXPR: - case CATCH_EXPR: - case CHANGE_DYNAMIC_TYPE_EXPR: - case ASM_EXPR: - case RESX_EXPR: - case PHI_NODE: - case STATEMENT_LIST: - case OMP_PARALLEL: - case OMP_FOR: - case OMP_SECTIONS: - case OMP_SECTIONS_SWITCH: - case OMP_SECTION: - case OMP_SINGLE: - case OMP_MASTER: - case OMP_ORDERED: - case OMP_CRITICAL: - case OMP_RETURN: - case OMP_CONTINUE: - case OMP_TASK: - case OMP_ATOMIC_LOAD: - case OMP_ATOMIC_STORE: - /* These are always void. */ - return true; - - case CALL_EXPR: - case GIMPLE_MODIFY_STMT: - case PREDICT_EXPR: - /* These are valid regardless of their type. */ - return true; - - default: - return false; - } -} - -/* Return true if T is a variable. */ - -bool -is_gimple_variable (tree t) -{ - return (TREE_CODE (t) == VAR_DECL - || TREE_CODE (t) == PARM_DECL - || TREE_CODE (t) == RESULT_DECL - || TREE_CODE (t) == SSA_NAME); -} - -/* Return true if T is a GIMPLE identifier (something with an address). */ - -bool -is_gimple_id (tree t) -{ - return (is_gimple_variable (t) - || TREE_CODE (t) == FUNCTION_DECL - || TREE_CODE (t) == LABEL_DECL - || TREE_CODE (t) == CONST_DECL - /* Allow string constants, since they are addressable. */ - || TREE_CODE (t) == STRING_CST); -} - -/* Return true if TYPE is a suitable type for a scalar register variable. */ - -bool -is_gimple_reg_type (tree type) -{ - /* In addition to aggregate types, we also exclude complex types if not - optimizing because they can be subject to partial stores in GNU C by - means of the __real__ and __imag__ operators and we cannot promote - them to total stores (see gimplify_modify_expr_complex_part). */ - return !(AGGREGATE_TYPE_P (type) - || (TREE_CODE (type) == COMPLEX_TYPE && !optimize)); - -} - -/* Return true if T is a non-aggregate register variable. */ - -bool -is_gimple_reg (tree t) -{ - if (TREE_CODE (t) == SSA_NAME) - t = SSA_NAME_VAR (t); - - if (MTAG_P (t)) - return false; - - if (!is_gimple_variable (t)) - return false; - - if (!is_gimple_reg_type (TREE_TYPE (t))) - return false; - - /* A volatile decl is not acceptable because we can't reuse it as - needed. We need to copy it into a temp first. */ - if (TREE_THIS_VOLATILE (t)) - return false; - - /* We define "registers" as things that can be renamed as needed, - which with our infrastructure does not apply to memory. */ - if (needs_to_live_in_memory (t)) - return false; - - /* Hard register variables are an interesting case. For those that - are call-clobbered, we don't know where all the calls are, since - we don't (want to) take into account which operations will turn - into libcalls at the rtl level. For those that are call-saved, - we don't currently model the fact that calls may in fact change - global hard registers, nor do we examine ASM_CLOBBERS at the tree - level, and so miss variable changes that might imply. All around, - it seems safest to not do too much optimization with these at the - tree level at all. We'll have to rely on the rtl optimizers to - clean this up, as there we've got all the appropriate bits exposed. */ - if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t)) - return false; - - /* Complex and vector values must have been put into SSA-like form. - That is, no assignments to the individual components. */ - if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE - || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE) - return DECL_GIMPLE_REG_P (t); - - return true; -} - - -/* Returns true if T is a GIMPLE formal temporary variable. */ - -bool -is_gimple_formal_tmp_var (tree t) -{ - if (TREE_CODE (t) == SSA_NAME) - return true; - - return TREE_CODE (t) == VAR_DECL && DECL_GIMPLE_FORMAL_TEMP_P (t); -} - -/* Returns true if T is a GIMPLE formal temporary register variable. */ - -bool -is_gimple_formal_tmp_reg (tree t) -{ - /* The intent of this is to get hold of a value that won't change. - An SSA_NAME qualifies no matter if its of a user variable or not. */ - if (TREE_CODE (t) == SSA_NAME) - return true; - - /* We don't know the lifetime characteristics of user variables. */ - if (!is_gimple_formal_tmp_var (t)) - return false; - - /* Finally, it must be capable of being placed in a register. */ - return is_gimple_reg (t); -} - -/* Return true if T is a GIMPLE variable whose address is not needed. */ - -bool -is_gimple_non_addressable (tree t) -{ - if (TREE_CODE (t) == SSA_NAME) - t = SSA_NAME_VAR (t); - - return (is_gimple_variable (t) && ! needs_to_live_in_memory (t)); -} - -/* Return true if T is a GIMPLE rvalue, i.e. an identifier or a constant. */ - -bool -is_gimple_val (tree t) -{ - /* Make loads from volatiles and memory vars explicit. */ - if (is_gimple_variable (t) - && is_gimple_reg_type (TREE_TYPE (t)) - && !is_gimple_reg (t)) - return false; - - /* FIXME make these decls. That can happen only when we expose the - entire landing-pad construct at the tree level. */ - if (TREE_CODE (t) == EXC_PTR_EXPR || TREE_CODE (t) == FILTER_EXPR) - return true; - - return (is_gimple_variable (t) || is_gimple_min_invariant (t)); -} - -/* Similarly, but accept hard registers as inputs to asm statements. */ - -bool -is_gimple_asm_val (tree t) -{ - if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t)) - return true; - - return is_gimple_val (t); -} - -/* Return true if T is a GIMPLE minimal lvalue. */ - -bool -is_gimple_min_lval (tree t) -{ - return (is_gimple_id (t) - || TREE_CODE (t) == INDIRECT_REF); -} - -/* Return true if T is a typecast operation. */ - -bool -is_gimple_cast (tree t) -{ - return (CONVERT_EXPR_P (t) - || TREE_CODE (t) == FIX_TRUNC_EXPR); -} - -/* Return true if T is a valid function operand of a CALL_EXPR. */ - -bool -is_gimple_call_addr (tree t) -{ - return (TREE_CODE (t) == OBJ_TYPE_REF - || is_gimple_val (t)); -} - -/* If T makes a function call, return the corresponding CALL_EXPR operand. - Otherwise, return NULL_TREE. */ - -tree -get_call_expr_in (tree t) -{ - /* FIXME tuples: delete the assertion below when conversion complete. */ - gcc_assert (TREE_CODE (t) != MODIFY_EXPR); - if (TREE_CODE (t) == GIMPLE_MODIFY_STMT) - t = GIMPLE_STMT_OPERAND (t, 1); - if (TREE_CODE (t) == WITH_SIZE_EXPR) - t = TREE_OPERAND (t, 0); - if (TREE_CODE (t) == CALL_EXPR) - return t; - return NULL_TREE; -} - -/* Given a memory reference expression T, return its base address. - The base address of a memory reference expression is the main - object being referenced. For instance, the base address for - 'array[i].fld[j]' is 'array'. You can think of this as stripping - away the offset part from a memory address. - - This function calls handled_component_p to strip away all the inner - parts of the memory reference until it reaches the base object. */ - -tree -get_base_address (tree t) -{ - while (handled_component_p (t)) - t = TREE_OPERAND (t, 0); - - if (SSA_VAR_P (t) - || TREE_CODE (t) == STRING_CST - || TREE_CODE (t) == CONSTRUCTOR - || INDIRECT_REF_P (t)) - return t; - else - return NULL_TREE; -} - -void -recalculate_side_effects (tree t) -{ - enum tree_code code = TREE_CODE (t); - int len = TREE_OPERAND_LENGTH (t); - int i; - - switch (TREE_CODE_CLASS (code)) - { - case tcc_expression: - switch (code) - { - case INIT_EXPR: - case GIMPLE_MODIFY_STMT: - case VA_ARG_EXPR: - case PREDECREMENT_EXPR: - case PREINCREMENT_EXPR: - case POSTDECREMENT_EXPR: - case POSTINCREMENT_EXPR: - /* All of these have side-effects, no matter what their - operands are. */ - return; - - default: - break; - } - /* Fall through. */ - - case tcc_comparison: /* a comparison expression */ - case tcc_unary: /* a unary arithmetic expression */ - case tcc_binary: /* a binary arithmetic expression */ - case tcc_reference: /* a reference */ - case tcc_vl_exp: /* a function call */ - TREE_SIDE_EFFECTS (t) = TREE_THIS_VOLATILE (t); - for (i = 0; i < len; ++i) - { - tree op = TREE_OPERAND (t, i); - if (op && TREE_SIDE_EFFECTS (op)) - TREE_SIDE_EFFECTS (t) = 1; - } - break; - - default: - /* Can never be used with non-expressions. */ - gcc_unreachable (); - } -} - -/* Canonicalize a tree T for use in a COND_EXPR as conditional. Returns - a canonicalized tree that is valid for a COND_EXPR or NULL_TREE, if - we failed to create one. */ - -tree -canonicalize_cond_expr_cond (tree t) -{ - /* For (bool)x use x != 0. */ - if (TREE_CODE (t) == NOP_EXPR - && TREE_TYPE (t) == boolean_type_node) - { - tree top0 = TREE_OPERAND (t, 0); - t = build2 (NE_EXPR, TREE_TYPE (t), - top0, build_int_cst (TREE_TYPE (top0), 0)); - } - /* For !x use x == 0. */ - else if (TREE_CODE (t) == TRUTH_NOT_EXPR) - { - tree top0 = TREE_OPERAND (t, 0); - t = build2 (EQ_EXPR, TREE_TYPE (t), - top0, build_int_cst (TREE_TYPE (top0), 0)); - } - /* For cmp ? 1 : 0 use cmp. */ - else if (TREE_CODE (t) == COND_EXPR - && COMPARISON_CLASS_P (TREE_OPERAND (t, 0)) - && integer_onep (TREE_OPERAND (t, 1)) - && integer_zerop (TREE_OPERAND (t, 2))) - { - tree top0 = TREE_OPERAND (t, 0); - t = build2 (TREE_CODE (top0), TREE_TYPE (t), - TREE_OPERAND (top0, 0), TREE_OPERAND (top0, 1)); - } - - if (is_gimple_condexpr (t)) - return t; - - return NULL_TREE; -} |