aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorMon P Wang <wangmp@apple.com>2008-12-18 20:03:17 +0000
committerMon P Wang <wangmp@apple.com>2008-12-18 20:03:17 +0000
commit87c8a8f304d1ee72829086ce2c41a8fa3813ba6a (patch)
treed5b38f2594ae2e43b94f0751c2972cb599818d5f /include
parent5c9f34b7a0c151dd8c508a872dc5e898bde4582e (diff)
downloadexternal_llvm-87c8a8f304d1ee72829086ce2c41a8fa3813ba6a.zip
external_llvm-87c8a8f304d1ee72829086ce2c41a8fa3813ba6a.tar.gz
external_llvm-87c8a8f304d1ee72829086ce2c41a8fa3813ba6a.tar.bz2
Added support for vector widening.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@61209 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r--include/llvm/CodeGen/ValueTypes.h74
-rw-r--r--include/llvm/CodeGen/ValueTypes.td33
-rw-r--r--include/llvm/Target/TargetLowering.h15
3 files changed, 82 insertions, 40 deletions
diff --git a/include/llvm/CodeGen/ValueTypes.h b/include/llvm/CodeGen/ValueTypes.h
index c655d36..1a08f4d 100644
--- a/include/llvm/CodeGen/ValueTypes.h
+++ b/include/llvm/CodeGen/ValueTypes.h
@@ -49,25 +49,28 @@ namespace llvm {
isVoid = 13, // This has no value
- v8i8 = 14, // 8 x i8
- v4i16 = 15, // 4 x i16
- v2i32 = 16, // 2 x i32
- v1i64 = 17, // 1 x i64
- v16i8 = 18, // 16 x i8
- v8i16 = 19, // 8 x i16
- v3i32 = 20, // 3 x i32
- v4i32 = 21, // 4 x i32
- v2i64 = 22, // 2 x i64
-
- v2f32 = 23, // 2 x f32
- v3f32 = 24, // 3 x f32
- v4f32 = 25, // 4 x f32
- v2f64 = 26, // 2 x f64
-
- FIRST_VECTOR_VALUETYPE = v8i8,
+ v2i8 = 14, // 2 x i8
+ v4i8 = 15, // 4 x i8
+ v2i16 = 16, // 2 x i16
+ v8i8 = 17, // 8 x i8
+ v4i16 = 18, // 4 x i16
+ v2i32 = 19, // 2 x i32
+ v1i64 = 20, // 1 x i64
+ v16i8 = 21, // 16 x i8
+ v8i16 = 22, // 8 x i16
+ v3i32 = 23, // 3 x i32
+ v4i32 = 24, // 4 x i32
+ v2i64 = 25, // 2 x i64
+
+ v2f32 = 26, // 2 x f32
+ v3f32 = 27, // 3 x f32
+ v4f32 = 28, // 4 x f32
+ v2f64 = 29, // 2 x f64
+
+ FIRST_VECTOR_VALUETYPE = v2i8,
LAST_VECTOR_VALUETYPE = v2f64,
- LAST_VALUETYPE = 27, // This always remains at the end of the list.
+ LAST_VALUETYPE = 30, // This always remains at the end of the list.
// iPTRAny - An int value the size of the pointer of the current
// target to any address space. This must only be used internal to
@@ -166,10 +169,13 @@ namespace llvm {
default:
break;
case i8:
+ if (NumElements == 2) return v2i8;
+ if (NumElements == 4) return v4i8;
if (NumElements == 8) return v8i8;
if (NumElements == 16) return v16i8;
break;
case i16:
+ if (NumElements == 2) return v2i16;
if (NumElements == 4) return v4i16;
if (NumElements == 8) return v8i16;
break;
@@ -233,7 +239,7 @@ namespace llvm {
return isSimple() ?
((SimpleTy >= FIRST_INTEGER_VALUETYPE &&
SimpleTy <= LAST_INTEGER_VALUETYPE) ||
- (SimpleTy >= v8i8 && SimpleTy <= v2i64)) :
+ (SimpleTy >= v2i8 && SimpleTy <= v2i64)) :
isExtendedInteger();
}
@@ -312,8 +318,11 @@ namespace llvm {
switch (V) {
default:
return getExtendedVectorElementType();
+ case v2i8 :
+ case v4i8 :
case v8i8 :
case v16i8: return i8;
+ case v2i16:
case v4i16:
case v8i16: return i16;
case v2i32:
@@ -338,11 +347,14 @@ namespace llvm {
case v16i8: return 16;
case v8i8 :
case v8i16: return 8;
+ case v4i8:
case v4i16:
case v4i32:
case v4f32: return 4;
case v3i32:
case v3f32: return 3;
+ case v2i8:
+ case v2i16:
case v2i32:
case v2i64:
case v2f32:
@@ -364,9 +376,12 @@ namespace llvm {
return getExtendedSizeInBits();
case i1 : return 1;
case i8 : return 8;
- case i16 : return 16;
+ case i16 :
+ case v2i8: return 16;
case f32 :
- case i32 : return 32;
+ case i32 :
+ case v4i8:
+ case v2i16: return 32;
case f64 :
case i64 :
case v8i8:
@@ -407,6 +422,25 @@ namespace llvm {
return getIntegerVT(1 << Log2_32_Ceil(BitWidth));
}
+ /// isPow2VectorType - Retuns true if the given vector is a power of 2.
+ bool isPow2VectorType() const {
+ unsigned NElts = getVectorNumElements();
+ return !(NElts & (NElts - 1));
+ }
+
+ /// getPow2VectorType - Widens the length of the given vector MVT up to
+ /// the nearest power of 2 and returns that type.
+ MVT getPow2VectorType() const {
+ if (!isPow2VectorType()) {
+ unsigned NElts = getVectorNumElements();
+ unsigned Pow2NElts = 1 << Log2_32_Ceil(NElts);
+ return MVT::getVectorVT(getVectorElementType(), Pow2NElts);
+ }
+ else {
+ return *this;
+ }
+ }
+
/// getIntegerVTBitMask - Return an integer with 1's every place there are
/// bits in the specified integer value type. FIXME: Should return an apint.
uint64_t getIntegerVTBitMask() const {
diff --git a/include/llvm/CodeGen/ValueTypes.td b/include/llvm/CodeGen/ValueTypes.td
index 844b8db..53ed0be 100644
--- a/include/llvm/CodeGen/ValueTypes.td
+++ b/include/llvm/CodeGen/ValueTypes.td
@@ -33,21 +33,24 @@ def f128 : ValueType<128, 10>; // 128-bit floating point value
def ppcf128: ValueType<128, 11>; // PPC 128-bit floating point value
def FlagVT : ValueType<0 , 12>; // Condition code or machine flag
def isVoid : ValueType<0 , 13>; // Produces no value
-def v8i8 : ValueType<64 , 14>; // 8 x i8 vector value
-def v4i16 : ValueType<64 , 15>; // 4 x i16 vector value
-def v2i32 : ValueType<64 , 16>; // 2 x i32 vector value
-def v1i64 : ValueType<64 , 17>; // 1 x i64 vector value
-
-def v16i8 : ValueType<128, 18>; // 16 x i8 vector value
-def v8i16 : ValueType<128, 19>; // 8 x i16 vector value
-def v3i32 : ValueType<96 , 20>; // 3 x i32 vector value
-def v4i32 : ValueType<128, 21>; // 4 x i32 vector value
-def v2i64 : ValueType<128, 22>; // 2 x i64 vector value
-
-def v2f32 : ValueType<64, 23>; // 2 x f32 vector value
-def v3f32 : ValueType<96 , 24>; // 3 x f32 vector value
-def v4f32 : ValueType<128, 25>; // 4 x f32 vector value
-def v2f64 : ValueType<128, 26>; // 2 x f64 vector value
+def v2i8 : ValueType<16 , 14>; // 2 x i8 vector value
+def v4i8 : ValueType<32 , 15>; // 4 x i8 vector value
+def v2i16 : ValueType<32 , 16>; // 2 x i16 vector value
+def v8i8 : ValueType<64 , 17>; // 8 x i8 vector value
+def v4i16 : ValueType<64 , 18>; // 4 x i16 vector value
+def v2i32 : ValueType<64 , 19>; // 2 x i32 vector value
+def v1i64 : ValueType<64 , 20>; // 1 x i64 vector value
+
+def v16i8 : ValueType<128, 21>; // 16 x i8 vector value
+def v8i16 : ValueType<128, 22>; // 8 x i16 vector value
+def v3i32 : ValueType<96 , 23>; // 3 x i32 vector value
+def v4i32 : ValueType<128, 24>; // 4 x i32 vector value
+def v2i64 : ValueType<128, 25>; // 2 x i64 vector value
+
+def v2f32 : ValueType<64, 26>; // 2 x f32 vector value
+def v3f32 : ValueType<96 , 27>; // 3 x f32 vector value
+def v4f32 : ValueType<128, 28>; // 4 x f32 vector value
+def v2f64 : ValueType<128, 29>; // 2 x f64 vector value
// Pseudo valuetype mapped to the current pointer size to any address space.
// Should only be used in TableGen.
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index 71a1d89..2c65588 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -168,8 +168,7 @@ public:
LegalizeAction getTypeAction(MVT VT) const {
if (VT.isExtended()) {
if (VT.isVector()) {
- // First try vector widening
- return Promote;
+ return VT.isPow2VectorType() ? Expand : Promote;
}
if (VT.isInteger())
// First promote to a power-of-two size, then expand if necessary.
@@ -216,9 +215,15 @@ public:
}
if (VT.isVector()) {
- unsigned NumElts = VT.getVectorNumElements();
- MVT EltVT = VT.getVectorElementType();
- return (NumElts == 1) ? EltVT : MVT::getVectorVT(EltVT, NumElts / 2);
+ MVT NVT = VT.getPow2VectorType();
+ if (NVT == VT) {
+ // Vector length is a power of 2 - split to half the size.
+ unsigned NumElts = VT.getVectorNumElements();
+ MVT EltVT = VT.getVectorElementType();
+ return (NumElts == 1) ? EltVT : MVT::getVectorVT(EltVT, NumElts / 2);
+ }
+ // Promote to a power of two size, avoiding multi-step promotion.
+ return getTypeAction(NVT) == Promote ? getTypeToTransformTo(NVT) : NVT;
} else if (VT.isInteger()) {
MVT NVT = VT.getRoundIntegerType();
if (NVT == VT)