expr.c (expand_expr_real_1): For vector constants with integer modes...
authorRoger Sayle <roger@eyesopen.com>
Tue, 20 Jun 2006 15:02:05 +0000 (15:02 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Tue, 20 Jun 2006 15:02:05 +0000 (15:02 +0000)
* 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.

From-SVN: r114815

gcc/ChangeLog
gcc/expr.c
gcc/fold-const.c
gcc/tree.c

index aec8a3f..0a56b81 100644 (file)
@@ -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
index 94e8586..562588a 100644 (file)
@@ -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);
index 5a65586..b54658d 100644 (file)
@@ -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;
index 0d40a51..2df2f7b 100644 (file)
@@ -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;
 }