diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-11-05 22:25:29 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-11-05 22:25:29 +0000 |
commit | 7deddfded2d013c07a639873a4c90bfed40fd03e (patch) | |
tree | 3df2a52207fec5bec55c28303aa57a8bd9b4e620 /gcc/fold-const.c | |
parent | c79b54af83c8031caac515081fb7c56a127b90e3 (diff) | |
download | gcc-7deddfded2d013c07a639873a4c90bfed40fd03e.tar.gz |
2010-11-05 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 166377
2010-11-05 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 166377
* gcc/Makefile.in (MELT_RAW_CFLAGS): removed LIBELFINC
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@166380 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r-- | gcc/fold-const.c | 127 |
1 files changed, 72 insertions, 55 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c index decb0fba8f5..b6a9814fbe3 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -1796,16 +1796,10 @@ fold_convert_const (enum tree_code code, tree type, tree arg1) static tree build_zero_vector (tree type) { - tree elem, list; - int i, units; - - elem = fold_convert_const (NOP_EXPR, TREE_TYPE (type), integer_zero_node); - units = TYPE_VECTOR_SUBPARTS (type); + tree t; - list = NULL_TREE; - for (i = 0; i < units; i++) - list = tree_cons (NULL_TREE, elem, list); - return build_vector (type, list); + t = fold_convert_const (NOP_EXPR, TREE_TYPE (type), integer_zero_node); + return build_vector_from_val (type, t); } /* Returns true, if ARG is convertible to TYPE using a NOP_EXPR. */ @@ -8234,7 +8228,7 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0) case IMAGPART_EXPR: if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE) - return fold_convert_loc (loc, type, integer_zero_node); + return build_zero_cst (type); if (TREE_CODE (arg0) == COMPLEX_EXPR) return omit_one_operand_loc (loc, type, TREE_OPERAND (arg0, 1), TREE_OPERAND (arg0, 0)); @@ -9289,7 +9283,7 @@ fold_mult_zconjz (location_t loc, tree type, tree expr) fold_build2_loc (loc, MULT_EXPR, itype, rpart, rpart), fold_build2_loc (loc, MULT_EXPR, itype, ipart, ipart)); return fold_build2_loc (loc, COMPLEX_EXPR, type, tem, - fold_convert_loc (loc, itype, integer_zero_node)); + build_zero_cst (itype)); } @@ -10281,7 +10275,7 @@ fold_binary_loc (location_t loc, if ((!FLOAT_TYPE_P (type) || !HONOR_NANS (TYPE_MODE (type))) && operand_equal_p (arg0, arg1, 0)) - return fold_convert_loc (loc, type, integer_zero_node); + return build_zero_cst (type); /* A - B -> A + (-B) if B is easily negatable. */ if (negate_expr_p (arg1) @@ -10668,7 +10662,7 @@ fold_binary_loc (location_t loc, if (TREE_CODE (arg0) == BIT_NOT_EXPR && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0)) { - t1 = fold_convert_loc (loc, type, integer_zero_node); + t1 = build_zero_cst (type); t1 = fold_unary_loc (loc, BIT_NOT_EXPR, type, t1); return omit_one_operand_loc (loc, type, t1, arg1); } @@ -10677,7 +10671,7 @@ fold_binary_loc (location_t loc, if (TREE_CODE (arg1) == BIT_NOT_EXPR && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0)) { - t1 = fold_convert_loc (loc, type, integer_zero_node); + t1 = build_zero_cst (type); t1 = fold_unary_loc (loc, BIT_NOT_EXPR, type, t1); return omit_one_operand_loc (loc, type, t1, arg0); } @@ -10807,7 +10801,7 @@ fold_binary_loc (location_t loc, if (TREE_CODE (arg0) == BIT_NOT_EXPR && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0)) { - t1 = fold_convert_loc (loc, type, integer_zero_node); + t1 = build_zero_cst (type); t1 = fold_unary_loc (loc, BIT_NOT_EXPR, type, t1); return omit_one_operand_loc (loc, type, t1, arg1); } @@ -10816,7 +10810,7 @@ fold_binary_loc (location_t loc, if (TREE_CODE (arg1) == BIT_NOT_EXPR && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0)) { - t1 = fold_convert_loc (loc, type, integer_zero_node); + t1 = build_zero_cst (type); t1 = fold_unary_loc (loc, BIT_NOT_EXPR, type, t1); return omit_one_operand_loc (loc, type, t1, arg0); } @@ -13287,10 +13281,10 @@ contains_label_p (tree st) tree fold_ternary_loc (location_t loc, enum tree_code code, tree type, - tree op0, tree op1, tree op2) + tree op0, tree op1, tree op2) { tree tem; - tree arg0 = NULL_TREE, arg1 = NULL_TREE; + tree arg0 = NULL_TREE, arg1 = NULL_TREE, arg2 = NULL_TREE; enum tree_code_class kind = TREE_CODE_CLASS (code); gcc_assert (IS_EXPR_CODE_CLASS (kind) @@ -13318,6 +13312,12 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type, STRIP_NOPS (arg1); } + if (op2) + { + arg2 = op2; + STRIP_NOPS (arg2); + } + switch (code) { case COMPONENT_REF: @@ -13604,7 +13604,7 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type, if (elements) return TREE_VALUE (elements); else - return fold_convert_loc (loc, type, integer_zero_node); + return build_zero_cst (type); } } @@ -13616,6 +13616,17 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type, return NULL_TREE; + case FMA_EXPR: + /* For integers we can decompose the FMA if possible. */ + if (TREE_CODE (arg0) == INTEGER_CST + && TREE_CODE (arg1) == INTEGER_CST) + return fold_build2_loc (loc, PLUS_EXPR, type, + const_binop (MULT_EXPR, arg0, arg1), arg2); + if (integer_zerop (arg2)) + return fold_build2_loc (loc, MULT_EXPR, type, arg0, arg1); + + return fold_fma (loc, type, arg0, arg1, arg2); + default: return NULL_TREE; } /* switch (code) */ @@ -15649,53 +15660,59 @@ fold_indirect_ref_1 (location_t loc, tree type, tree op0) } } - /* ((foo*)&vectorfoo)[1] => BIT_FIELD_REF<vectorfoo,...> */ if (TREE_CODE (sub) == POINTER_PLUS_EXPR && TREE_CODE (TREE_OPERAND (sub, 1)) == INTEGER_CST) { tree op00 = TREE_OPERAND (sub, 0); tree op01 = TREE_OPERAND (sub, 1); - tree op00type; STRIP_NOPS (op00); - op00type = TREE_TYPE (op00); - if (TREE_CODE (op00) == ADDR_EXPR - && TREE_CODE (TREE_TYPE (op00type)) == VECTOR_TYPE - && type == TREE_TYPE (TREE_TYPE (op00type))) + if (TREE_CODE (op00) == ADDR_EXPR) { - HOST_WIDE_INT offset = tree_low_cst (op01, 0); - tree part_width = TYPE_SIZE (type); - unsigned HOST_WIDE_INT part_widthi = tree_low_cst (part_width, 0)/BITS_PER_UNIT; - unsigned HOST_WIDE_INT indexi = offset * BITS_PER_UNIT; - tree index = bitsize_int (indexi); - - if (offset/part_widthi <= TYPE_VECTOR_SUBPARTS (TREE_TYPE (op00type))) - return fold_build3_loc (loc, - BIT_FIELD_REF, type, TREE_OPERAND (op00, 0), - part_width, index); - - } - } + tree op00type; + op00 = TREE_OPERAND (op00, 0); + op00type = TREE_TYPE (op00); + /* ((foo*)&vectorfoo)[1] => BIT_FIELD_REF<vectorfoo,...> */ + if (TREE_CODE (op00type) == VECTOR_TYPE + && type == TREE_TYPE (op00type)) + { + HOST_WIDE_INT offset = tree_low_cst (op01, 0); + tree part_width = TYPE_SIZE (type); + unsigned HOST_WIDE_INT part_widthi = tree_low_cst (part_width, 0)/BITS_PER_UNIT; + unsigned HOST_WIDE_INT indexi = offset * BITS_PER_UNIT; + tree index = bitsize_int (indexi); - /* ((foo*)&complexfoo)[1] => __imag__ complexfoo */ - if (TREE_CODE (sub) == POINTER_PLUS_EXPR - && TREE_CODE (TREE_OPERAND (sub, 1)) == INTEGER_CST) - { - tree op00 = TREE_OPERAND (sub, 0); - tree op01 = TREE_OPERAND (sub, 1); - tree op00type; + if (offset/part_widthi <= TYPE_VECTOR_SUBPARTS (op00type)) + return fold_build3_loc (loc, + BIT_FIELD_REF, type, op00, + part_width, index); - STRIP_NOPS (op00); - op00type = TREE_TYPE (op00); - if (TREE_CODE (op00) == ADDR_EXPR - && TREE_CODE (TREE_TYPE (op00type)) == COMPLEX_TYPE - && type == TREE_TYPE (TREE_TYPE (op00type))) - { - tree size = TYPE_SIZE_UNIT (type); - if (tree_int_cst_equal (size, op01)) - return fold_build1_loc (loc, IMAGPART_EXPR, type, - TREE_OPERAND (op00, 0)); + } + /* ((foo*)&complexfoo)[1] => __imag__ complexfoo */ + else if (TREE_CODE (op00type) == COMPLEX_TYPE + && type == TREE_TYPE (op00type)) + { + tree size = TYPE_SIZE_UNIT (type); + if (tree_int_cst_equal (size, op01)) + return fold_build1_loc (loc, IMAGPART_EXPR, type, op00); + } + /* ((foo *)&fooarray)[1] => fooarray[1] */ + else if (TREE_CODE (op00type) == ARRAY_TYPE + && type == TREE_TYPE (op00type)) + { + tree type_domain = TYPE_DOMAIN (op00type); + tree min_val = size_zero_node; + if (type_domain && TYPE_MIN_VALUE (type_domain)) + min_val = TYPE_MIN_VALUE (type_domain); + op01 = size_binop_loc (loc, EXACT_DIV_EXPR, op01, + TYPE_SIZE_UNIT (type)); + op01 = size_binop_loc (loc, PLUS_EXPR, op01, min_val); + op0 = build4 (ARRAY_REF, type, op00, op01, + NULL_TREE, NULL_TREE); + SET_EXPR_LOCATION (op0, loc); + return op0; + } } } |