This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: PR 8878
- From: Aldy Hernandez <aldyh at redhat dot com>
- To: Mark Mitchell <mark at codesourcery dot com>
- Cc: gcc at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org
- Date: Thu, 24 Jul 2003 15:09:06 -0400
- Subject: Re: PR 8878
- References: <200307232306.h6NN6A7F029904@doubledemon.codesourcery.com>
Hi Mark.
I am committing the patch below to the 3.3 branch. This fixes 8878.
This patch has been tested on x86-linux.
I am closing the PR.
Aldy
2003-04-01 Aldy Hernandez <aldyh@redhat.com>
PR/8878
* expr.c (expand_expr): Handle VECTOR_CST.
(const_vector_from_tree): New.
* varasm.c (output_constant): Handle VECTOR_CST.
* c-typeck.c (digest_init): Build a vector constant from a
VECTOR_TYPE.
Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.498.2.19
diff -c -p -r1.498.2.19 expr.c
*** expr.c 13 Jul 2003 21:37:40 -0000 1.498.2.19
--- expr.c 24 Jul 2003 19:07:21 -0000
*************** static rtx clear_storage_via_libcall PAR
*** 153,159 ****
static tree clear_storage_libcall_fn PARAMS ((int));
static rtx compress_float_constant PARAMS ((rtx, rtx));
static rtx get_subtarget PARAMS ((rtx));
! static int is_zeros_p PARAMS ((tree));
static int mostly_zeros_p PARAMS ((tree));
static void store_constructor_field PARAMS ((rtx, unsigned HOST_WIDE_INT,
HOST_WIDE_INT, enum machine_mode,
--- 153,159 ----
static tree clear_storage_libcall_fn PARAMS ((int));
static rtx compress_float_constant PARAMS ((rtx, rtx));
static rtx get_subtarget PARAMS ((rtx));
! static int is_zeros_p PARAMS ((tree));
static int mostly_zeros_p PARAMS ((tree));
static void store_constructor_field PARAMS ((rtx, unsigned HOST_WIDE_INT,
HOST_WIDE_INT, enum machine_mode,
*************** static rtx do_store_flag PARAMS ((tree,
*** 177,182 ****
--- 177,183 ----
static void emit_single_push_insn PARAMS ((enum machine_mode, rtx, tree));
#endif
static void do_tablejump PARAMS ((rtx, enum machine_mode, rtx, rtx, rtx));
+ static rtx const_vector_from_tree PARAMS ((tree));
/* Record for each mode whether we can move a register directly to or
from an object of that mode in memory. If we can't, we won't try
*************** expand_expr (exp, target, tmode, modifie
*** 6793,6798 ****
--- 6794,6802 ----
return temp;
+ case VECTOR_CST:
+ return const_vector_from_tree (exp);
+
case CONST_DECL:
return expand_expr (DECL_INITIAL (exp), target, VOIDmode, modifier);
*************** vector_mode_valid_p (mode)
*** 11241,11246 ****
--- 11245,11287 ----
/* If we have support for the inner mode, we can safely emulate it.
We may not have V2DI, but me can emulate with a pair of DIs. */
return mov_optab->handlers[innermode].insn_code != CODE_FOR_nothing;
+ }
+
+ /* Return a CONST_VECTOR rtx for a VECTOR_CST tree. */
+ static rtx
+ const_vector_from_tree (exp)
+ tree exp;
+ {
+ rtvec v;
+ int units, i;
+ tree link, elt;
+ enum machine_mode inner, mode;
+
+ mode = TYPE_MODE (TREE_TYPE (exp));
+
+ if (is_zeros_p (exp))
+ return CONST0_RTX (mode);
+
+ units = GET_MODE_NUNITS (mode);
+ inner = GET_MODE_INNER (mode);
+
+ v = rtvec_alloc (units);
+
+ link = TREE_VECTOR_CST_ELTS (exp);
+ for (i = 0; link; link = TREE_CHAIN (link), ++i)
+ {
+ elt = TREE_VALUE (link);
+
+ if (TREE_CODE (elt) == REAL_CST)
+ RTVEC_ELT (v, i) = CONST_DOUBLE_FROM_REAL_VALUE (TREE_REAL_CST (elt),
+ inner);
+ else
+ RTVEC_ELT (v, i) = immed_double_const (TREE_INT_CST_LOW (elt),
+ TREE_INT_CST_HIGH (elt),
+ inner);
+ }
+
+ return gen_rtx_raw_CONST_VECTOR (mode, v);
}
#include "gt-expr.h"
Index: varasm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/varasm.c,v
retrieving revision 1.324.2.4
diff -c -p -r1.324.2.4 varasm.c
*** varasm.c 29 Apr 2003 12:16:41 -0000 1.324.2.4
--- varasm.c 24 Jul 2003 19:07:24 -0000
*************** output_constant (exp, size, align)
*** 4050,4055 ****
--- 4050,4072 ----
thissize = MIN (TREE_STRING_LENGTH (exp), size);
assemble_string (TREE_STRING_POINTER (exp), thissize);
}
+ else if (TREE_CODE (exp) == VECTOR_CST)
+ {
+ int elt_size;
+ tree link;
+ unsigned int nalign;
+ enum machine_mode inner;
+
+ inner = GET_MODE_INNER (TYPE_MODE (TREE_TYPE (exp)));
+ nalign = MIN (align, GET_MODE_ALIGNMENT (inner));
+
+ elt_size = GET_MODE_UNIT_SIZE (TYPE_MODE (TREE_TYPE (exp)));
+
+ link = TREE_VECTOR_CST_ELTS (exp);
+ output_constant (TREE_VALUE (link), elt_size, align);
+ while ((link = TREE_CHAIN (link)) != NULL)
+ output_constant (TREE_VALUE (link), elt_size, nalign);
+ }
else
abort ();
break;
Index: c-typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-typeck.c,v
retrieving revision 1.213.2.6
diff -c -p -r1.213.2.6 c-typeck.c
*** c-typeck.c 18 Apr 2003 06:50:45 -0000 1.213.2.6
--- c-typeck.c 24 Jul 2003 19:07:28 -0000
*************** digest_init (type, init, require_constan
*** 4759,4764 ****
--- 4759,4772 ----
return inside_init;
}
}
+ /* Build a VECTOR_CST from a *constant* vector constructor. If the
+ vector constructor is not constant (e.g. {1,2,3,foo()}) then punt
+ below and handle as a constructor. */
+ if (code == VECTOR_TYPE
+ && comptypes (TREE_TYPE (inside_init), type)
+ && TREE_CONSTANT (inside_init))
+ return build_vector (type, TREE_OPERAND (inside_init, 1));
+
/* Any type can be initialized
from an expression of the same type, optionally with braces. */