gcc-4.5: Bring latest upstream and linaro patches

Build tested on angstrom-2010/console-image for all qemus + beagleboard
for both uclibc/eglibc

Signed-off-by: Khem Raj <raj.khem@gmail.com>
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
This commit is contained in:
Khem Raj
2011-07-30 05:58:13 +00:00
committed by Koen Kooi
parent 0aa9586cb3
commit 7280929da6
12 changed files with 1870 additions and 199 deletions
+10 -1
View File
@@ -24,7 +24,7 @@ INC_PR = "r39"
BINV = "${PV}.4" BINV = "${PV}.4"
SRCREV = 175127 SRCREV = 176640
BRANCH = "gcc-4_5-branch" BRANCH = "gcc-4_5-branch"
PR_append = "+svnr${SRCPV}" PR_append = "+svnr${SRCPV}"
@@ -192,6 +192,15 @@ SRC_URI = "svn://gcc.gnu.org/svn/gcc/branches;module=${BRANCH};proto=http \
file://linaro/gcc-4.5-linaro-r99511.patch \ file://linaro/gcc-4.5-linaro-r99511.patch \
file://linaro/gcc-4.5-linaro-r99514.patch \ file://linaro/gcc-4.5-linaro-r99514.patch \
file://linaro/gcc-4.5-linaro-r99516.patch \ file://linaro/gcc-4.5-linaro-r99516.patch \
file://linaro/gcc-4.5-linaro-r99519.patch \
file://linaro/gcc-4.5-linaro-r99521.patch \
file://linaro/gcc-4.5-linaro-r99522.patch \
file://linaro/gcc-4.5-linaro-r99523.patch \
file://linaro/gcc-4.5-linaro-r99524.patch \
file://linaro/gcc-4.5-linaro-r99525.patch \
file://linaro/gcc-4.5-linaro-r99528.patch \
file://linaro/gcc-4.5-linaro-r99529.patch \
file://linaro/linaro-lp815435.patch \
\ \
file://more-epilogues.patch \ file://more-epilogues.patch \
file://gcc-scalar-widening-pr45847.patch \ file://gcc-scalar-widening-pr45847.patch \
@@ -110,8 +110,10 @@
Backport from mainline: Backport from mainline:
=== modified file 'gcc/cfgexpand.c' === modified file 'gcc/cfgexpand.c'
--- old/gcc/cfgexpand.c 2010-09-01 13:29:58 +0000 Index: gcc-4_5-branch/gcc/cfgexpand.c
+++ new/gcc/cfgexpand.c 2010-09-16 09:15:46 +0000 ===================================================================
--- gcc-4_5-branch.orig/gcc/cfgexpand.c 2011-07-22 16:59:23.000000000 -0700
+++ gcc-4_5-branch/gcc/cfgexpand.c 2011-07-22 16:59:28.581747691 -0700
@@ -64,7 +64,13 @@ @@ -64,7 +64,13 @@
grhs_class = get_gimple_rhs_class (gimple_expr_code (stmt)); grhs_class = get_gimple_rhs_class (gimple_expr_code (stmt));
@@ -127,7 +129,7 @@
t = build2 (gimple_assign_rhs_code (stmt), t = build2 (gimple_assign_rhs_code (stmt),
TREE_TYPE (gimple_assign_lhs (stmt)), TREE_TYPE (gimple_assign_lhs (stmt)),
gimple_assign_rhs1 (stmt), gimple_assign_rhs1 (stmt),
@@ -1887,6 +1893,9 @@ @@ -1893,6 +1899,9 @@
ops.type = TREE_TYPE (lhs); ops.type = TREE_TYPE (lhs);
switch (get_gimple_rhs_class (gimple_expr_code (stmt))) switch (get_gimple_rhs_class (gimple_expr_code (stmt)))
{ {
@@ -137,7 +139,7 @@
case GIMPLE_BINARY_RHS: case GIMPLE_BINARY_RHS:
ops.op1 = gimple_assign_rhs2 (stmt); ops.op1 = gimple_assign_rhs2 (stmt);
/* Fallthru */ /* Fallthru */
@@ -2237,6 +2246,8 @@ @@ -2243,6 +2252,8 @@
{ {
case COND_EXPR: case COND_EXPR:
case DOT_PROD_EXPR: case DOT_PROD_EXPR:
@@ -146,7 +148,7 @@
goto ternary; goto ternary;
case TRUTH_ANDIF_EXPR: case TRUTH_ANDIF_EXPR:
@@ -3023,6 +3034,8 @@ @@ -3030,6 +3041,8 @@
return NULL; return NULL;
case WIDEN_MULT_EXPR: case WIDEN_MULT_EXPR:
@@ -155,7 +157,7 @@
if (SCALAR_INT_MODE_P (GET_MODE (op0)) if (SCALAR_INT_MODE_P (GET_MODE (op0))
&& SCALAR_INT_MODE_P (mode)) && SCALAR_INT_MODE_P (mode))
{ {
@@ -3035,7 +3048,13 @@ @@ -3042,7 +3055,13 @@
op1 = simplify_gen_unary (ZERO_EXTEND, mode, op1, inner_mode); op1 = simplify_gen_unary (ZERO_EXTEND, mode, op1, inner_mode);
else else
op1 = simplify_gen_unary (SIGN_EXTEND, mode, op1, inner_mode); op1 = simplify_gen_unary (SIGN_EXTEND, mode, op1, inner_mode);
@@ -170,10 +172,10 @@
} }
return NULL; return NULL;
Index: gcc-4_5-branch/gcc/config/arm/arm.md
=== modified file 'gcc/config/arm/arm.md' ===================================================================
--- old/gcc/config/arm/arm.md 2010-09-15 16:55:55 +0000 --- gcc-4_5-branch.orig/gcc/config/arm/arm.md 2011-07-22 16:59:25.000000000 -0700
+++ new/gcc/config/arm/arm.md 2010-09-16 09:15:46 +0000 +++ gcc-4_5-branch/gcc/config/arm/arm.md 2011-07-22 16:59:28.581747691 -0700
@@ -1507,7 +1507,15 @@ @@ -1507,7 +1507,15 @@
(set_attr "predicable" "yes")] (set_attr "predicable" "yes")]
) )
@@ -248,10 +250,10 @@
[(set_attr "insn" "smlalxy") [(set_attr "insn" "smlalxy")
(set_attr "predicable" "yes")]) (set_attr "predicable" "yes")])
Index: gcc-4_5-branch/gcc/doc/gimple.texi
=== modified file 'gcc/doc/gimple.texi' ===================================================================
--- old/gcc/doc/gimple.texi 2010-07-06 19:23:53 +0000 --- gcc-4_5-branch.orig/gcc/doc/gimple.texi 2011-07-22 16:58:48.000000000 -0700
+++ new/gcc/doc/gimple.texi 2010-09-16 09:15:46 +0000 +++ gcc-4_5-branch/gcc/doc/gimple.texi 2011-07-22 16:59:28.581747691 -0700
@@ -554,6 +554,9 @@ @@ -554,6 +554,9 @@
@item @code{GIMPLE_INVALID_RHS} @item @code{GIMPLE_INVALID_RHS}
The tree cannot be used as a GIMPLE operand. The tree cannot be used as a GIMPLE operand.
@@ -295,7 +297,7 @@
@deftypefn {GIMPLE function} void gimple_assign_set_lhs (gimple g, tree lhs) @deftypefn {GIMPLE function} void gimple_assign_set_lhs (gimple g, tree lhs)
Set @code{LHS} to be the @code{LHS} operand of assignment statement @code{G}. Set @code{LHS} to be the @code{LHS} operand of assignment statement @code{G}.
@end deftypefn @end deftypefn
@@ -1092,20 +1105,16 @@ @@ -1092,17 +1105,13 @@
statement @code{G}. statement @code{G}.
@end deftypefn @end deftypefn
@@ -305,27 +307,23 @@
- -
-@deftypefn {GIMPLE function} tree *gimple_assign_rhs2_ptr (gimple g) -@deftypefn {GIMPLE function} tree *gimple_assign_rhs2_ptr (gimple g)
-Return a pointer to the second operand on the @code{RHS} of assignment -Return a pointer to the second operand on the @code{RHS} of assignment
-statement @code{G}. +@deftypefn {GIMPLE function} void gimple_assign_set_rhs2 (gimple g, tree rhs)
-@end deftypefn +Set @code{RHS} to be the second operand on the @code{RHS} of assignment
-
@deftypefn {GIMPLE function} void gimple_assign_set_rhs2 (gimple g, tree rhs)
Set @code{RHS} to be the second operand on the @code{RHS} of assignment
statement @code{G}. statement @code{G}.
@end deftypefn @end deftypefn
-@deftypefn {GIMPLE function} void gimple_assign_set_rhs2 (gimple g, tree rhs)
-Set @code{RHS} to be the second operand on the @code{RHS} of assignment
+@deftypefn {GIMPLE function} void gimple_assign_set_rhs3 (gimple g, tree rhs) +@deftypefn {GIMPLE function} void gimple_assign_set_rhs3 (gimple g, tree rhs)
+Set @code{RHS} to be the third operand on the @code{RHS} of assignment +Set @code{RHS} to be the third operand on the @code{RHS} of assignment
+statement @code{G}. statement @code{G}.
+@end deftypefn
+
@deftypefn {GIMPLE function} bool gimple_assign_cast_p (gimple s)
Return true if @code{S} is a type-cast assignment.
@end deftypefn @end deftypefn
=== modified file 'gcc/expr.c' Index: gcc-4_5-branch/gcc/expr.c
--- old/gcc/expr.c 2010-09-01 13:29:58 +0000 ===================================================================
+++ new/gcc/expr.c 2010-09-16 09:15:46 +0000 --- gcc-4_5-branch.orig/gcc/expr.c 2011-07-22 16:59:23.000000000 -0700
@@ -7225,8 +7225,6 @@ +++ gcc-4_5-branch/gcc/expr.c 2011-07-22 16:59:28.591747691 -0700
@@ -7228,8 +7228,6 @@
rtx subtarget, original_target; rtx subtarget, original_target;
int ignore; int ignore;
bool reduce_bit_field; bool reduce_bit_field;
@@ -334,7 +332,7 @@
location_t loc = ops->location; location_t loc = ops->location;
tree treeop0, treeop1; tree treeop0, treeop1;
#define REDUCE_BIT_FIELD(expr) (reduce_bit_field \ #define REDUCE_BIT_FIELD(expr) (reduce_bit_field \
@@ -7246,7 +7244,8 @@ @@ -7249,7 +7247,8 @@
exactly those that are valid in gimple expressions that aren't exactly those that are valid in gimple expressions that aren't
GIMPLE_SINGLE_RHS (or invalid). */ GIMPLE_SINGLE_RHS (or invalid). */
gcc_assert (get_gimple_rhs_class (code) == GIMPLE_UNARY_RHS gcc_assert (get_gimple_rhs_class (code) == GIMPLE_UNARY_RHS
@@ -344,7 +342,7 @@
ignore = (target == const0_rtx ignore = (target == const0_rtx
|| ((CONVERT_EXPR_CODE_P (code) || ((CONVERT_EXPR_CODE_P (code)
@@ -7421,58 +7420,6 @@ @@ -7424,58 +7423,6 @@
fold_convert_loc (loc, ssizetype, fold_convert_loc (loc, ssizetype,
treeop1)); treeop1));
case PLUS_EXPR: case PLUS_EXPR:
@@ -403,7 +401,7 @@
/* If we are adding a constant, a VAR_DECL that is sp, fp, or ap, and /* If we are adding a constant, a VAR_DECL that is sp, fp, or ap, and
something else, make sure we add the register to the constant and something else, make sure we add the register to the constant and
then to the other thing. This case can occur during strength then to the other thing. This case can occur during strength
@@ -7587,57 +7534,6 @@ @@ -7590,57 +7537,6 @@
return REDUCE_BIT_FIELD (simplify_gen_binary (PLUS, mode, op0, op1)); return REDUCE_BIT_FIELD (simplify_gen_binary (PLUS, mode, op0, op1));
case MINUS_EXPR: case MINUS_EXPR:
@@ -461,7 +459,7 @@
/* For initializers, we are allowed to return a MINUS of two /* For initializers, we are allowed to return a MINUS of two
symbolic constants. Here we handle all cases when both operands symbolic constants. Here we handle all cases when both operands
are constant. */ are constant. */
@@ -7678,6 +7574,14 @@ @@ -7681,6 +7577,14 @@
goto binop2; goto binop2;
@@ -476,10 +474,10 @@
case WIDEN_MULT_EXPR: case WIDEN_MULT_EXPR:
/* If first operand is constant, swap them. /* If first operand is constant, swap them.
Thus the following special case checks need only Thus the following special case checks need only
Index: gcc-4_5-branch/gcc/gimple-pretty-print.c
=== modified file 'gcc/gimple-pretty-print.c' ===================================================================
--- old/gcc/gimple-pretty-print.c 2009-11-25 10:55:54 +0000 --- gcc-4_5-branch.orig/gcc/gimple-pretty-print.c 2011-07-22 16:58:48.000000000 -0700
+++ new/gcc/gimple-pretty-print.c 2010-09-16 09:15:46 +0000 +++ gcc-4_5-branch/gcc/gimple-pretty-print.c 2011-07-22 16:59:28.591747691 -0700
@@ -376,6 +376,34 @@ @@ -376,6 +376,34 @@
} }
} }
@@ -524,10 +522,10 @@
else else
gcc_unreachable (); gcc_unreachable ();
if (!(flags & TDF_RHS_ONLY)) if (!(flags & TDF_RHS_ONLY))
Index: gcc-4_5-branch/gcc/gimple.c
=== modified file 'gcc/gimple.c' ===================================================================
--- old/gcc/gimple.c 2010-09-15 16:47:52 +0000 --- gcc-4_5-branch.orig/gcc/gimple.c 2011-07-22 16:59:25.000000000 -0700
+++ new/gcc/gimple.c 2010-09-16 09:15:46 +0000 +++ gcc-4_5-branch/gcc/gimple.c 2011-07-22 16:59:28.591747691 -0700
@@ -289,31 +289,40 @@ @@ -289,31 +289,40 @@
@@ -547,13 +545,10 @@
grhs_class = get_gimple_rhs_class (*subcode_p); grhs_class = get_gimple_rhs_class (*subcode_p);
- if (grhs_class == GIMPLE_BINARY_RHS) - if (grhs_class == GIMPLE_BINARY_RHS)
- {
- *op1_p = TREE_OPERAND (expr, 0);
- *op2_p = TREE_OPERAND (expr, 1);
+ if (grhs_class == GIMPLE_TERNARY_RHS) + if (grhs_class == GIMPLE_TERNARY_RHS)
+ { {
+ *op1_p = TREE_OPERAND (expr, 0); *op1_p = TREE_OPERAND (expr, 0);
+ *op2_p = TREE_OPERAND (expr, 1); *op2_p = TREE_OPERAND (expr, 1);
+ *op3_p = TREE_OPERAND (expr, 2); + *op3_p = TREE_OPERAND (expr, 2);
+ } + }
+ else if (grhs_class == GIMPLE_BINARY_RHS) + else if (grhs_class == GIMPLE_BINARY_RHS)
@@ -668,10 +663,10 @@
: ((SYM) == COND_EXPR \ : ((SYM) == COND_EXPR \
|| (SYM) == CONSTRUCTOR \ || (SYM) == CONSTRUCTOR \
|| (SYM) == OBJ_TYPE_REF \ || (SYM) == OBJ_TYPE_REF \
Index: gcc-4_5-branch/gcc/gimple.h
=== modified file 'gcc/gimple.h' ===================================================================
--- old/gcc/gimple.h 2010-08-10 13:31:21 +0000 --- gcc-4_5-branch.orig/gcc/gimple.h 2011-07-22 16:59:12.000000000 -0700
+++ new/gcc/gimple.h 2010-09-16 09:15:46 +0000 +++ gcc-4_5-branch/gcc/gimple.h 2011-07-22 16:59:28.591747691 -0700
@@ -80,6 +80,7 @@ @@ -80,6 +80,7 @@
enum gimple_rhs_class enum gimple_rhs_class
{ {
@@ -774,10 +769,10 @@
/* Returns true if GS is a nontemporal move. */ /* Returns true if GS is a nontemporal move. */
static inline bool static inline bool
Index: gcc-4_5-branch/gcc/optabs.c
=== modified file 'gcc/optabs.c' ===================================================================
--- old/gcc/optabs.c 2010-03-19 19:45:01 +0000 --- gcc-4_5-branch.orig/gcc/optabs.c 2011-07-22 16:58:48.000000000 -0700
+++ new/gcc/optabs.c 2010-09-16 09:15:46 +0000 +++ gcc-4_5-branch/gcc/optabs.c 2011-07-22 16:59:28.601747691 -0700
@@ -408,6 +408,20 @@ @@ -408,6 +408,20 @@
case DOT_PROD_EXPR: case DOT_PROD_EXPR:
return TYPE_UNSIGNED (type) ? udot_prod_optab : sdot_prod_optab; return TYPE_UNSIGNED (type) ? udot_prod_optab : sdot_prod_optab;
@@ -813,21 +808,21 @@
gcc_assert (icode != CODE_FOR_nothing); gcc_assert (icode != CODE_FOR_nothing);
xmode0 = insn_data[icode].operand[1].mode; xmode0 = insn_data[icode].operand[1].mode;
Index: gcc-4_5-branch/gcc/testsuite/gcc.target/arm/wmul-1.c
=== modified file 'gcc/testsuite/gcc.target/arm/wmul-1.c' ===================================================================
--- old/gcc/testsuite/gcc.target/arm/wmul-1.c 2010-09-01 13:29:58 +0000 --- gcc-4_5-branch.orig/gcc/testsuite/gcc.target/arm/wmul-1.c 2011-07-22 16:59:24.000000000 -0700
+++ new/gcc/testsuite/gcc.target/arm/wmul-1.c 2010-09-16 09:15:46 +0000 +++ gcc-4_5-branch/gcc/testsuite/gcc.target/arm/wmul-1.c 2011-07-22 16:59:28.601747691 -0700
@@ -15,4 +15,4 @@ @@ -15,4 +15,4 @@
return sqr; return sqr;
} }
-/* { dg-final { scan-assembler-times "smulbb" 2 } } */ -/* { dg-final { scan-assembler-times "smulbb" 2 } } */
+/* { dg-final { scan-assembler-times "smlabb" 2 } } */ +/* { dg-final { scan-assembler-times "smlabb" 2 } } */
Index: gcc-4_5-branch/gcc/tree-cfg.c
=== modified file 'gcc/tree-cfg.c' ===================================================================
--- old/gcc/tree-cfg.c 2010-09-01 13:29:58 +0000 --- gcc-4_5-branch.orig/gcc/tree-cfg.c 2011-07-22 16:59:24.000000000 -0700
+++ new/gcc/tree-cfg.c 2010-09-16 09:15:46 +0000 +++ gcc-4_5-branch/gcc/tree-cfg.c 2011-07-22 16:59:28.601747691 -0700
@@ -3483,6 +3483,65 @@ @@ -3484,6 +3484,65 @@
return false; return false;
} }
@@ -893,7 +888,7 @@
/* Verify a gimple assignment statement STMT with a single rhs. /* Verify a gimple assignment statement STMT with a single rhs.
Returns true if anything is wrong. */ Returns true if anything is wrong. */
@@ -3615,6 +3674,9 @@ @@ -3616,6 +3675,9 @@
case GIMPLE_BINARY_RHS: case GIMPLE_BINARY_RHS:
return verify_gimple_assign_binary (stmt); return verify_gimple_assign_binary (stmt);
@@ -903,11 +898,11 @@
default: default:
gcc_unreachable (); gcc_unreachable ();
} }
Index: gcc-4_5-branch/gcc/tree-inline.c
=== modified file 'gcc/tree-inline.c' ===================================================================
--- old/gcc/tree-inline.c 2010-09-01 13:29:58 +0000 --- gcc-4_5-branch.orig/gcc/tree-inline.c 2011-07-22 16:59:24.000000000 -0700
+++ new/gcc/tree-inline.c 2010-09-16 09:15:46 +0000 +++ gcc-4_5-branch/gcc/tree-inline.c 2011-07-22 16:59:28.601747691 -0700
@@ -3199,6 +3199,8 @@ @@ -3207,6 +3207,8 @@
case WIDEN_SUM_EXPR: case WIDEN_SUM_EXPR:
case WIDEN_MULT_EXPR: case WIDEN_MULT_EXPR:
case DOT_PROD_EXPR: case DOT_PROD_EXPR:
@@ -916,10 +911,10 @@
case VEC_WIDEN_MULT_HI_EXPR: case VEC_WIDEN_MULT_HI_EXPR:
case VEC_WIDEN_MULT_LO_EXPR: case VEC_WIDEN_MULT_LO_EXPR:
Index: gcc-4_5-branch/gcc/tree-pretty-print.c
=== modified file 'gcc/tree-pretty-print.c' ===================================================================
--- old/gcc/tree-pretty-print.c 2009-11-30 10:36:54 +0000 --- gcc-4_5-branch.orig/gcc/tree-pretty-print.c 2011-07-22 16:58:48.000000000 -0700
+++ new/gcc/tree-pretty-print.c 2010-09-16 09:15:46 +0000 +++ gcc-4_5-branch/gcc/tree-pretty-print.c 2011-07-22 16:59:28.611747691 -0700
@@ -1939,6 +1939,26 @@ @@ -1939,6 +1939,26 @@
pp_string (buffer, " > "); pp_string (buffer, " > ");
break; break;
@@ -956,10 +951,10 @@
case MULT_EXPR: case MULT_EXPR:
case TRUNC_DIV_EXPR: case TRUNC_DIV_EXPR:
case CEIL_DIV_EXPR: case CEIL_DIV_EXPR:
Index: gcc-4_5-branch/gcc/tree-ssa-ccp.c
=== modified file 'gcc/tree-ssa-ccp.c' ===================================================================
--- old/gcc/tree-ssa-ccp.c 2010-08-10 13:31:21 +0000 --- gcc-4_5-branch.orig/gcc/tree-ssa-ccp.c 2011-07-22 16:59:12.000000000 -0700
+++ new/gcc/tree-ssa-ccp.c 2010-09-16 09:15:46 +0000 +++ gcc-4_5-branch/gcc/tree-ssa-ccp.c 2011-07-22 16:59:28.611747691 -0700
@@ -915,6 +915,23 @@ @@ -915,6 +915,23 @@
TREE_TYPE (TREE_OPERAND (addr, 0)))); TREE_TYPE (TREE_OPERAND (addr, 0))));
} }
@@ -1079,10 +1074,10 @@
case GIMPLE_INVALID_RHS: case GIMPLE_INVALID_RHS:
gcc_unreachable (); gcc_unreachable ();
} }
Index: gcc-4_5-branch/gcc/tree-ssa-dom.c
=== modified file 'gcc/tree-ssa-dom.c' ===================================================================
--- old/gcc/tree-ssa-dom.c 2010-07-20 11:44:16 +0000 --- gcc-4_5-branch.orig/gcc/tree-ssa-dom.c 2011-07-22 16:58:48.000000000 -0700
+++ new/gcc/tree-ssa-dom.c 2010-09-16 09:15:46 +0000 +++ gcc-4_5-branch/gcc/tree-ssa-dom.c 2011-07-22 17:23:51.501747355 -0700
@@ -54,6 +54,7 @@ @@ -54,6 +54,7 @@
EXPR_SINGLE, EXPR_SINGLE,
EXPR_UNARY, EXPR_UNARY,
@@ -1101,58 +1096,31 @@
struct { tree fn; bool pure; size_t nargs; tree *args; } call; struct { tree fn; bool pure; size_t nargs; tree *args; } call;
} ops; } ops;
}; };
@@ -214,22 +216,30 @@ @@ -229,6 +231,14 @@
switch (get_gimple_rhs_class (subcode)) expr->ops.binary.opnd0 = gimple_assign_rhs1 (stmt);
{ expr->ops.binary.opnd1 = gimple_assign_rhs2 (stmt);
case GIMPLE_SINGLE_RHS: break;
- expr->kind = EXPR_SINGLE;
- expr->ops.single.rhs = gimple_assign_rhs1 (stmt);
- break;
+ expr->kind = EXPR_SINGLE;
+ expr->ops.single.rhs = gimple_assign_rhs1 (stmt);
+ break;
case GIMPLE_UNARY_RHS:
- expr->kind = EXPR_UNARY;
+ expr->kind = EXPR_UNARY;
expr->type = TREE_TYPE (gimple_assign_lhs (stmt));
- expr->ops.unary.op = subcode;
- expr->ops.unary.opnd = gimple_assign_rhs1 (stmt);
- break;
+ expr->ops.unary.op = subcode;
+ expr->ops.unary.opnd = gimple_assign_rhs1 (stmt);
+ break;
case GIMPLE_BINARY_RHS:
- expr->kind = EXPR_BINARY;
- expr->type = TREE_TYPE (gimple_assign_lhs (stmt));
- expr->ops.binary.op = subcode;
- expr->ops.binary.opnd0 = gimple_assign_rhs1 (stmt);
- expr->ops.binary.opnd1 = gimple_assign_rhs2 (stmt);
- break;
+ expr->kind = EXPR_BINARY;
+ expr->type = TREE_TYPE (gimple_assign_lhs (stmt));
+ expr->ops.binary.op = subcode;
+ expr->ops.binary.opnd0 = gimple_assign_rhs1 (stmt);
+ expr->ops.binary.opnd1 = gimple_assign_rhs2 (stmt);
+ break;
+ case GIMPLE_TERNARY_RHS: + case GIMPLE_TERNARY_RHS:
+ expr->kind = EXPR_TERNARY; + expr->kind = EXPR_TERNARY;
+ expr->type = TREE_TYPE (gimple_assign_lhs (stmt)); + expr->type = TREE_TYPE (gimple_assign_lhs (stmt));
+ expr->ops.ternary.op = subcode; + expr->ops.ternary.op = subcode;
+ expr->ops.ternary.opnd0 = gimple_assign_rhs1 (stmt); + expr->ops.ternary.opnd0 = gimple_assign_rhs1 (stmt);
+ expr->ops.ternary.opnd1 = gimple_assign_rhs2 (stmt); + expr->ops.ternary.opnd1 = gimple_assign_rhs2 (stmt);
+ expr->ops.ternary.opnd2 = gimple_assign_rhs3 (stmt); + expr->ops.ternary.opnd2 = gimple_assign_rhs3 (stmt);
+ break; + break;
default: default:
gcc_unreachable (); gcc_unreachable ();
} }
@@ -374,23 +384,40 @@ @@ -373,23 +383,40 @@
expr1->ops.unary.opnd, 0); expr1->ops.unary.opnd, 0);
case EXPR_BINARY: case EXPR_BINARY:
- { - {
- if (expr0->ops.binary.op != expr1->ops.binary.op) - if (expr0->ops.binary.op != expr1->ops.binary.op)
- return false; - return false;
- + if (expr0->ops.binary.op != expr1->ops.binary.op)
+ return false;
- if (operand_equal_p (expr0->ops.binary.opnd0, - if (operand_equal_p (expr0->ops.binary.opnd0,
- expr1->ops.binary.opnd0, 0) - expr1->ops.binary.opnd0, 0)
- && operand_equal_p (expr0->ops.binary.opnd1, - && operand_equal_p (expr0->ops.binary.opnd1,
@@ -1166,9 +1134,6 @@
- && operand_equal_p (expr0->ops.binary.opnd1, - && operand_equal_p (expr0->ops.binary.opnd1,
- expr1->ops.binary.opnd0, 0)); - expr1->ops.binary.opnd0, 0));
- } - }
+ if (expr0->ops.binary.op != expr1->ops.binary.op)
+ return false;
+
+ if (operand_equal_p (expr0->ops.binary.opnd0, + if (operand_equal_p (expr0->ops.binary.opnd0,
+ expr1->ops.binary.opnd0, 0) + expr1->ops.binary.opnd0, 0)
+ && operand_equal_p (expr0->ops.binary.opnd1, + && operand_equal_p (expr0->ops.binary.opnd1,
@@ -1203,7 +1168,7 @@
case EXPR_CALL: case EXPR_CALL:
{ {
@@ -453,8 +480,8 @@ @@ -452,8 +479,8 @@
case EXPR_BINARY: case EXPR_BINARY:
val = iterative_hash_object (expr->ops.binary.op, val); val = iterative_hash_object (expr->ops.binary.op, val);
if (commutative_tree_code (expr->ops.binary.op)) if (commutative_tree_code (expr->ops.binary.op))
@@ -1214,7 +1179,7 @@
else else
{ {
val = iterative_hash_expr (expr->ops.binary.opnd0, val); val = iterative_hash_expr (expr->ops.binary.opnd0, val);
@@ -462,6 +489,19 @@ @@ -461,6 +488,19 @@
} }
break; break;
@@ -1234,7 +1199,7 @@
case EXPR_CALL: case EXPR_CALL:
{ {
size_t i; size_t i;
@@ -514,6 +554,16 @@ @@ -513,6 +553,16 @@
print_generic_expr (stream, element->expr.ops.binary.opnd1, 0); print_generic_expr (stream, element->expr.ops.binary.opnd1, 0);
break; break;
@@ -1251,11 +1216,11 @@
case EXPR_CALL: case EXPR_CALL:
{ {
size_t i; size_t i;
Index: gcc-4_5-branch/gcc/tree-ssa-math-opts.c
=== modified file 'gcc/tree-ssa-math-opts.c' ===================================================================
--- old/gcc/tree-ssa-math-opts.c 2010-09-01 13:29:58 +0000 --- gcc-4_5-branch.orig/gcc/tree-ssa-math-opts.c 2011-07-22 16:59:24.000000000 -0700
+++ new/gcc/tree-ssa-math-opts.c 2010-09-16 09:15:46 +0000 +++ gcc-4_5-branch/gcc/tree-ssa-math-opts.c 2011-07-22 16:59:28.611747691 -0700
@@ -1261,6 +1261,235 @@ @@ -1270,6 +1270,235 @@
} }
}; };
@@ -1491,7 +1456,7 @@
/* Find integer multiplications where the operands are extended from /* Find integer multiplications where the operands are extended from
smaller types, and replace the MULT_EXPR with a WIDEN_MULT_EXPR smaller types, and replace the MULT_EXPR with a WIDEN_MULT_EXPR
where appropriate. */ where appropriate. */
@@ -1278,94 +1507,19 @@ @@ -1287,94 +1516,19 @@
for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next (&gsi)) for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{ {
gimple stmt = gsi_stmt (gsi); gimple stmt = gsi_stmt (gsi);
@@ -1499,11 +1464,13 @@
- tree type, type1 = NULL, type2 = NULL; - tree type, type1 = NULL, type2 = NULL;
- tree rhs1, rhs2, rhs1_convop = NULL, rhs2_convop = NULL; - tree rhs1, rhs2, rhs1_convop = NULL, rhs2_convop = NULL;
- enum tree_code rhs1_code, rhs2_code; - enum tree_code rhs1_code, rhs2_code;
- + enum tree_code code;
- if (!is_gimple_assign (stmt) - if (!is_gimple_assign (stmt)
- || gimple_assign_rhs_code (stmt) != MULT_EXPR) - || gimple_assign_rhs_code (stmt) != MULT_EXPR)
- continue; + if (!is_gimple_assign (stmt))
- continue;
- type = TREE_TYPE (gimple_assign_lhs (stmt)); - type = TREE_TYPE (gimple_assign_lhs (stmt));
- -
- if (TREE_CODE (type) != INTEGER_TYPE) - if (TREE_CODE (type) != INTEGER_TYPE)
@@ -1581,11 +1548,6 @@
- gimple_assign_set_rhs_code (stmt, WIDEN_MULT_EXPR); - gimple_assign_set_rhs_code (stmt, WIDEN_MULT_EXPR);
- update_stmt (stmt); - update_stmt (stmt);
- changed = true; - changed = true;
+ enum tree_code code;
+
+ if (!is_gimple_assign (stmt))
+ continue;
+
+ code = gimple_assign_rhs_code (stmt); + code = gimple_assign_rhs_code (stmt);
+ if (code == MULT_EXPR) + if (code == MULT_EXPR)
+ changed |= convert_mult_to_widen (stmt); + changed |= convert_mult_to_widen (stmt);
@@ -1597,10 +1559,10 @@
return (changed ? TODO_dump_func | TODO_update_ssa | TODO_verify_ssa return (changed ? TODO_dump_func | TODO_update_ssa | TODO_verify_ssa
| TODO_verify_stmts : 0); | TODO_verify_stmts : 0);
} }
Index: gcc-4_5-branch/gcc/tree-ssa-operands.c
=== modified file 'gcc/tree-ssa-operands.c' ===================================================================
--- old/gcc/tree-ssa-operands.c 2010-04-02 18:54:46 +0000 --- gcc-4_5-branch.orig/gcc/tree-ssa-operands.c 2011-07-22 16:58:48.000000000 -0700
+++ new/gcc/tree-ssa-operands.c 2010-09-16 09:15:46 +0000 +++ gcc-4_5-branch/gcc/tree-ssa-operands.c 2011-07-22 16:59:28.611747691 -0700
@@ -994,11 +994,13 @@ @@ -994,11 +994,13 @@
case DOT_PROD_EXPR: case DOT_PROD_EXPR:
@@ -1618,11 +1580,11 @@
} }
case FUNCTION_DECL: case FUNCTION_DECL:
Index: gcc-4_5-branch/gcc/tree-ssa-sccvn.c
=== modified file 'gcc/tree-ssa-sccvn.c' ===================================================================
--- old/gcc/tree-ssa-sccvn.c 2010-05-14 11:40:18 +0000 --- gcc-4_5-branch.orig/gcc/tree-ssa-sccvn.c 2011-07-22 16:58:48.000000000 -0700
+++ new/gcc/tree-ssa-sccvn.c 2010-09-16 09:15:46 +0000 +++ gcc-4_5-branch/gcc/tree-ssa-sccvn.c 2011-07-22 16:59:28.611747691 -0700
@@ -2277,6 +2277,10 @@ @@ -2298,6 +2298,10 @@
case GIMPLE_BINARY_RHS: case GIMPLE_BINARY_RHS:
return (is_gimple_min_invariant (gimple_assign_rhs1 (stmt)) return (is_gimple_min_invariant (gimple_assign_rhs1 (stmt))
|| is_gimple_min_invariant (gimple_assign_rhs2 (stmt))); || is_gimple_min_invariant (gimple_assign_rhs2 (stmt)));
@@ -1633,10 +1595,10 @@
case GIMPLE_SINGLE_RHS: case GIMPLE_SINGLE_RHS:
/* Constants inside reference ops are rarely interesting, but /* Constants inside reference ops are rarely interesting, but
it can take a lot of looking to find them. */ it can take a lot of looking to find them. */
Index: gcc-4_5-branch/gcc/tree-ssa-threadedge.c
=== modified file 'gcc/tree-ssa-threadedge.c' ===================================================================
--- old/gcc/tree-ssa-threadedge.c 2009-11-25 10:55:54 +0000 --- gcc-4_5-branch.orig/gcc/tree-ssa-threadedge.c 2011-07-22 16:58:48.000000000 -0700
+++ new/gcc/tree-ssa-threadedge.c 2010-09-16 09:15:46 +0000 +++ gcc-4_5-branch/gcc/tree-ssa-threadedge.c 2011-07-22 16:59:28.611747691 -0700
@@ -247,14 +247,14 @@ @@ -247,14 +247,14 @@
return fold (rhs); return fold (rhs);
@@ -1672,10 +1634,10 @@
default: default:
gcc_unreachable (); gcc_unreachable ();
} }
Index: gcc-4_5-branch/gcc/tree-vrp.c
=== modified file 'gcc/tree-vrp.c' ===================================================================
--- old/gcc/tree-vrp.c 2010-06-14 14:23:31 +0000 --- gcc-4_5-branch.orig/gcc/tree-vrp.c 2011-07-22 16:58:48.000000000 -0700
+++ new/gcc/tree-vrp.c 2010-09-16 09:15:46 +0000 +++ gcc-4_5-branch/gcc/tree-vrp.c 2011-07-22 16:59:28.621747691 -0700
@@ -864,6 +864,8 @@ @@ -864,6 +864,8 @@
gimple_assign_rhs1 (stmt), gimple_assign_rhs1 (stmt),
gimple_assign_rhs2 (stmt), gimple_assign_rhs2 (stmt),
@@ -1694,11 +1656,11 @@
case GIMPLE_SINGLE_RHS: case GIMPLE_SINGLE_RHS:
return tree_single_nonzero_warnv_p (gimple_assign_rhs1 (stmt), return tree_single_nonzero_warnv_p (gimple_assign_rhs1 (stmt),
strict_overflow_p); strict_overflow_p);
Index: gcc-4_5-branch/gcc/tree.c
=== modified file 'gcc/tree.c' ===================================================================
--- old/gcc/tree.c 2010-08-10 13:31:21 +0000 --- gcc-4_5-branch.orig/gcc/tree.c 2011-07-22 16:59:13.000000000 -0700
+++ new/gcc/tree.c 2010-09-16 09:15:46 +0000 +++ gcc-4_5-branch/gcc/tree.c 2011-07-22 16:59:28.621747691 -0700
@@ -6538,6 +6538,23 @@ @@ -6548,6 +6548,23 @@
return false; return false;
} }
@@ -1722,10 +1684,10 @@
/* Generate a hash value for an expression. This can be used iteratively /* Generate a hash value for an expression. This can be used iteratively
by passing a previous result as the VAL argument. by passing a previous result as the VAL argument.
Index: gcc-4_5-branch/gcc/tree.def
=== modified file 'gcc/tree.def' ===================================================================
--- old/gcc/tree.def 2010-04-02 18:54:46 +0000 --- gcc-4_5-branch.orig/gcc/tree.def 2011-07-22 16:58:48.000000000 -0700
+++ new/gcc/tree.def 2010-09-16 09:15:46 +0000 +++ gcc-4_5-branch/gcc/tree.def 2011-07-22 16:59:28.631747691 -0700
@@ -1083,6 +1083,18 @@ @@ -1083,6 +1083,18 @@
the arguments from type t1 to type t2, and then multiplying them. */ the arguments from type t1 to type t2, and then multiplying them. */
DEFTREECODE (WIDEN_MULT_EXPR, "widen_mult_expr", tcc_binary, 2) DEFTREECODE (WIDEN_MULT_EXPR, "widen_mult_expr", tcc_binary, 2)
@@ -1745,11 +1707,11 @@
/* Whole vector left/right shift in bits. /* Whole vector left/right shift in bits.
Operand 0 is a vector to be shifted. Operand 0 is a vector to be shifted.
Operand 1 is an integer shift amount in bits. */ Operand 1 is an integer shift amount in bits. */
Index: gcc-4_5-branch/gcc/tree.h
=== modified file 'gcc/tree.h' ===================================================================
--- old/gcc/tree.h 2010-08-10 13:31:21 +0000 --- gcc-4_5-branch.orig/gcc/tree.h 2011-07-22 16:59:13.000000000 -0700
+++ new/gcc/tree.h 2010-09-16 09:15:46 +0000 +++ gcc-4_5-branch/gcc/tree.h 2011-07-22 16:59:28.631747691 -0700
@@ -4705,6 +4705,7 @@ @@ -4687,6 +4687,7 @@
extern int type_num_arguments (const_tree); extern int type_num_arguments (const_tree);
extern bool associative_tree_code (enum tree_code); extern bool associative_tree_code (enum tree_code);
extern bool commutative_tree_code (enum tree_code); extern bool commutative_tree_code (enum tree_code);
@@ -1757,4 +1719,3 @@
extern tree upper_bound_in_type (tree, tree); extern tree upper_bound_in_type (tree, tree);
extern tree lower_bound_in_type (tree, tree); extern tree lower_bound_in_type (tree, tree);
extern int operand_equal_for_phi_arg_p (const_tree, const_tree); extern int operand_equal_for_phi_arg_p (const_tree, const_tree);
@@ -6,8 +6,10 @@
(try_combine, simplify_if_then_else): Update. (try_combine, simplify_if_then_else): Update.
=== modified file 'gcc/combine.c' === modified file 'gcc/combine.c'
--- old/gcc/combine.c 2010-11-04 12:39:28 +0000 Index: gcc-4_5-branch/gcc/combine.c
+++ new/gcc/combine.c 2010-11-25 11:11:45 +0000 ===================================================================
--- gcc-4_5-branch.orig/gcc/combine.c 2011-07-22 17:24:46.000000000 -0700
+++ gcc-4_5-branch/gcc/combine.c 2011-07-22 17:34:41.961747206 -0700
@@ -392,8 +392,8 @@ @@ -392,8 +392,8 @@
static void undo_all (void); static void undo_all (void);
static void undo_commit (void); static void undo_commit (void);
@@ -19,7 +21,7 @@
static rtx simplify_if_then_else (rtx); static rtx simplify_if_then_else (rtx);
static rtx simplify_set (rtx); static rtx simplify_set (rtx);
static rtx simplify_logical (rtx); static rtx simplify_logical (rtx);
@@ -2944,12 +2944,12 @@ @@ -2962,12 +2962,12 @@
if (i1) if (i1)
{ {
subst_low_luid = DF_INSN_LUID (i1); subst_low_luid = DF_INSN_LUID (i1);
@@ -34,7 +36,7 @@
} }
} }
@@ -2960,7 +2960,7 @@ @@ -2978,7 +2978,7 @@
to avoid self-referential rtl. */ to avoid self-referential rtl. */
subst_low_luid = DF_INSN_LUID (i2); subst_low_luid = DF_INSN_LUID (i2);
@@ -43,7 +45,7 @@
! i1_feeds_i3 && i1dest_in_i1src); ! i1_feeds_i3 && i1dest_in_i1src);
substed_i2 = 1; substed_i2 = 1;
@@ -2991,7 +2991,7 @@ @@ -3009,7 +3009,7 @@
n_occurrences = 0; n_occurrences = 0;
subst_low_luid = DF_INSN_LUID (i1); subst_low_luid = DF_INSN_LUID (i1);
@@ -52,7 +54,7 @@
substed_i1 = 1; substed_i1 = 1;
} }
@@ -3053,7 +3053,7 @@ @@ -3071,7 +3071,7 @@
else else
/* See comment where i2pat is assigned. */ /* See comment where i2pat is assigned. */
XVECEXP (newpat, 0, --total_sets) XVECEXP (newpat, 0, --total_sets)
@@ -61,7 +63,7 @@
} }
} }
@@ -4605,11 +4605,13 @@ @@ -4623,11 +4623,13 @@
IN_DEST is nonzero if we are processing the SET_DEST of a SET. IN_DEST is nonzero if we are processing the SET_DEST of a SET.
@@ -76,7 +78,7 @@
{ {
enum rtx_code code = GET_CODE (x); enum rtx_code code = GET_CODE (x);
enum machine_mode op0_mode = VOIDmode; enum machine_mode op0_mode = VOIDmode;
@@ -4670,7 +4672,7 @@ @@ -4688,7 +4690,7 @@
&& GET_CODE (XVECEXP (x, 0, 0)) == SET && GET_CODE (XVECEXP (x, 0, 0)) == SET
&& GET_CODE (SET_SRC (XVECEXP (x, 0, 0))) == ASM_OPERANDS) && GET_CODE (SET_SRC (XVECEXP (x, 0, 0))) == ASM_OPERANDS)
{ {
@@ -85,7 +87,7 @@
/* If this substitution failed, this whole thing fails. */ /* If this substitution failed, this whole thing fails. */
if (GET_CODE (new_rtx) == CLOBBER if (GET_CODE (new_rtx) == CLOBBER
@@ -4687,7 +4689,7 @@ @@ -4705,7 +4707,7 @@
&& GET_CODE (dest) != CC0 && GET_CODE (dest) != CC0
&& GET_CODE (dest) != PC) && GET_CODE (dest) != PC)
{ {
@@ -94,7 +96,7 @@
/* If this substitution failed, this whole thing fails. */ /* If this substitution failed, this whole thing fails. */
if (GET_CODE (new_rtx) == CLOBBER if (GET_CODE (new_rtx) == CLOBBER
@@ -4733,8 +4735,8 @@ @@ -4751,8 +4753,8 @@
} }
else else
{ {
@@ -105,7 +107,7 @@
/* If this substitution failed, this whole thing /* If this substitution failed, this whole thing
fails. */ fails. */
@@ -4811,7 +4813,9 @@ @@ -4829,7 +4831,9 @@
&& (code == SUBREG || code == STRICT_LOW_PART && (code == SUBREG || code == STRICT_LOW_PART
|| code == ZERO_EXTRACT)) || code == ZERO_EXTRACT))
|| code == SET) || code == SET)
@@ -116,7 +118,7 @@
/* If we found that we will have to reject this combination, /* If we found that we will have to reject this combination,
indicate that by returning the CLOBBER ourselves, rather than indicate that by returning the CLOBBER ourselves, rather than
@@ -4868,7 +4872,7 @@ @@ -4886,7 +4890,7 @@
/* If X is sufficiently simple, don't bother trying to do anything /* If X is sufficiently simple, don't bother trying to do anything
with it. */ with it. */
if (code != CONST_INT && code != REG && code != CLOBBER) if (code != CONST_INT && code != REG && code != CLOBBER)
@@ -125,7 +127,7 @@
if (GET_CODE (x) == code) if (GET_CODE (x) == code)
break; break;
@@ -4888,10 +4892,12 @@ @@ -4906,10 +4910,12 @@
expression. expression.
OP0_MODE is the original mode of XEXP (x, 0). IN_DEST is nonzero OP0_MODE is the original mode of XEXP (x, 0). IN_DEST is nonzero
@@ -140,7 +142,7 @@
{ {
enum rtx_code code = GET_CODE (x); enum rtx_code code = GET_CODE (x);
enum machine_mode mode = GET_MODE (x); enum machine_mode mode = GET_MODE (x);
@@ -4946,8 +4952,8 @@ @@ -4964,8 +4970,8 @@
false arms to store-flag values. Be careful to use copy_rtx false arms to store-flag values. Be careful to use copy_rtx
here since true_rtx or false_rtx might share RTL with x as a here since true_rtx or false_rtx might share RTL with x as a
result of the if_then_else_cond call above. */ result of the if_then_else_cond call above. */
@@ -151,16 +153,16 @@
/* If true_rtx and false_rtx are not general_operands, an if_then_else /* If true_rtx and false_rtx are not general_operands, an if_then_else
is unlikely to be simpler. */ is unlikely to be simpler. */
@@ -5291,7 +5297,7 @@ @@ -5309,7 +5315,7 @@
{ {
/* Try to simplify the expression further. */ /* Try to simplify the expression further. */
rtx tor = simplify_gen_binary (IOR, mode, XEXP (x, 0), XEXP (x, 1)); rtx tor = simplify_gen_binary (IOR, mode, XEXP (x, 0), XEXP (x, 1));
- temp = combine_simplify_rtx (tor, mode, in_dest); - temp = combine_simplify_rtx (tor, VOIDmode, in_dest);
+ temp = combine_simplify_rtx (tor, mode, in_dest, 0); + temp = combine_simplify_rtx (tor, VOIDmode, in_dest, 0);
/* If we could, great. If not, do not go ahead with the IOR /* If we could, great. If not, do not go ahead with the IOR
replacement, since PLUS appears in many special purpose replacement, since PLUS appears in many special purpose
@@ -5384,7 +5390,16 @@ @@ -5402,7 +5408,16 @@
ZERO_EXTRACT is indeed appropriate, it will be placed back by ZERO_EXTRACT is indeed appropriate, it will be placed back by
the call to make_compound_operation in the SET case. */ the call to make_compound_operation in the SET case. */
@@ -178,7 +180,7 @@
&& new_code == NE && GET_MODE_CLASS (mode) == MODE_INT && new_code == NE && GET_MODE_CLASS (mode) == MODE_INT
&& op1 == const0_rtx && op1 == const0_rtx
&& mode == GET_MODE (op0) && mode == GET_MODE (op0)
@@ -5628,11 +5643,11 @@ @@ -5646,11 +5661,11 @@
if (reg_mentioned_p (from, true_rtx)) if (reg_mentioned_p (from, true_rtx))
true_rtx = subst (known_cond (copy_rtx (true_rtx), true_code, true_rtx = subst (known_cond (copy_rtx (true_rtx), true_code,
from, true_val), from, true_val),
@@ -192,7 +194,7 @@
SUBST (XEXP (x, 1), swapped ? false_rtx : true_rtx); SUBST (XEXP (x, 1), swapped ? false_rtx : true_rtx);
SUBST (XEXP (x, 2), swapped ? true_rtx : false_rtx); SUBST (XEXP (x, 2), swapped ? true_rtx : false_rtx);
@@ -5849,11 +5864,11 @@ @@ -5867,11 +5882,11 @@
{ {
temp = subst (simplify_gen_relational (true_code, m, VOIDmode, temp = subst (simplify_gen_relational (true_code, m, VOIDmode,
cond_op0, cond_op1), cond_op0, cond_op1),
@@ -206,4 +208,3 @@
temp = simplify_gen_binary (op, m, gen_lowpart (m, z), temp); temp = simplify_gen_binary (op, m, gen_lowpart (m, z), temp);
if (extend_op != UNKNOWN) if (extend_op != UNKNOWN)
@@ -0,0 +1,25 @@
2011-07-01 Ramana Radhakrishnan <ramana.radhakrishnan@linaro.org>
Backport from mainline.
LP 744754
2011-04-17 Chung-Lin Tang <cltang@codesourcery.com>
* config/arm/arm.c (neon_struct_mem_operand):
Support POST_INC/PRE_DEC memory operands.
=== modified file 'gcc/config/arm/arm.c'
--- old/gcc/config/arm/arm.c 2011-05-11 14:47:14 +0000
+++ new/gcc/config/arm/arm.c 2011-06-29 10:46:39 +0000
@@ -9322,6 +9322,11 @@
if (GET_CODE (ind) == REG)
return arm_address_register_rtx_p (ind, 0);
+ /* vldm/vstm allows POST_INC (ia) and PRE_DEC (db). */
+ if (GET_CODE (ind) == POST_INC
+ || GET_CODE (ind) == PRE_DEC)
+ return arm_address_register_rtx_p (XEXP (ind, 0), 0);
+
return FALSE;
}
@@ -0,0 +1,166 @@
2011-07-08 Richard Sandiford <rdsandiford@googlemail.com>
gcc/
* builtins.c (get_object_alignment): Fix comment.
* fold-const.c (get_pointer_modulus_and_residue): Remove
allow_func_align. Use get_object_alignment.
(fold_binary_loc): Update caller.
2011-07-08 Richard Sandiford <rdsandiford@googlemail.com>
gcc/
Backport from mainline:
2011-06-29 Richard Sandiford <richard.sandiford@linaro.org>
PR tree-optimization/49545
* builtins.c (get_object_alignment_1): Update function comment.
Do not use DECL_ALIGN for functions, but test
TARGET_PTRMEMFUNC_VBIT_LOCATION instead.
* fold-const.c (get_pointer_modulus_and_residue): Don't check
for functions here.
gcc/testsuite/
Backport from mainline:
2011-06-29 Richard Sandiford <richard.sandiford@linaro.org>
* gcc.dg/torture/pr49169.c: Restrict to ARM and MIPS targets.
2011-07-08 Richard Sandiford <richard.sandiford@linaro.org>
gcc/
Backport from mainline:
2011-07-27 Richard Guenther <rguenther@suse.de>
PR tree-optimization/49169
* fold-const.c (get_pointer_modulus_and_residue): Don't rely on
the alignment of function decls.
gcc/testsuite/
Backport from mainline:
2011-07-27 Michael Hope <michael.hope@linaro.org>
Richard Sandiford <richard.sandiford@linaro.org>
PR tree-optimization/49169
* gcc.dg/torture/pr49169.c: New test.
=== modified file 'gcc/builtins.c'
--- old/gcc/builtins.c 2011-01-06 11:02:44 +0000
+++ new/gcc/builtins.c 2011-06-29 09:59:48 +0000
@@ -263,7 +263,14 @@
/* Return the alignment in bits of EXP, an object.
Don't return more than MAX_ALIGN no matter what, ALIGN is the inital
- guessed alignment e.g. from type alignment. */
+ guessed alignment e.g. from type alignment.
+
+ Note that the address (and thus the alignment) computed here is based
+ on the address to which a symbol resolves, whereas DECL_ALIGN is based
+ on the address at which an object is actually located. These two
+ addresses are not always the same. For example, on ARM targets,
+ the address &foo of a Thumb function foo() has the lowest bit set,
+ whereas foo() itself starts on an even address. */
int
get_object_alignment (tree exp, unsigned int align, unsigned int max_align)
@@ -327,7 +334,21 @@
exp = DECL_INITIAL (exp);
if (DECL_P (exp)
&& TREE_CODE (exp) != LABEL_DECL)
- align = MIN (inner, DECL_ALIGN (exp));
+ {
+ if (TREE_CODE (exp) == FUNCTION_DECL)
+ {
+ /* Function addresses can encode extra information besides their
+ alignment. However, if TARGET_PTRMEMFUNC_VBIT_LOCATION
+ allows the low bit to be used as a virtual bit, we know
+ that the address itself must be 2-byte aligned. */
+ if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn)
+ align = 2 * BITS_PER_UNIT;
+ else
+ align = BITS_PER_UNIT;
+ }
+ else
+ align = MIN (inner, DECL_ALIGN (exp));
+ }
#ifdef CONSTANT_ALIGNMENT
else if (CONSTANT_CLASS_P (exp))
align = MIN (inner, (unsigned)CONSTANT_ALIGNMENT (exp, align));
=== modified file 'gcc/fold-const.c'
--- old/gcc/fold-const.c 2011-05-05 14:28:53 +0000
+++ new/gcc/fold-const.c 2011-07-08 12:54:44 +0000
@@ -10030,15 +10030,10 @@
0 <= N < M as is common. In general, the precise value of P is unknown.
M is chosen as large as possible such that constant N can be determined.
- Returns M and sets *RESIDUE to N.
-
- If ALLOW_FUNC_ALIGN is true, do take functions' DECL_ALIGN_UNIT into
- account. This is not always possible due to PR 35705.
- */
+ Returns M and sets *RESIDUE to N. */
static unsigned HOST_WIDE_INT
-get_pointer_modulus_and_residue (tree expr, unsigned HOST_WIDE_INT *residue,
- bool allow_func_align)
+get_pointer_modulus_and_residue (tree expr, unsigned HOST_WIDE_INT *residue)
{
enum tree_code code;
@@ -10068,9 +10063,8 @@
}
}
- if (DECL_P (expr)
- && (allow_func_align || TREE_CODE (expr) != FUNCTION_DECL))
- return DECL_ALIGN_UNIT (expr);
+ if (DECL_P (expr))
+ return get_object_alignment (expr, BITS_PER_UNIT, ~0U) / BITS_PER_UNIT;
}
else if (code == POINTER_PLUS_EXPR)
{
@@ -10080,8 +10074,7 @@
op0 = TREE_OPERAND (expr, 0);
STRIP_NOPS (op0);
- modulus = get_pointer_modulus_and_residue (op0, residue,
- allow_func_align);
+ modulus = get_pointer_modulus_and_residue (op0, residue);
op1 = TREE_OPERAND (expr, 1);
STRIP_NOPS (op1);
@@ -11801,8 +11794,7 @@
unsigned HOST_WIDE_INT modulus, residue;
unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (arg1);
- modulus = get_pointer_modulus_and_residue (arg0, &residue,
- integer_onep (arg1));
+ modulus = get_pointer_modulus_and_residue (arg0, &residue);
/* This works because modulus is a power of 2. If this weren't the
case, we'd have to replace it by its greatest power-of-2
=== added file 'gcc/testsuite/gcc.dg/torture/pr49169.c'
--- old/gcc/testsuite/gcc.dg/torture/pr49169.c 1970-01-01 00:00:00 +0000
+++ new/gcc/testsuite/gcc.dg/torture/pr49169.c 2011-06-29 09:59:48 +0000
@@ -0,0 +1,15 @@
+/* { dg-do compile { target { arm*-*-* || mips*-*-* } } } */
+
+#include <stdlib.h>
+#include <stdint.h>
+
+int
+main (void)
+{
+ void *p = main;
+ if ((intptr_t) p & 1)
+ abort ();
+ return 0;
+}
+
+/* { dg-final { scan-assembler "abort" } } */
@@ -0,0 +1,210 @@
2011-07-11 Revital Eres <revital.eres@linaro.org>
Backport from mainline -r175091
gcc/
* modulo-sched.c (struct ps_insn): Remove row_rest_count field.
(struct partial_schedule): Add rows_length field.
(verify_partial_schedule): Check rows_length.
(ps_insert_empty_row): Handle rows_length.
(create_partial_schedule): Likewise.
(free_partial_schedule): Likewise.
(reset_partial_schedule): Likewise.
(create_ps_insn): Remove rest_count argument.
(remove_node_from_ps): Update rows_length.
(add_node_to_ps): Update rows_length and call create_ps_insn
without passing row_rest_count.
(rotate_partial_schedule): Update rows_length.
=== modified file 'gcc/modulo-sched.c'
--- old/gcc/modulo-sched.c 2011-05-13 16:16:22 +0000
+++ new/gcc/modulo-sched.c 2011-07-04 11:39:09 +0000
@@ -134,8 +134,6 @@
ps_insn_ptr next_in_row,
prev_in_row;
- /* The number of nodes in the same row that come after this node. */
- int row_rest_count;
};
/* Holds the partial schedule as an array of II rows. Each entry of the
@@ -149,6 +147,12 @@
/* rows[i] points to linked list of insns scheduled in row i (0<=i<ii). */
ps_insn_ptr *rows;
+ /* rows_length[i] holds the number of instructions in the row.
+ It is used only (as an optimization) to back off quickly from
+ trying to schedule a node in a full row; that is, to avoid running
+ through futile DFA state transitions. */
+ int *rows_length;
+
/* The earliest absolute cycle of an insn in the partial schedule. */
int min_cycle;
@@ -1907,6 +1911,7 @@
int ii = ps->ii;
int new_ii = ii + 1;
int row;
+ int *rows_length_new;
verify_partial_schedule (ps, sched_nodes);
@@ -1921,9 +1926,11 @@
rotate_partial_schedule (ps, PS_MIN_CYCLE (ps));
rows_new = (ps_insn_ptr *) xcalloc (new_ii, sizeof (ps_insn_ptr));
+ rows_length_new = (int *) xcalloc (new_ii, sizeof (int));
for (row = 0; row < split_row; row++)
{
rows_new[row] = ps->rows[row];
+ rows_length_new[row] = ps->rows_length[row];
ps->rows[row] = NULL;
for (crr_insn = rows_new[row];
crr_insn; crr_insn = crr_insn->next_in_row)
@@ -1944,6 +1951,7 @@
for (row = split_row; row < ii; row++)
{
rows_new[row + 1] = ps->rows[row];
+ rows_length_new[row + 1] = ps->rows_length[row];
ps->rows[row] = NULL;
for (crr_insn = rows_new[row + 1];
crr_insn; crr_insn = crr_insn->next_in_row)
@@ -1965,6 +1973,8 @@
+ (SMODULO (ps->max_cycle, ii) >= split_row ? 1 : 0);
free (ps->rows);
ps->rows = rows_new;
+ free (ps->rows_length);
+ ps->rows_length = rows_length_new;
ps->ii = new_ii;
gcc_assert (ps->min_cycle >= 0);
@@ -2040,16 +2050,23 @@
ps_insn_ptr crr_insn;
for (row = 0; row < ps->ii; row++)
- for (crr_insn = ps->rows[row]; crr_insn; crr_insn = crr_insn->next_in_row)
- {
- ddg_node_ptr u = crr_insn->node;
-
- gcc_assert (TEST_BIT (sched_nodes, u->cuid));
- /* ??? Test also that all nodes of sched_nodes are in ps, perhaps by
- popcount (sched_nodes) == number of insns in ps. */
- gcc_assert (SCHED_TIME (u) >= ps->min_cycle);
- gcc_assert (SCHED_TIME (u) <= ps->max_cycle);
- }
+ {
+ int length = 0;
+
+ for (crr_insn = ps->rows[row]; crr_insn; crr_insn = crr_insn->next_in_row)
+ {
+ ddg_node_ptr u = crr_insn->node;
+
+ length++;
+ gcc_assert (TEST_BIT (sched_nodes, u->cuid));
+ /* ??? Test also that all nodes of sched_nodes are in ps, perhaps by
+ popcount (sched_nodes) == number of insns in ps. */
+ gcc_assert (SCHED_TIME (u) >= ps->min_cycle);
+ gcc_assert (SCHED_TIME (u) <= ps->max_cycle);
+ }
+
+ gcc_assert (ps->rows_length[row] == length);
+ }
}
@@ -2455,6 +2472,7 @@
{
partial_schedule_ptr ps = XNEW (struct partial_schedule);
ps->rows = (ps_insn_ptr *) xcalloc (ii, sizeof (ps_insn_ptr));
+ ps->rows_length = (int *) xcalloc (ii, sizeof (int));
ps->ii = ii;
ps->history = history;
ps->min_cycle = INT_MAX;
@@ -2493,6 +2511,7 @@
return;
free_ps_insns (ps);
free (ps->rows);
+ free (ps->rows_length);
free (ps);
}
@@ -2510,6 +2529,8 @@
ps->rows = (ps_insn_ptr *) xrealloc (ps->rows, new_ii
* sizeof (ps_insn_ptr));
memset (ps->rows, 0, new_ii * sizeof (ps_insn_ptr));
+ ps->rows_length = (int *) xrealloc (ps->rows_length, new_ii * sizeof (int));
+ memset (ps->rows_length, 0, new_ii * sizeof (int));
ps->ii = new_ii;
ps->min_cycle = INT_MAX;
ps->max_cycle = INT_MIN;
@@ -2538,14 +2559,13 @@
/* Creates an object of PS_INSN and initializes it to the given parameters. */
static ps_insn_ptr
-create_ps_insn (ddg_node_ptr node, int rest_count, int cycle)
+create_ps_insn (ddg_node_ptr node, int cycle)
{
ps_insn_ptr ps_i = XNEW (struct ps_insn);
ps_i->node = node;
ps_i->next_in_row = NULL;
ps_i->prev_in_row = NULL;
- ps_i->row_rest_count = rest_count;
ps_i->cycle = cycle;
return ps_i;
@@ -2578,6 +2598,8 @@
if (ps_i->next_in_row)
ps_i->next_in_row->prev_in_row = ps_i->prev_in_row;
}
+
+ ps->rows_length[row] -= 1;
free (ps_i);
return true;
}
@@ -2734,17 +2756,12 @@
sbitmap must_precede, sbitmap must_follow)
{
ps_insn_ptr ps_i;
- int rest_count = 1;
int row = SMODULO (cycle, ps->ii);
- if (ps->rows[row]
- && ps->rows[row]->row_rest_count >= issue_rate)
+ if (ps->rows_length[row] >= issue_rate)
return NULL;
- if (ps->rows[row])
- rest_count += ps->rows[row]->row_rest_count;
-
- ps_i = create_ps_insn (node, rest_count, cycle);
+ ps_i = create_ps_insn (node, cycle);
/* Finds and inserts PS_I according to MUST_FOLLOW and
MUST_PRECEDE. */
@@ -2754,6 +2771,7 @@
return NULL;
}
+ ps->rows_length[row] += 1;
return ps_i;
}
@@ -2909,11 +2927,16 @@
for (i = 0; i < backward_rotates; i++)
{
ps_insn_ptr first_row = ps->rows[0];
+ int first_row_length = ps->rows_length[0];
for (row = 0; row < last_row; row++)
- ps->rows[row] = ps->rows[row+1];
+ {
+ ps->rows[row] = ps->rows[row + 1];
+ ps->rows_length[row] = ps->rows_length[row + 1];
+ }
ps->rows[last_row] = first_row;
+ ps->rows_length[last_row] = first_row_length;
}
ps->max_cycle -= start_cycle;
@@ -0,0 +1,119 @@
2011-07-14 Richard Sandiford <richard.sandiford@linaro.org>
Backport from mainline:
gcc/
2011-07-07 Richard Sandiford <richard.sandiford@linaro.org>
* reload1.c (choose_reload_regs): Use mode sizes to check whether
an old reload register completely defines the required value.
gcc/testsuite/
2011-07-07 Richard Sandiford <richard.sandiford@linaro.org>
* gcc.target/arm/neon-modes-3.c: New test.
=== modified file 'gcc/reload1.c'
--- old/gcc/reload1.c 2011-07-01 09:27:50 +0000
+++ new/gcc/reload1.c 2011-07-11 10:05:08 +0000
@@ -6449,6 +6449,8 @@
if (regno >= 0
&& reg_last_reload_reg[regno] != 0
+ && (GET_MODE_SIZE (GET_MODE (reg_last_reload_reg[regno]))
+ >= GET_MODE_SIZE (mode) + byte)
#ifdef CANNOT_CHANGE_MODE_CLASS
/* Verify that the register it's in can be used in
mode MODE. */
@@ -6460,24 +6462,12 @@
{
enum reg_class rclass = rld[r].rclass, last_class;
rtx last_reg = reg_last_reload_reg[regno];
- enum machine_mode need_mode;
i = REGNO (last_reg);
i += subreg_regno_offset (i, GET_MODE (last_reg), byte, mode);
last_class = REGNO_REG_CLASS (i);
- if (byte == 0)
- need_mode = mode;
- else
- need_mode
- = smallest_mode_for_size
- (GET_MODE_BITSIZE (mode) + byte * BITS_PER_UNIT,
- GET_MODE_CLASS (mode) == MODE_PARTIAL_INT
- ? MODE_INT : GET_MODE_CLASS (mode));
-
- if ((GET_MODE_SIZE (GET_MODE (last_reg))
- >= GET_MODE_SIZE (need_mode))
- && reg_reloaded_contents[i] == regno
+ if (reg_reloaded_contents[i] == regno
&& TEST_HARD_REG_BIT (reg_reloaded_valid, i)
&& HARD_REGNO_MODE_OK (i, rld[r].mode)
&& (TEST_HARD_REG_BIT (reg_class_contents[(int) rclass], i)
=== added file 'gcc/testsuite/gcc.target/arm/neon-modes-3.c'
--- old/gcc/testsuite/gcc.target/arm/neon-modes-3.c 1970-01-01 00:00:00 +0000
+++ new/gcc/testsuite/gcc.target/arm/neon-modes-3.c 2011-07-11 10:05:08 +0000
@@ -0,0 +1,61 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_neon_ok } */
+/* { dg-options "-O" } */
+/* { dg-add-options arm_neon } */
+
+#include <arm_neon.h>
+
+void f1 (volatile float32x4_t *dest, volatile float32x4x4_t *src, int n)
+{
+ float32x4x4_t a5, a6, a7, a8, a9;
+ int i;
+
+ a5 = *src;
+ a6 = *src;
+ a7 = *src;
+ a8 = *src;
+ a9 = *src;
+ while (n--)
+ {
+ for (i = 0; i < 8; i++)
+ {
+ float32x4x4_t a0, a1, a2, a3, a4;
+
+ a0 = *src;
+ a1 = *src;
+ a2 = *src;
+ a3 = *src;
+ a4 = *src;
+ *src = a0;
+ *dest = a0.val[0];
+ *dest = a0.val[3];
+ *src = a1;
+ *dest = a1.val[0];
+ *dest = a1.val[3];
+ *src = a2;
+ *dest = a2.val[0];
+ *dest = a2.val[3];
+ *src = a3;
+ *dest = a3.val[0];
+ *dest = a3.val[3];
+ *src = a4;
+ *dest = a4.val[0];
+ *dest = a4.val[3];
+ }
+ *src = a5;
+ *dest = a5.val[0];
+ *dest = a5.val[3];
+ *src = a6;
+ *dest = a6.val[0];
+ *dest = a6.val[3];
+ *src = a7;
+ *dest = a7.val[0];
+ *dest = a7.val[3];
+ *src = a8;
+ *dest = a8.val[0];
+ *dest = a8.val[3];
+ *src = a9;
+ *dest = a9.val[0];
+ *dest = a9.val[3];
+ }
+}
@@ -0,0 +1,209 @@
2011-07-14 Richard Sandiford <richard.sandiford@linaro.org>
gcc/
* config/arm/arm.h (ARM_LEGITIMIZE_RELOAD_ADDRESS): Apply the
arm_legitimize_reload_address changes marked [*] below.
Backport from mainline:
2011-04-20 Chung-Lin Tang <cltang@codesourcery.com>
[*] config/arm/arm.c (arm_legitimize_reload_address): For NEON
quad-word modes, reduce to 9-bit index range when above 1016
limit.
2011-04-11 Chung-Lin Tang <cltang@codesourcery.com>
Richard Earnshaw <rearnsha@arm.com>
PR target/48250
[*] config/arm/arm.c (arm_legitimize_reload_address): Update cases
to use sign-magnitude offsets. Reject unsupported unaligned
cases. Add detailed description in comments.
* config/arm/arm.md (reload_outdf): Disable for ARM mode; change
condition from TARGET_32BIT to TARGET_ARM.
=== modified file 'gcc/config/arm/arm.h'
--- old/gcc/config/arm/arm.h 2011-04-20 10:07:36 +0000
+++ new/gcc/config/arm/arm.h 2011-07-12 16:35:20 +0000
@@ -1399,6 +1399,11 @@
? GENERAL_REGS : NO_REGS) \
: THUMB_SECONDARY_INPUT_RELOAD_CLASS (CLASS, MODE, X)))
+#define SIGN_MAG_LOW_ADDR_BITS(VAL, N) \
+ (((VAL) & ((1 << (N)) - 1)) \
+ ? (((VAL) & ((1 << ((N) + 1)) - 1)) ^ (1 << (N))) - (1 << (N)) \
+ : 0)
+
/* Try a machine-dependent way of reloading an illegitimate address
operand. If we find one, push the reload and jump to WIN. This
macro is used in only one place: `find_reloads_address' in reload.c.
@@ -1418,26 +1423,135 @@
HOST_WIDE_INT val = INTVAL (XEXP (X, 1)); \
HOST_WIDE_INT low, high; \
\
- if (MODE == DImode || (MODE == DFmode && TARGET_SOFT_FLOAT)) \
- low = ((val & 0xf) ^ 0x8) - 0x8; \
- else if (TARGET_MAVERICK && TARGET_HARD_FLOAT) \
- /* Need to be careful, -256 is not a valid offset. */ \
- low = val >= 0 ? (val & 0xff) : -((-val) & 0xff); \
- else if (TARGET_REALLY_IWMMXT && MODE == SImode) \
- /* Need to be careful, -1024 is not a valid offset. */ \
- low = val >= 0 ? (val & 0x3ff) : -((-val) & 0x3ff); \
- else if (MODE == SImode \
- || (MODE == SFmode && TARGET_SOFT_FLOAT) \
- || ((MODE == HImode || MODE == QImode) && ! arm_arch4)) \
- /* Need to be careful, -4096 is not a valid offset. */ \
- low = val >= 0 ? (val & 0xfff) : -((-val) & 0xfff); \
- else if ((MODE == HImode || MODE == QImode) && arm_arch4) \
- /* Need to be careful, -256 is not a valid offset. */ \
- low = val >= 0 ? (val & 0xff) : -((-val) & 0xff); \
- else if (GET_MODE_CLASS (MODE) == MODE_FLOAT \
- && TARGET_HARD_FLOAT && TARGET_FPA) \
- /* Need to be careful, -1024 is not a valid offset. */ \
- low = val >= 0 ? (val & 0x3ff) : -((-val) & 0x3ff); \
+ /* Detect coprocessor load/stores. */ \
+ bool coproc_p = ((TARGET_HARD_FLOAT \
+ && (TARGET_VFP || TARGET_FPA || TARGET_MAVERICK) \
+ && (mode == SFmode || mode == DFmode \
+ || (mode == DImode && TARGET_MAVERICK))) \
+ || (TARGET_REALLY_IWMMXT \
+ && VALID_IWMMXT_REG_MODE (mode)) \
+ || (TARGET_NEON \
+ && (VALID_NEON_DREG_MODE (mode) \
+ || VALID_NEON_QREG_MODE (mode)))); \
+ \
+ /* For some conditions, bail out when lower two bits are \
+ unaligned. */ \
+ if ((val & 0x3) != 0 \
+ /* Coprocessor load/store indexes are 8-bits + '00' \
+ appended. */ \
+ && (coproc_p \
+ /* For DI, and DF under soft-float: */ \
+ || ((mode == DImode || mode == DFmode) \
+ /* Without ldrd, we use stm/ldm, which does not \
+ fair well with unaligned bits. */ \
+ && (! TARGET_LDRD \
+ /* Thumb-2 ldrd/strd is [-1020,+1020] in \
+ steps of 4. */ \
+ || TARGET_THUMB2)))) \
+ break; \
+ \
+ /* When breaking down a [reg+index] reload address into \
+ [(reg+high)+low], of which the (reg+high) gets turned into \
+ a reload add insn, we try to decompose the index into \
+ high/low values that can often also lead to better reload \
+ CSE. For example: \
+ ldr r0, [r2, #4100] // Offset too large \
+ ldr r1, [r2, #4104] // Offset too large \
+ \
+ is best reloaded as: \
+ add t1, r2, #4096 \
+ ldr r0, [t1, #4] \
+ add t2, r2, #4096 \
+ ldr r1, [t2, #8] \
+ \
+ which post-reload CSE can simplify in most cases to eliminate \
+ the second add instruction: \
+ add t1, r2, #4096 \
+ ldr r0, [t1, #4] \
+ ldr r1, [t1, #8] \
+ \
+ The idea here is that we want to split out the bits of the \
+ constant as a mask, rather than as subtracting the maximum \
+ offset that the respective type of load/store used can \
+ handle. \
+ \
+ When encountering negative offsets, we can still utilize it \
+ even if the overall offset is positive; sometimes this may \
+ lead to an immediate that can be constructed with fewer \
+ instructions. For example: \
+ ldr r0, [r2, #0x3FFFFC] \
+ \
+ This is best reloaded as: \
+ add t1, r2, #0x400000 \
+ ldr r0, [t1, #-4] \
+ \
+ The trick for spotting this for a load insn with N bits of \
+ offset (i.e. bits N-1:0) is to look at bit N; if it is set, \
+ then chose a negative offset that is going to make bit N and \
+ all the bits below it become zero in the remainder part. \
+ \
+ The SIGN_MAG_LOW_ADDR_BITS macro below implements this, \
+ with respect to sign-magnitude addressing (i.e. separate \
+ +- bit, or 1's complement), used in most cases of ARM \
+ load/store instructions. */ \
+ \
+ if (coproc_p) \
+ { \
+ low = SIGN_MAG_LOW_ADDR_BITS (val, 10); \
+ \
+ /* NEON quad-word load/stores are made of two double-word \
+ accesses, so the valid index range is reduced by 8. \
+ Treat as 9-bit range if we go over it. */ \
+ if (TARGET_NEON && VALID_NEON_QREG_MODE (mode) && low >= 1016) \
+ low = SIGN_MAG_LOW_ADDR_BITS (val, 9); \
+ } \
+ else if (GET_MODE_SIZE (mode) == 8) \
+ { \
+ if (TARGET_LDRD) \
+ low = (TARGET_THUMB2 \
+ ? SIGN_MAG_LOW_ADDR_BITS (val, 10) \
+ : SIGN_MAG_LOW_ADDR_BITS (val, 8)); \
+ else \
+ /* For pre-ARMv5TE (without ldrd), we use ldm/stm(db/da/ib) \
+ to access doublewords. The supported load/store offsets \
+ are -8, -4, and 4, which we try to produce here. */ \
+ low = ((val & 0xf) ^ 0x8) - 0x8; \
+ } \
+ else if (GET_MODE_SIZE (mode) < 8) \
+ { \
+ /* NEON element load/stores do not have an offset. */ \
+ if (TARGET_NEON_FP16 && mode == HFmode) \
+ break; \
+ \
+ if (TARGET_THUMB2) \
+ { \
+ /* Thumb-2 has an asymmetrical index range of (-256,4096). \
+ Try the wider 12-bit range first, and re-try if the \
+ result is out of range. */ \
+ low = SIGN_MAG_LOW_ADDR_BITS (val, 12); \
+ if (low < -255) \
+ low = SIGN_MAG_LOW_ADDR_BITS (val, 8); \
+ } \
+ else \
+ { \
+ if (mode == HImode || mode == HFmode) \
+ { \
+ if (arm_arch4) \
+ low = SIGN_MAG_LOW_ADDR_BITS (val, 8); \
+ else \
+ { \
+ /* The storehi/movhi_bytes fallbacks can use \
+ only [-4094,+4094] of the full ldrb/strb \
+ index range. */ \
+ low = SIGN_MAG_LOW_ADDR_BITS (val, 12); \
+ if (low == 4095 || low == -4095) \
+ break; \
+ } \
+ } \
+ else \
+ low = SIGN_MAG_LOW_ADDR_BITS (val, 12); \
+ } \
+ } \
else \
break; \
\
=== modified file 'gcc/config/arm/arm.md'
--- old/gcc/config/arm/arm.md 2011-04-28 16:13:24 +0000
+++ new/gcc/config/arm/arm.md 2011-07-12 16:35:20 +0000
@@ -6167,7 +6167,7 @@
[(match_operand:DF 0 "arm_reload_memory_operand" "=o")
(match_operand:DF 1 "s_register_operand" "r")
(match_operand:SI 2 "s_register_operand" "=&r")]
- "TARGET_32BIT"
+ "TARGET_THUMB2"
"
{
enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
@@ -0,0 +1,67 @@
2011-07-15 Michael Hope <michael.hope@linaro.org>
gcc/
Backport from mainline:
2011-04-05 Eric Botcazou <ebotcazou@adacore.com>
* ifcvt.c (cond_exec_process_insns): Disallow converting a block
that contains the prologue.
gcc/testsuite/
Backport from mainline:
2011-04-01 Bernd Schmidt <bernds@codesourcery.com>
* gcc.c-torture/compile/20110401-1.c: New test.
=== modified file 'gcc/ifcvt.c'
--- old/gcc/ifcvt.c 2011-05-05 14:28:53 +0000
+++ new/gcc/ifcvt.c 2011-07-11 04:08:33 +0000
@@ -1,5 +1,6 @@
/* If-conversion support.
- Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010
+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010,
+ 2011
Free Software Foundation, Inc.
This file is part of GCC.
@@ -311,6 +312,10 @@
for (insn = start; ; insn = NEXT_INSN (insn))
{
+ /* dwarf2out can't cope with conditional prologues. */
+ if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_PROLOGUE_END)
+ return FALSE;
+
if (NOTE_P (insn) || DEBUG_INSN_P (insn))
goto insn_done;
=== added file 'gcc/testsuite/gcc.c-torture/compile/20110401-1.c'
--- old/gcc/testsuite/gcc.c-torture/compile/20110401-1.c 1970-01-01 00:00:00 +0000
+++ new/gcc/testsuite/gcc.c-torture/compile/20110401-1.c 2011-07-11 04:08:33 +0000
@@ -0,0 +1,22 @@
+void asn1_length_der (unsigned long int len, unsigned char *ans, int *ans_len)
+{
+ int k;
+ unsigned char temp[4];
+ if (len < 128) {
+ if (ans != ((void *) 0))
+ ans[0] = (unsigned char) len;
+ *ans_len = 1;
+ } else {
+ k = 0;
+ while (len) {
+ temp[k++] = len & 0xFF;
+ len = len >> 8;
+ }
+ *ans_len = k + 1;
+ if (ans != ((void *) 0)) {
+ ans[0] = ((unsigned char) k & 0x7F) + 128;
+ while (k--)
+ ans[*ans_len - 1 - k] = temp[k];
+ }
+ }
+}
@@ -0,0 +1,138 @@
2011-07-19 Revital Eres <revital.eres@linaro.org>
Backport from mainline -r175090
gcc/
* ddg.c (add_intra_loop_mem_dep): New function.
(build_intra_loop_deps): Call it.
gcc/testsuite
* gcc.dg/sms-9.c: New file.
=== modified file 'gcc/ddg.c'
--- old/gcc/ddg.c 2011-05-13 16:16:22 +0000
+++ new/gcc/ddg.c 2011-07-05 09:02:18 +0000
@@ -352,6 +352,33 @@
}
+/* Given two nodes, analyze their RTL insns and add intra-loop mem deps
+ to ddg G. */
+static void
+add_intra_loop_mem_dep (ddg_ptr g, ddg_node_ptr from, ddg_node_ptr to)
+{
+
+ if ((from->cuid == to->cuid)
+ || !insn_alias_sets_conflict_p (from->insn, to->insn))
+ /* Do not create edge if memory references have disjoint alias sets
+ or 'to' and 'from' are the same instruction. */
+ return;
+
+ if (mem_write_insn_p (from->insn))
+ {
+ if (mem_read_insn_p (to->insn))
+ create_ddg_dep_no_link (g, from, to,
+ DEBUG_INSN_P (to->insn)
+ ? ANTI_DEP : TRUE_DEP, MEM_DEP, 0);
+ else
+ create_ddg_dep_no_link (g, from, to,
+ DEBUG_INSN_P (to->insn)
+ ? ANTI_DEP : OUTPUT_DEP, MEM_DEP, 0);
+ }
+ else if (!mem_read_insn_p (to->insn))
+ create_ddg_dep_no_link (g, from, to, ANTI_DEP, MEM_DEP, 0);
+}
+
/* Given two nodes, analyze their RTL insns and add inter-loop mem deps
to ddg G. */
static void
@@ -439,10 +466,22 @@
if (DEBUG_INSN_P (j_node->insn))
continue;
if (mem_access_insn_p (j_node->insn))
- /* Don't bother calculating inter-loop dep if an intra-loop dep
- already exists. */
+ {
+ /* Don't bother calculating inter-loop dep if an intra-loop dep
+ already exists. */
if (! TEST_BIT (dest_node->successors, j))
add_inter_loop_mem_dep (g, dest_node, j_node);
+ /* If -fmodulo-sched-allow-regmoves
+ is set certain anti-dep edges are not created.
+ It might be that these anti-dep edges are on the
+ path from one memory instruction to another such that
+ removing these edges could cause a violation of the
+ memory dependencies. Thus we add intra edges between
+ every two memory instructions in this case. */
+ if (flag_modulo_sched_allow_regmoves
+ && !TEST_BIT (dest_node->predecessors, j))
+ add_intra_loop_mem_dep (g, j_node, dest_node);
+ }
}
}
}
=== added file 'gcc/testsuite/gcc.dg/sms-9.c'
--- old/gcc/testsuite/gcc.dg/sms-9.c 1970-01-01 00:00:00 +0000
+++ new/gcc/testsuite/gcc.dg/sms-9.c 2011-07-04 11:13:26 +0000
@@ -0,0 +1,60 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fmodulo-sched -fno-auto-inc-dec -O2 -fmodulo-sched-allow-regmoves" } */
+
+#include <stdlib.h>
+#include <stdarg.h>
+
+struct df_ref_info
+{
+ unsigned int *begin;
+ unsigned int *count;
+};
+
+extern void *memset (void *s, int c, __SIZE_TYPE__ n);
+
+
+__attribute__ ((noinline))
+ int
+ df_reorganize_refs_by_reg_by_insn (struct df_ref_info *ref_info,
+ int num, unsigned int start)
+{
+ unsigned int m = num;
+ unsigned int offset = 77;
+ unsigned int r;
+
+ for (r = start; r < m; r++)
+ {
+ ref_info->begin[r] = offset;
+ offset += ref_info->count[r];
+ ref_info->count[r] = 0;
+ }
+
+ return offset;
+}
+
+int
+main ()
+{
+ struct df_ref_info temp;
+ int num = 100;
+ unsigned int start = 5;
+ int i, offset;
+
+ temp.begin = malloc (100 * sizeof (unsigned int));
+ temp.count = malloc (100 * sizeof (unsigned int));
+
+ memset (temp.begin, 0, sizeof (unsigned int) * num);
+ memset (temp.count, 0, sizeof (unsigned int) * num);
+
+ for (i = 0; i < num; i++)
+ temp.count[i] = i + 1;
+
+ offset = df_reorganize_refs_by_reg_by_insn (&temp, num, start);
+
+ if (offset != 5112)
+ abort ();
+
+ free (temp.begin);
+ free (temp.count);
+ return 0;
+}
@@ -0,0 +1,741 @@
2011-07-21 Richard Sandiford <richard.sandiford@linaro.org>
gcc/
PR middle-end/49736
* expr.c (all_zeros_p): Undo bogus part of last change.
2011-07-21 Richard Sandiford <rdsandiford@googlemail.com>
Backport from mainline:
gcc/cp/
2011-07-13 Richard Sandiford <richard.sandiford@linaro.org>
* typeck2.c (split_nonconstant_init_1): Pass the initializer directly,
rather than a pointer to it. Return true if the whole of the value
was initialized by the generated statements. Use
complete_ctor_at_level_p instead of count_type_elements.
gcc/
2011-07-13 Richard Sandiford <richard.sandiford@linaro.org>
* tree.h (categorize_ctor_elements): Remove comment. Fix long line.
(count_type_elements): Delete.
(complete_ctor_at_level_p): Declare.
* expr.c (flexible_array_member_p): New function, split out from...
(count_type_elements): ...here. Make static. Replace allow_flexarr
parameter with for_ctor_p. When for_ctor_p is true, return the
number of elements that should appear in the top-level constructor,
otherwise return an estimate of the number of scalars.
(categorize_ctor_elements): Replace p_must_clear with p_complete.
(categorize_ctor_elements_1): Likewise. Use complete_ctor_at_level_p.
(complete_ctor_at_level_p): New function, borrowing union logic
from old categorize_ctor_elements_1.
(mostly_zeros_p): Return true if the constructor is not complete.
(all_zeros_p): Update call to categorize_ctor_elements.
* gimplify.c (gimplify_init_constructor): Update call to
categorize_ctor_elements. Don't call count_type_elements.
Unconditionally prevent clearing for variable-sized types,
otherwise rely on categorize_ctor_elements to detect
incomplete initializers.
gcc/testsuite/
2011-07-13 Chung-Lin Tang <cltang@codesourcery.com>
* gcc.target/arm/pr48183.c: New test.
=== modified file 'gcc/cp/typeck2.c'
--- old/gcc/cp/typeck2.c 2010-07-30 14:05:57 +0000
+++ new/gcc/cp/typeck2.c 2011-07-13 13:36:36 +0000
@@ -546,18 +546,20 @@
/* The recursive part of split_nonconstant_init. DEST is an lvalue
- expression to which INIT should be assigned. INIT is a CONSTRUCTOR. */
+ expression to which INIT should be assigned. INIT is a CONSTRUCTOR.
+ Return true if the whole of the value was initialized by the
+ generated statements. */
-static void
-split_nonconstant_init_1 (tree dest, tree *initp)
+static bool
+split_nonconstant_init_1 (tree dest, tree init)
{
unsigned HOST_WIDE_INT idx;
- tree init = *initp;
tree field_index, value;
tree type = TREE_TYPE (dest);
tree inner_type = NULL;
bool array_type_p = false;
- HOST_WIDE_INT num_type_elements, num_initialized_elements;
+ bool complete_p = true;
+ HOST_WIDE_INT num_split_elts = 0;
switch (TREE_CODE (type))
{
@@ -569,7 +571,6 @@
case RECORD_TYPE:
case UNION_TYPE:
case QUAL_UNION_TYPE:
- num_initialized_elements = 0;
FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (init), idx,
field_index, value)
{
@@ -592,13 +593,14 @@
sub = build3 (COMPONENT_REF, inner_type, dest, field_index,
NULL_TREE);
- split_nonconstant_init_1 (sub, &value);
+ if (!split_nonconstant_init_1 (sub, value))
+ complete_p = false;
+ num_split_elts++;
}
else if (!initializer_constant_valid_p (value, inner_type))
{
tree code;
tree sub;
- HOST_WIDE_INT inner_elements;
/* FIXME: Ordered removal is O(1) so the whole function is
worst-case quadratic. This could be fixed using an aside
@@ -622,21 +624,9 @@
code = build_stmt (input_location, EXPR_STMT, code);
add_stmt (code);
- inner_elements = count_type_elements (inner_type, true);
- if (inner_elements < 0)
- num_initialized_elements = -1;
- else if (num_initialized_elements >= 0)
- num_initialized_elements += inner_elements;
- continue;
+ num_split_elts++;
}
}
-
- num_type_elements = count_type_elements (type, true);
- /* If all elements of the initializer are non-constant and
- have been split out, we don't need the empty CONSTRUCTOR. */
- if (num_type_elements > 0
- && num_type_elements == num_initialized_elements)
- *initp = NULL;
break;
case VECTOR_TYPE:
@@ -648,6 +638,7 @@
code = build2 (MODIFY_EXPR, type, dest, cons);
code = build_stmt (input_location, EXPR_STMT, code);
add_stmt (code);
+ num_split_elts += CONSTRUCTOR_NELTS (init);
}
break;
@@ -657,6 +648,8 @@
/* The rest of the initializer is now a constant. */
TREE_CONSTANT (init) = 1;
+ return complete_p && complete_ctor_at_level_p (TREE_TYPE (init),
+ num_split_elts, inner_type);
}
/* A subroutine of store_init_value. Splits non-constant static
@@ -672,7 +665,8 @@
if (TREE_CODE (init) == CONSTRUCTOR)
{
code = push_stmt_list ();
- split_nonconstant_init_1 (dest, &init);
+ if (split_nonconstant_init_1 (dest, init))
+ init = NULL_TREE;
code = pop_stmt_list (code);
DECL_INITIAL (dest) = init;
TREE_READONLY (dest) = 0;
=== modified file 'gcc/expr.c'
--- old/gcc/expr.c 2011-04-20 10:07:36 +0000
+++ new/gcc/expr.c 2011-07-14 11:52:06 +0000
@@ -4860,16 +4860,136 @@
return NULL_RTX;
}
+/* Return true if field F of structure TYPE is a flexible array. */
+
+static bool
+flexible_array_member_p (const_tree f, const_tree type)
+{
+ const_tree tf;
+
+ tf = TREE_TYPE (f);
+ return (TREE_CHAIN (f) == NULL
+ && TREE_CODE (tf) == ARRAY_TYPE
+ && TYPE_DOMAIN (tf)
+ && TYPE_MIN_VALUE (TYPE_DOMAIN (tf))
+ && integer_zerop (TYPE_MIN_VALUE (TYPE_DOMAIN (tf)))
+ && !TYPE_MAX_VALUE (TYPE_DOMAIN (tf))
+ && int_size_in_bytes (type) >= 0);
+}
+
+/* If FOR_CTOR_P, return the number of top-level elements that a constructor
+ must have in order for it to completely initialize a value of type TYPE.
+ Return -1 if the number isn't known.
+
+ If !FOR_CTOR_P, return an estimate of the number of scalars in TYPE. */
+
+static HOST_WIDE_INT
+count_type_elements (const_tree type, bool for_ctor_p)
+{
+ switch (TREE_CODE (type))
+ {
+ case ARRAY_TYPE:
+ {
+ tree nelts;
+
+ nelts = array_type_nelts (type);
+ if (nelts && host_integerp (nelts, 1))
+ {
+ unsigned HOST_WIDE_INT n;
+
+ n = tree_low_cst (nelts, 1) + 1;
+ if (n == 0 || for_ctor_p)
+ return n;
+ else
+ return n * count_type_elements (TREE_TYPE (type), false);
+ }
+ return for_ctor_p ? -1 : 1;
+ }
+
+ case RECORD_TYPE:
+ {
+ unsigned HOST_WIDE_INT n;
+ tree f;
+
+ n = 0;
+ for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
+ if (TREE_CODE (f) == FIELD_DECL)
+ {
+ if (!for_ctor_p)
+ n += count_type_elements (TREE_TYPE (f), false);
+ else if (!flexible_array_member_p (f, type))
+ /* Don't count flexible arrays, which are not supposed
+ to be initialized. */
+ n += 1;
+ }
+
+ return n;
+ }
+
+ case UNION_TYPE:
+ case QUAL_UNION_TYPE:
+ {
+ tree f;
+ HOST_WIDE_INT n, m;
+
+ gcc_assert (!for_ctor_p);
+ /* Estimate the number of scalars in each field and pick the
+ maximum. Other estimates would do instead; the idea is simply
+ to make sure that the estimate is not sensitive to the ordering
+ of the fields. */
+ n = 1;
+ for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
+ if (TREE_CODE (f) == FIELD_DECL)
+ {
+ m = count_type_elements (TREE_TYPE (f), false);
+ /* If the field doesn't span the whole union, add an extra
+ scalar for the rest. */
+ if (simple_cst_equal (TYPE_SIZE (TREE_TYPE (f)),
+ TYPE_SIZE (type)) != 1)
+ m++;
+ if (n < m)
+ n = m;
+ }
+ return n;
+ }
+
+ case COMPLEX_TYPE:
+ return 2;
+
+ case VECTOR_TYPE:
+ return TYPE_VECTOR_SUBPARTS (type);
+
+ case INTEGER_TYPE:
+ case REAL_TYPE:
+ case FIXED_POINT_TYPE:
+ case ENUMERAL_TYPE:
+ case BOOLEAN_TYPE:
+ case POINTER_TYPE:
+ case OFFSET_TYPE:
+ case REFERENCE_TYPE:
+ return 1;
+
+ case ERROR_MARK:
+ return 0;
+
+ case VOID_TYPE:
+ case METHOD_TYPE:
+ case FUNCTION_TYPE:
+ case LANG_TYPE:
+ default:
+ gcc_unreachable ();
+ }
+}
+
/* Helper for categorize_ctor_elements. Identical interface. */
static bool
categorize_ctor_elements_1 (const_tree ctor, HOST_WIDE_INT *p_nz_elts,
- HOST_WIDE_INT *p_elt_count,
- bool *p_must_clear)
+ HOST_WIDE_INT *p_init_elts, bool *p_complete)
{
unsigned HOST_WIDE_INT idx;
- HOST_WIDE_INT nz_elts, elt_count;
- tree value, purpose;
+ HOST_WIDE_INT nz_elts, init_elts, num_fields;
+ tree value, purpose, elt_type;
/* Whether CTOR is a valid constant initializer, in accordance with what
initializer_constant_valid_p does. If inferred from the constructor
@@ -4878,7 +4998,9 @@
bool const_p = const_from_elts_p ? true : TREE_STATIC (ctor);
nz_elts = 0;
- elt_count = 0;
+ init_elts = 0;
+ num_fields = 0;
+ elt_type = NULL_TREE;
FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), idx, purpose, value)
{
@@ -4894,6 +5016,8 @@
mult = (tree_low_cst (hi_index, 1)
- tree_low_cst (lo_index, 1) + 1);
}
+ num_fields += mult;
+ elt_type = TREE_TYPE (value);
switch (TREE_CODE (value))
{
@@ -4901,11 +5025,11 @@
{
HOST_WIDE_INT nz = 0, ic = 0;
- bool const_elt_p
- = categorize_ctor_elements_1 (value, &nz, &ic, p_must_clear);
+ bool const_elt_p = categorize_ctor_elements_1 (value, &nz, &ic,
+ p_complete);
nz_elts += mult * nz;
- elt_count += mult * ic;
+ init_elts += mult * ic;
if (const_from_elts_p && const_p)
const_p = const_elt_p;
@@ -4917,12 +5041,12 @@
case FIXED_CST:
if (!initializer_zerop (value))
nz_elts += mult;
- elt_count += mult;
+ init_elts += mult;
break;
case STRING_CST:
nz_elts += mult * TREE_STRING_LENGTH (value);
- elt_count += mult * TREE_STRING_LENGTH (value);
+ init_elts += mult * TREE_STRING_LENGTH (value);
break;
case COMPLEX_CST:
@@ -4930,7 +5054,7 @@
nz_elts += mult;
if (!initializer_zerop (TREE_IMAGPART (value)))
nz_elts += mult;
- elt_count += mult;
+ init_elts += mult;
break;
case VECTOR_CST:
@@ -4940,60 +5064,31 @@
{
if (!initializer_zerop (TREE_VALUE (v)))
nz_elts += mult;
- elt_count += mult;
+ init_elts += mult;
}
}
break;
default:
- nz_elts += mult;
- elt_count += mult;
+ {
+ HOST_WIDE_INT tc = count_type_elements (elt_type, false);
+ nz_elts += mult * tc;
+ init_elts += mult * tc;
- if (const_from_elts_p && const_p)
- const_p = initializer_constant_valid_p (value, TREE_TYPE (value))
- != NULL_TREE;
+ if (const_from_elts_p && const_p)
+ const_p = initializer_constant_valid_p (value, elt_type)
+ != NULL_TREE;
+ }
break;
}
}
- if (!*p_must_clear
- && (TREE_CODE (TREE_TYPE (ctor)) == UNION_TYPE
- || TREE_CODE (TREE_TYPE (ctor)) == QUAL_UNION_TYPE))
- {
- tree init_sub_type;
- bool clear_this = true;
-
- if (!VEC_empty (constructor_elt, CONSTRUCTOR_ELTS (ctor)))
- {
- /* We don't expect more than one element of the union to be
- initialized. Not sure what we should do otherwise... */
- gcc_assert (VEC_length (constructor_elt, CONSTRUCTOR_ELTS (ctor))
- == 1);
-
- init_sub_type = TREE_TYPE (VEC_index (constructor_elt,
- CONSTRUCTOR_ELTS (ctor),
- 0)->value);
-
- /* ??? We could look at each element of the union, and find the
- largest element. Which would avoid comparing the size of the
- initialized element against any tail padding in the union.
- Doesn't seem worth the effort... */
- if (simple_cst_equal (TYPE_SIZE (TREE_TYPE (ctor)),
- TYPE_SIZE (init_sub_type)) == 1)
- {
- /* And now we have to find out if the element itself is fully
- constructed. E.g. for union { struct { int a, b; } s; } u
- = { .s = { .a = 1 } }. */
- if (elt_count == count_type_elements (init_sub_type, false))
- clear_this = false;
- }
- }
-
- *p_must_clear = clear_this;
- }
+ if (*p_complete && !complete_ctor_at_level_p (TREE_TYPE (ctor),
+ num_fields, elt_type))
+ *p_complete = false;
*p_nz_elts += nz_elts;
- *p_elt_count += elt_count;
+ *p_init_elts += init_elts;
return const_p;
}
@@ -5003,111 +5098,50 @@
and place it in *P_NZ_ELTS;
* how many scalar fields in total are in CTOR,
and place it in *P_ELT_COUNT.
- * if a type is a union, and the initializer from the constructor
- is not the largest element in the union, then set *p_must_clear.
+ * whether the constructor is complete -- in the sense that every
+ meaningful byte is explicitly given a value --
+ and place it in *P_COMPLETE.
Return whether or not CTOR is a valid static constant initializer, the same
as "initializer_constant_valid_p (CTOR, TREE_TYPE (CTOR)) != 0". */
bool
categorize_ctor_elements (const_tree ctor, HOST_WIDE_INT *p_nz_elts,
- HOST_WIDE_INT *p_elt_count,
- bool *p_must_clear)
+ HOST_WIDE_INT *p_init_elts, bool *p_complete)
{
*p_nz_elts = 0;
- *p_elt_count = 0;
- *p_must_clear = false;
+ *p_init_elts = 0;
+ *p_complete = true;
- return
- categorize_ctor_elements_1 (ctor, p_nz_elts, p_elt_count, p_must_clear);
+ return categorize_ctor_elements_1 (ctor, p_nz_elts, p_init_elts, p_complete);
}
-/* Count the number of scalars in TYPE. Return -1 on overflow or
- variable-sized. If ALLOW_FLEXARR is true, don't count flexible
- array member at the end of the structure. */
+/* TYPE is initialized by a constructor with NUM_ELTS elements, the last
+ of which had type LAST_TYPE. Each element was itself a complete
+ initializer, in the sense that every meaningful byte was explicitly
+ given a value. Return true if the same is true for the constructor
+ as a whole. */
-HOST_WIDE_INT
-count_type_elements (const_tree type, bool allow_flexarr)
+bool
+complete_ctor_at_level_p (const_tree type, HOST_WIDE_INT num_elts,
+ const_tree last_type)
{
- const HOST_WIDE_INT max = ~((HOST_WIDE_INT)1 << (HOST_BITS_PER_WIDE_INT-1));
- switch (TREE_CODE (type))
+ if (TREE_CODE (type) == UNION_TYPE
+ || TREE_CODE (type) == QUAL_UNION_TYPE)
{
- case ARRAY_TYPE:
- {
- tree telts = array_type_nelts (type);
- if (telts && host_integerp (telts, 1))
- {
- HOST_WIDE_INT n = tree_low_cst (telts, 1) + 1;
- HOST_WIDE_INT m = count_type_elements (TREE_TYPE (type), false);
- if (n == 0)
- return 0;
- else if (max / n > m)
- return n * m;
- }
- return -1;
- }
-
- case RECORD_TYPE:
- {
- HOST_WIDE_INT n = 0, t;
- tree f;
-
- for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
- if (TREE_CODE (f) == FIELD_DECL)
- {
- t = count_type_elements (TREE_TYPE (f), false);
- if (t < 0)
- {
- /* Check for structures with flexible array member. */
- tree tf = TREE_TYPE (f);
- if (allow_flexarr
- && TREE_CHAIN (f) == NULL
- && TREE_CODE (tf) == ARRAY_TYPE
- && TYPE_DOMAIN (tf)
- && TYPE_MIN_VALUE (TYPE_DOMAIN (tf))
- && integer_zerop (TYPE_MIN_VALUE (TYPE_DOMAIN (tf)))
- && !TYPE_MAX_VALUE (TYPE_DOMAIN (tf))
- && int_size_in_bytes (type) >= 0)
- break;
-
- return -1;
- }
- n += t;
- }
-
- return n;
- }
-
- case UNION_TYPE:
- case QUAL_UNION_TYPE:
- return -1;
-
- case COMPLEX_TYPE:
- return 2;
-
- case VECTOR_TYPE:
- return TYPE_VECTOR_SUBPARTS (type);
-
- case INTEGER_TYPE:
- case REAL_TYPE:
- case FIXED_POINT_TYPE:
- case ENUMERAL_TYPE:
- case BOOLEAN_TYPE:
- case POINTER_TYPE:
- case OFFSET_TYPE:
- case REFERENCE_TYPE:
- return 1;
-
- case ERROR_MARK:
- return 0;
-
- case VOID_TYPE:
- case METHOD_TYPE:
- case FUNCTION_TYPE:
- case LANG_TYPE:
- default:
- gcc_unreachable ();
+ if (num_elts == 0)
+ return false;
+
+ gcc_assert (num_elts == 1 && last_type);
+
+ /* ??? We could look at each element of the union, and find the
+ largest element. Which would avoid comparing the size of the
+ initialized element against any tail padding in the union.
+ Doesn't seem worth the effort... */
+ return simple_cst_equal (TYPE_SIZE (type), TYPE_SIZE (last_type)) == 1;
}
+
+ return count_type_elements (type, true) == num_elts;
}
/* Return 1 if EXP contains mostly (3/4) zeros. */
@@ -5116,18 +5150,12 @@
mostly_zeros_p (const_tree exp)
{
if (TREE_CODE (exp) == CONSTRUCTOR)
-
{
- HOST_WIDE_INT nz_elts, count, elts;
- bool must_clear;
-
- categorize_ctor_elements (exp, &nz_elts, &count, &must_clear);
- if (must_clear)
- return 1;
-
- elts = count_type_elements (TREE_TYPE (exp), false);
-
- return nz_elts < elts / 4;
+ HOST_WIDE_INT nz_elts, init_elts;
+ bool complete_p;
+
+ categorize_ctor_elements (exp, &nz_elts, &init_elts, &complete_p);
+ return !complete_p || nz_elts < init_elts / 4;
}
return initializer_zerop (exp);
@@ -5139,12 +5167,11 @@
all_zeros_p (const_tree exp)
{
if (TREE_CODE (exp) == CONSTRUCTOR)
-
{
- HOST_WIDE_INT nz_elts, count;
- bool must_clear;
+ HOST_WIDE_INT nz_elts, init_elts;
+ bool complete_p;
- categorize_ctor_elements (exp, &nz_elts, &count, &must_clear);
+ categorize_ctor_elements (exp, &nz_elts, &init_elts, &complete_p);
return nz_elts == 0;
}
=== modified file 'gcc/gimplify.c'
--- old/gcc/gimplify.c 2011-04-07 18:27:20 +0000
+++ new/gcc/gimplify.c 2011-07-13 13:36:36 +0000
@@ -3634,9 +3634,8 @@
case ARRAY_TYPE:
{
struct gimplify_init_ctor_preeval_data preeval_data;
- HOST_WIDE_INT num_type_elements, num_ctor_elements;
- HOST_WIDE_INT num_nonzero_elements;
- bool cleared, valid_const_initializer;
+ HOST_WIDE_INT num_ctor_elements, num_nonzero_elements;
+ bool cleared, complete_p, valid_const_initializer;
/* Aggregate types must lower constructors to initialization of
individual elements. The exception is that a CONSTRUCTOR node
@@ -3653,7 +3652,7 @@
can only do so if it known to be a valid constant initializer. */
valid_const_initializer
= categorize_ctor_elements (ctor, &num_nonzero_elements,
- &num_ctor_elements, &cleared);
+ &num_ctor_elements, &complete_p);
/* If a const aggregate variable is being initialized, then it
should never be a lose to promote the variable to be static. */
@@ -3691,26 +3690,29 @@
parts in, then generate code for the non-constant parts. */
/* TODO. There's code in cp/typeck.c to do this. */
- num_type_elements = count_type_elements (type, true);
+ if (int_size_in_bytes (TREE_TYPE (ctor)) < 0)
+ /* store_constructor will ignore the clearing of variable-sized
+ objects. Initializers for such objects must explicitly set
+ every field that needs to be set. */
+ cleared = false;
+ else if (!complete_p)
+ /* If the constructor isn't complete, clear the whole object
+ beforehand.
- /* If count_type_elements could not determine number of type elements
- for a constant-sized object, assume clearing is needed.
- Don't do this for variable-sized objects, as store_constructor
- will ignore the clearing of variable-sized objects. */
- if (num_type_elements < 0 && int_size_in_bytes (type) >= 0)
+ ??? This ought not to be needed. For any element not present
+ in the initializer, we should simply set them to zero. Except
+ we'd need to *find* the elements that are not present, and that
+ requires trickery to avoid quadratic compile-time behavior in
+ large cases or excessive memory use in small cases. */
cleared = true;
- /* If there are "lots" of zeros, then block clear the object first. */
- else if (num_type_elements - num_nonzero_elements
+ else if (num_ctor_elements - num_nonzero_elements
> CLEAR_RATIO (optimize_function_for_speed_p (cfun))
- && num_nonzero_elements < num_type_elements/4)
- cleared = true;
- /* ??? This bit ought not be needed. For any element not present
- in the initializer, we should simply set them to zero. Except
- we'd need to *find* the elements that are not present, and that
- requires trickery to avoid quadratic compile-time behavior in
- large cases or excessive memory use in small cases. */
- else if (num_ctor_elements < num_type_elements)
- cleared = true;
+ && num_nonzero_elements < num_ctor_elements / 4)
+ /* If there are "lots" of zeros, it's more efficient to clear
+ the memory and then set the nonzero elements. */
+ cleared = true;
+ else
+ cleared = false;
/* If there are "lots" of initialized elements, and all of them
are valid address constants, then the entire initializer can
=== added file 'gcc/testsuite/gcc.target/arm/pr48183.c'
--- old/gcc/testsuite/gcc.target/arm/pr48183.c 1970-01-01 00:00:00 +0000
+++ new/gcc/testsuite/gcc.target/arm/pr48183.c 2011-07-13 13:36:36 +0000
@@ -0,0 +1,25 @@
+/* testsuite/gcc.target/arm/pr48183.c */
+
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_neon_ok } */
+/* { dg-options "-O -g" } */
+/* { dg-add-options arm_neon } */
+
+#include <arm_neon.h>
+
+void move_16bit_to_32bit (int32_t *dst, const short *src, unsigned n)
+{
+ unsigned i;
+ int16x4x2_t input;
+ int32x4x2_t mid;
+ int32x4x2_t output;
+
+ for (i = 0; i < n/2; i += 8) {
+ input = vld2_s16(src + i);
+ mid.val[0] = vmovl_s16(input.val[0]);
+ mid.val[1] = vmovl_s16(input.val[1]);
+ output.val[0] = vshlq_n_s32(mid.val[0], 8);
+ output.val[1] = vshlq_n_s32(mid.val[1], 8);
+ vst2q_s32((int32_t *)dst + i, output);
+ }
+}
=== modified file 'gcc/tree.h'
--- old/gcc/tree.h 2011-04-06 12:29:08 +0000
+++ new/gcc/tree.h 2011-07-13 13:36:36 +0000
@@ -4361,21 +4361,10 @@
extern VEC(tree,gc) *ctor_to_vec (tree);
-/* Examine CTOR to discover:
- * how many scalar fields are set to nonzero values,
- and place it in *P_NZ_ELTS;
- * how many scalar fields in total are in CTOR,
- and place it in *P_ELT_COUNT.
- * if a type is a union, and the initializer from the constructor
- is not the largest element in the union, then set *p_must_clear.
-
- Return whether or not CTOR is a valid static constant initializer, the same
- as "initializer_constant_valid_p (CTOR, TREE_TYPE (CTOR)) != 0". */
-
-extern bool categorize_ctor_elements (const_tree, HOST_WIDE_INT *, HOST_WIDE_INT *,
- bool *);
-
-extern HOST_WIDE_INT count_type_elements (const_tree, bool);
+extern bool categorize_ctor_elements (const_tree, HOST_WIDE_INT *,
+ HOST_WIDE_INT *, bool *);
+
+extern bool complete_ctor_at_level_p (const_tree, HOST_WIDE_INT, const_tree);
/* integer_zerop (tree x) is nonzero if X is an integer constant of value 0. */
@@ -0,0 +1,25 @@
2011-07-29 Ramana Radhakrishnan <ramana.radhakrishnan@linaro.org>
gcc/
Backport only bits marked as [*] from mainline:
2010-12-19 Chung-Lin Tang <cltang@codesourcery.com>
* config/arm/arm.c ([*]arm_legitimate_index_p): Add VFP load/store
index range case. Change to SF/DFmode tests to avoid capturing HFmode.
(thumb2_legitimate_index_p): Same.
Index: gcc-4_5-branch/gcc/config/arm/arm.c
===================================================================
--- gcc-4_5-branch.orig/gcc/config/arm/arm.c 2011-07-22 17:56:51.000000000 -0700
+++ gcc-4_5-branch/gcc/config/arm/arm.c 2011-07-29 14:43:42.171610966 -0700
@@ -5631,8 +5631,8 @@ arm_legitimate_index_p (enum machine_mod
/* Standard coprocessor addressing modes. */
if (TARGET_HARD_FLOAT
- && (TARGET_FPA || TARGET_MAVERICK)
- && (GET_MODE_CLASS (mode) == MODE_FLOAT
+ && (TARGET_FPA || TARGET_MAVERICK || TARGET_VFP)
+ && ((mode == SFmode || mode == DFmode)
|| (TARGET_MAVERICK && mode == DImode)))
return (code == CONST_INT && INTVAL (index) < 1024
&& INTVAL (index) > -1024