aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoger Sayle <roger@eyesopen.com>2006-06-20 15:02:05 +0000
committerRoger Sayle <roger@eyesopen.com>2006-06-20 15:02:05 +0000
commitb6df8704637ce0bcd4cd92068d14a8d44bf00e75 (patch)
treec9dae92eb51b59b6f01612dfb8113ea758cf617a
parentcbda9e3f888fcbf03a4782347baac46394ec85d2 (diff)
* expr.c (expand_expr_real_1) <VECTOR_CST>: For vector constants with
integer modes, attempt to directly construct an integer constant. * fold-const.c (native_encode_vector): Determine the size of each element from the vector type instead of the first vector element. * tree.c (build_constructor_single): Mark a CONSTRUCTOR as constant, if all of its elements/components are constant. (build_constructor_from_list): Likewise. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@114815 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/expr.c23
-rw-r--r--gcc/fold-const.c12
-rw-r--r--gcc/tree.c17
4 files changed, 45 insertions, 19 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index aec8a3fe6dd..0a56b814167 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,15 @@
+2006-06-20 Roger Sayle <roger@eyesopen.com>
+
+ * expr.c (expand_expr_real_1) <VECTOR_CST>: For vector constants with
+ integer modes, attempt to directly construct an integer constant.
+
+ * fold-const.c (native_encode_vector): Determine the size of each
+ element from the vector type instead of the first vector element.
+
+ * tree.c (build_constructor_single): Mark a CONSTRUCTOR as constant,
+ if all of its elements/components are constant.
+ (build_constructor_from_list): Likewise.
+
2006-06-20 Zdenek Dvorak <dvorakz@suse.cz>
PR tree-optimization/27331
diff --git a/gcc/expr.c b/gcc/expr.c
index 94e8586dc35..562588a4481 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -6939,14 +6939,21 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
return temp;
case VECTOR_CST:
- if (GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (exp))) == MODE_VECTOR_INT
- || GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (exp))) == MODE_VECTOR_FLOAT)
- return const_vector_from_tree (exp);
- else
- return expand_expr (build_constructor_from_list
- (TREE_TYPE (exp),
- TREE_VECTOR_CST_ELTS (exp)),
- ignore ? const0_rtx : target, tmode, modifier);
+ {
+ tree tmp = NULL_TREE;
+ if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
+ || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
+ return const_vector_from_tree (exp);
+ if (GET_MODE_CLASS (mode) == MODE_INT)
+ tmp = fold_unary (VIEW_CONVERT_EXPR,
+ lang_hooks.types.type_for_mode (mode, 1),
+ exp);
+ if (!tmp)
+ tmp = build_constructor_from_list (type,
+ TREE_VECTOR_CST_ELTS (exp));
+ return expand_expr (tmp, ignore ? const0_rtx : target,
+ tmode, modifier);
+ }
case CONST_DECL:
return expand_expr (DECL_INITIAL (exp), target, VOIDmode, modifier);
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 5a65586794e..b54658ded62 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -6934,12 +6934,13 @@ static int
native_encode_vector (tree expr, unsigned char *ptr, int len)
{
int i, size, offset, count;
- tree elem, elements;
+ tree itype, elem, elements;
- size = 0;
offset = 0;
elements = TREE_VECTOR_CST_ELTS (expr);
count = TYPE_VECTOR_SUBPARTS (TREE_TYPE (expr));
+ itype = TREE_TYPE (TREE_TYPE (expr));
+ size = GET_MODE_SIZE (TYPE_MODE (itype));
for (i = 0; i < count; i++)
{
if (elements)
@@ -6952,18 +6953,15 @@ native_encode_vector (tree expr, unsigned char *ptr, int len)
if (elem)
{
- size = native_encode_expr (elem, ptr+offset, len-offset);
- if (size == 0)
+ if (native_encode_expr (elem, ptr+offset, len-offset) != size)
return 0;
}
- else if (size != 0)
+ else
{
if (offset + size > len)
return 0;
memset (ptr+offset, 0, size);
}
- else
- return 0;
offset += size;
}
return offset;
diff --git a/gcc/tree.c b/gcc/tree.c
index 0d40a517fe9..2df2f7b3cb5 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -1013,13 +1013,16 @@ build_constructor_single (tree type, tree index, tree value)
{
VEC(constructor_elt,gc) *v;
constructor_elt *elt;
+ tree t;
v = VEC_alloc (constructor_elt, gc, 1);
elt = VEC_quick_push (constructor_elt, v, NULL);
elt->index = index;
elt->value = value;
- return build_constructor (type, v);
+ t = build_constructor (type, v);
+ TREE_CONSTANT (t) = TREE_CONSTANT (value);
+ return t;
}
@@ -1028,8 +1031,9 @@ build_constructor_single (tree type, tree index, tree value)
tree
build_constructor_from_list (tree type, tree vals)
{
- tree t;
+ tree t, val;
VEC(constructor_elt,gc) *v = NULL;
+ bool constant_p = true;
if (vals)
{
@@ -1037,12 +1041,17 @@ build_constructor_from_list (tree type, tree vals)
for (t = vals; t; t = TREE_CHAIN (t))
{
constructor_elt *elt = VEC_quick_push (constructor_elt, v, NULL);
+ val = TREE_VALUE (t);
elt->index = TREE_PURPOSE (t);
- elt->value = TREE_VALUE (t);
+ elt->value = val;
+ if (!TREE_CONSTANT (val))
+ constant_p = false;
}
}
- return build_constructor (type, v);
+ t = build_constructor (type, v);
+ TREE_CONSTANT (t) = constant_p;
+ return t;
}