X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Ftree-gimple.c;h=d1e47f65edab38c19c56f9799fc6d19524954bdd;hp=8f88f1d9866ee66790b765da4a7a1a823558fa0d;hb=df3ba0feef5d9404c65d8b38ca0b79b94ec7feff;hpb=1c6d350bdf1969384e29cda6125f9ea07e2877b5 diff --git a/gcc/tree-gimple.c b/gcc/tree-gimple.c index 8f88f1d9866..d1e47f65eda 100644 --- a/gcc/tree-gimple.c +++ b/gcc/tree-gimple.c @@ -8,7 +8,7 @@ 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 2, or (at your option) +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, @@ -17,9 +17,8 @@ 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 COPYING. If not, write to -the Free Software Foundation, 51 Franklin Street, Fifth Floor, -Boston, MA 02110-1301, USA. */ +along with GCC; see the file COPYING3. If not see +. */ #include "config.h" #include "system.h" @@ -62,12 +61,14 @@ is_gimple_formal_tmp_rhs (tree t) 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: @@ -170,7 +171,7 @@ is_gimple_addressable (tree t) form of function invariant. */ bool -is_gimple_min_invariant (tree t) +is_gimple_min_invariant (const_tree t) { switch (TREE_CODE (t)) { @@ -179,6 +180,7 @@ is_gimple_min_invariant (tree t) case INTEGER_CST: case REAL_CST: + case FIXED_CST: case STRING_CST: case COMPLEX_CST: case VECTOR_CST: @@ -201,7 +203,7 @@ is_gimple_min_invariant (tree t) bool is_gimple_stmt (tree t) { - enum tree_code code = TREE_CODE (t); + const enum tree_code code = TREE_CODE (t); switch (code) { @@ -231,6 +233,7 @@ is_gimple_stmt (tree t) case OMP_PARALLEL: case OMP_FOR: case OMP_SECTIONS: + case OMP_SECTIONS_SWITCH: case OMP_SECTION: case OMP_SINGLE: case OMP_MASTER: @@ -238,6 +241,8 @@ is_gimple_stmt (tree t) case OMP_CRITICAL: case OMP_RETURN: case OMP_CONTINUE: + case OMP_ATOMIC_LOAD: + case OMP_ATOMIC_STORE: /* These are always void. */ return true; @@ -280,7 +285,13 @@ is_gimple_id (tree t) bool is_gimple_reg_type (tree type) { - return !AGGREGATE_TYPE_P (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. */ @@ -323,8 +334,8 @@ is_gimple_reg (tree t) if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t)) return false; - /* Complex values must have been put into ssa form. That is, no - assignments to the individual components. */ + /* 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); @@ -519,3 +530,47 @@ recalculate_side_effects (tree t) 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)); + } + + /* A valid conditional for a COND_EXPR is either a gimple value + or a comparison with two gimple value operands. */ + if (is_gimple_val (t) + || (COMPARISON_CLASS_P (t) + && is_gimple_val (TREE_OPERAND (t, 0)) + && is_gimple_val (TREE_OPERAND (t, 1)))) + return t; + + return NULL_TREE; +}