[llvm-commits] [llvm] r52548 - in /llvm/trunk/lib/CodeGen/SelectionDAG: LegalizeFloatTypes.cpp LegalizeIntegerTypes.cpp LegalizeTypes.cpp LegalizeTypes.h LegalizeTypesGeneric.cpp LegalizeVectorTypes.cpp
Duncan Sands
baldrick at free.fr
Fri Jun 20 11:40:51 PDT 2008
Author: baldrick
Date: Fri Jun 20 13:40:50 2008
New Revision: 52548
URL: http://llvm.org/viewvc/llvm-project?rev=52548&view=rev
Log:
Share some code that is common between integer and
float expansion (and sometimes vector splitting too).
Added:
llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
Modified:
llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h
llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp?rev=52548&r1=52547&r2=52548&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp Fri Jun 20 13:40:50 2008
@@ -14,7 +14,7 @@
// The resulting integer value is the same as what you would get by performing
// the floating point operation and bitcasting the result to the integer type.
// Expansion is the act of changing a computation in an illegal type to be a
-// computation in multiple registers of a smaller type. For example,
+// computation in two identical registers of a smaller type. For example,
// implementing ppcf128 arithmetic in two f64 registers.
//
//===----------------------------------------------------------------------===//
@@ -395,6 +395,15 @@
#endif
assert(0 && "Do not know how to expand the result of this operator!");
abort();
+
+ case ISD::MERGE_VALUES: SplitRes_MERGE_VALUES(N, Lo, Hi); break;
+ case ISD::UNDEF: SplitRes_UNDEF(N, Lo, Hi); break;
+ case ISD::SELECT: SplitRes_SELECT(N, Lo, Hi); break;
+ case ISD::SELECT_CC: SplitRes_SELECT_CC(N, Lo, Hi); break;
+
+ case ISD::BIT_CONVERT: ExpandRes_BIT_CONVERT(N, Lo, Hi); break;
+ case ISD::BUILD_PAIR: ExpandRes_BUILD_PAIR(N, Lo, Hi); break;
+ case ISD::EXTRACT_VECTOR_ELT: ExpandRes_EXTRACT_VECTOR_ELT(N, Lo, Hi); break;
}
// If Lo/Hi is null, the sub-method took care of registering results etc.
@@ -428,6 +437,10 @@
#endif
assert(0 && "Do not know how to expand this operator's operand!");
abort();
+
+ case ISD::BIT_CONVERT: Res = ExpandOp_BIT_CONVERT(N); break;
+ case ISD::BUILD_VECTOR: Res = ExpandOp_BUILD_VECTOR(N); break;
+ case ISD::EXTRACT_ELEMENT: Res = ExpandOp_EXTRACT_ELEMENT(N); break;
}
}
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp?rev=52548&r1=52547&r2=52548&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp Fri Jun 20 13:40:50 2008
@@ -12,7 +12,7 @@
// computation in a larger type. For example, implementing i8 arithmetic in an
// i32 register (often needed on powerpc).
// Expansion is the act of changing a computation in an illegal type into a
-// computation in multiple registers of a smaller type. For example,
+// computation in two identical registers of a smaller type. For example,
// implementing i64 arithmetic in two i32 registers (often needed on 32-bit
// targets).
//
@@ -753,19 +753,24 @@
cerr << "ExpandIntegerResult #" << ResNo << ": ";
N->dump(&DAG); cerr << "\n";
#endif
- assert(0&&"Do not know how to expand the result of this operator!");
+ assert(0 && "Do not know how to expand the result of this operator!");
abort();
- case ISD::UNDEF: ExpandIntRes_UNDEF(N, Lo, Hi); break;
+ case ISD::MERGE_VALUES: SplitRes_MERGE_VALUES(N, Lo, Hi); break;
+ case ISD::SELECT: SplitRes_SELECT(N, Lo, Hi); break;
+ case ISD::SELECT_CC: SplitRes_SELECT_CC(N, Lo, Hi); break;
+ case ISD::UNDEF: SplitRes_UNDEF(N, Lo, Hi); break;
+
+ case ISD::BIT_CONVERT: ExpandRes_BIT_CONVERT(N, Lo, Hi); break;
+ case ISD::BUILD_PAIR: ExpandRes_BUILD_PAIR(N, Lo, Hi); break;
+ case ISD::EXTRACT_VECTOR_ELT: ExpandRes_EXTRACT_VECTOR_ELT(N, Lo, Hi); break;
+
case ISD::Constant: ExpandIntRes_Constant(N, Lo, Hi); break;
- case ISD::BUILD_PAIR: ExpandIntRes_BUILD_PAIR(N, Lo, Hi); break;
- case ISD::MERGE_VALUES: ExpandIntRes_MERGE_VALUES(N, Lo, Hi); break;
case ISD::ANY_EXTEND: ExpandIntRes_ANY_EXTEND(N, Lo, Hi); break;
case ISD::ZERO_EXTEND: ExpandIntRes_ZERO_EXTEND(N, Lo, Hi); break;
case ISD::SIGN_EXTEND: ExpandIntRes_SIGN_EXTEND(N, Lo, Hi); break;
case ISD::AssertZext: ExpandIntRes_AssertZext(N, Lo, Hi); break;
case ISD::TRUNCATE: ExpandIntRes_TRUNCATE(N, Lo, Hi); break;
- case ISD::BIT_CONVERT: ExpandIntRes_BIT_CONVERT(N, Lo, Hi); break;
case ISD::SIGN_EXTEND_INREG: ExpandIntRes_SIGN_EXTEND_INREG(N, Lo, Hi); break;
case ISD::FP_TO_SINT: ExpandIntRes_FP_TO_SINT(N, Lo, Hi); break;
case ISD::FP_TO_UINT: ExpandIntRes_FP_TO_UINT(N, Lo, Hi); break;
@@ -781,8 +786,6 @@
case ISD::SUBC: ExpandIntRes_ADDSUBC(N, Lo, Hi); break;
case ISD::ADDE:
case ISD::SUBE: ExpandIntRes_ADDSUBE(N, Lo, Hi); break;
- case ISD::SELECT: ExpandIntRes_SELECT(N, Lo, Hi); break;
- case ISD::SELECT_CC: ExpandIntRes_SELECT_CC(N, Lo, Hi); break;
case ISD::MUL: ExpandIntRes_MUL(N, Lo, Hi); break;
case ISD::SDIV: ExpandIntRes_SDIV(N, Lo, Hi); break;
case ISD::SREM: ExpandIntRes_SREM(N, Lo, Hi); break;
@@ -795,10 +798,6 @@
case ISD::CTLZ: ExpandIntRes_CTLZ(N, Lo, Hi); break;
case ISD::CTPOP: ExpandIntRes_CTPOP(N, Lo, Hi); break;
case ISD::CTTZ: ExpandIntRes_CTTZ(N, Lo, Hi); break;
-
- case ISD::EXTRACT_VECTOR_ELT:
- ExpandIntRes_EXTRACT_VECTOR_ELT(N, Lo, Hi);
- break;
}
// If Lo/Hi is null, the sub-method took care of registering results etc.
@@ -806,12 +805,6 @@
SetExpandedInteger(SDOperand(N, ResNo), Lo, Hi);
}
-void DAGTypeLegalizer::ExpandIntRes_UNDEF(SDNode *N,
- SDOperand &Lo, SDOperand &Hi) {
- MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
- Lo = Hi = DAG.getNode(ISD::UNDEF, NVT);
-}
-
void DAGTypeLegalizer::ExpandIntRes_Constant(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
@@ -821,34 +814,6 @@
Hi = DAG.getConstant(Cst.lshr(NBitWidth).trunc(NBitWidth), NVT);
}
-void DAGTypeLegalizer::ExpandIntRes_BUILD_PAIR(SDNode *N,
- SDOperand &Lo, SDOperand &Hi) {
- // Return the operands.
- Lo = N->getOperand(0);
- Hi = N->getOperand(1);
-}
-
-void DAGTypeLegalizer::ExpandIntRes_MERGE_VALUES(SDNode *N,
- SDOperand &Lo, SDOperand &Hi) {
- // A MERGE_VALUES node can produce any number of values. We know that the
- // first illegal one needs to be expanded into Lo/Hi.
- unsigned i;
-
- // The string of legal results gets turns into the input operands, which have
- // the same type.
- for (i = 0; isTypeLegal(N->getValueType(i)); ++i)
- ReplaceValueWith(SDOperand(N, i), SDOperand(N->getOperand(i)));
-
- // The first illegal result must be the one that needs to be expanded.
- GetExpandedInteger(N->getOperand(i), Lo, Hi);
-
- // Legalize the rest of the results into the input operands whether they are
- // legal or not.
- unsigned e = N->getNumValues();
- for (++i; i != e; ++i)
- ReplaceValueWith(SDOperand(N, i), SDOperand(N->getOperand(i)));
-}
-
void DAGTypeLegalizer::ExpandIntRes_ANY_EXTEND(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
@@ -950,61 +915,6 @@
Hi = DAG.getNode(ISD::TRUNCATE, NVT, Hi);
}
-void DAGTypeLegalizer::ExpandIntRes_BIT_CONVERT(SDNode *N,
- SDOperand &Lo, SDOperand &Hi) {
- MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
- SDOperand InOp = N->getOperand(0);
- MVT InVT = InOp.getValueType();
-
- // Handle some special cases efficiently.
- switch (getTypeAction(InVT)) {
- default:
- assert(false && "Unknown type action!");
- case Legal:
- case PromoteInteger:
- break;
- case SoftenFloat:
- // Convert the integer operand instead.
- SplitInteger(GetSoftenedFloat(InOp), Lo, Hi);
- Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Lo);
- Hi = DAG.getNode(ISD::BIT_CONVERT, NVT, Hi);
- return;
- case ExpandInteger:
- // Convert the expanded pieces of the input.
- GetExpandedInteger(InOp, Lo, Hi);
- Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Lo);
- Hi = DAG.getNode(ISD::BIT_CONVERT, NVT, Hi);
- return;
- case ExpandFloat:
- // Convert the expanded pieces of the input.
- GetExpandedFloat(InOp, Lo, Hi);
- Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Lo);
- Hi = DAG.getNode(ISD::BIT_CONVERT, NVT, Hi);
- return;
- case Split:
- // Convert the split parts of the input if it was split in two.
- GetSplitVector(InOp, Lo, Hi);
- if (Lo.getValueType() == Hi.getValueType()) {
- if (TLI.isBigEndian())
- std::swap(Lo, Hi);
- Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Lo);
- Hi = DAG.getNode(ISD::BIT_CONVERT, NVT, Hi);
- return;
- }
- break;
- case Scalarize:
- // Convert the element instead.
- SplitInteger(BitConvertToInteger(GetScalarizedVector(InOp)), Lo, Hi);
- Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Lo);
- Hi = DAG.getNode(ISD::BIT_CONVERT, NVT, Hi);
- return;
- }
-
- // Lower the bit-convert to a store/load from the stack, then expand the load.
- SDOperand Op = CreateStackStoreLoad(InOp, N->getValueType(0));
- ExpandIntRes_LOAD(cast<LoadSDNode>(Op.Val), Lo, Hi);
-}
-
void DAGTypeLegalizer::
ExpandIntRes_SIGN_EXTEND_INREG(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
GetExpandedInteger(N->getOperand(0), Lo, Hi);
@@ -1090,7 +1000,13 @@
void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N,
SDOperand &Lo, SDOperand &Hi) {
- // FIXME: Add support for indexed loads.
+ if (ISD::isNON_EXTLoad(N)) {
+ ExpandRes_NON_EXTLOAD(N, Lo, Hi);
+ return;
+ }
+
+ assert(ISD::isUNINDEXEDLoad(N) && "Indexed load during type legalization!");
+
MVT VT = N->getValueType(0);
MVT NVT = TLI.getTypeToTransformTo(VT);
SDOperand Ch = N->getChain(); // Legalize the chain.
@@ -1100,27 +1016,9 @@
unsigned Alignment = N->getAlignment();
bool isVolatile = N->isVolatile();
- assert(!(NVT.getSizeInBits() & 7) && "Expanded type not byte sized!");
-
- if (ExtType == ISD::NON_EXTLOAD) {
- Lo = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(), SVOffset,
- isVolatile, Alignment);
- // Increment the pointer to the other half.
- unsigned IncrementSize = NVT.getSizeInBits()/8;
- Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
- DAG.getIntPtrConstant(IncrementSize));
- Hi = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(), SVOffset+IncrementSize,
- isVolatile, MinAlign(Alignment, IncrementSize));
+ assert(NVT.isByteSized() && "Expanded type not byte sized!");
- // Build a factor node to remember that this load is independent of the
- // other one.
- Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1),
- Hi.getValue(1));
-
- // Handle endianness of the load.
- if (TLI.isBigEndian())
- std::swap(Lo, Hi);
- } else if (N->getMemoryVT().bitsLE(NVT)) {
+ if (N->getMemoryVT().bitsLE(NVT)) {
MVT EVT = N->getMemoryVT();
Lo = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(), SVOffset, EVT,
@@ -1225,26 +1123,6 @@
Hi = DAG.getNode(ISD::BSWAP, Hi.getValueType(), Hi);
}
-void DAGTypeLegalizer::ExpandIntRes_SELECT(SDNode *N,
- SDOperand &Lo, SDOperand &Hi) {
- SDOperand LL, LH, RL, RH;
- GetExpandedInteger(N->getOperand(1), LL, LH);
- GetExpandedInteger(N->getOperand(2), RL, RH);
- Lo = DAG.getNode(ISD::SELECT, LL.getValueType(), N->getOperand(0), LL, RL);
- Hi = DAG.getNode(ISD::SELECT, LL.getValueType(), N->getOperand(0), LH, RH);
-}
-
-void DAGTypeLegalizer::ExpandIntRes_SELECT_CC(SDNode *N,
- SDOperand &Lo, SDOperand &Hi) {
- SDOperand LL, LH, RL, RH;
- GetExpandedInteger(N->getOperand(2), LL, LH);
- GetExpandedInteger(N->getOperand(3), RL, RH);
- Lo = DAG.getNode(ISD::SELECT_CC, LL.getValueType(), N->getOperand(0),
- N->getOperand(1), LL, RL, N->getOperand(4));
- Hi = DAG.getNode(ISD::SELECT_CC, LL.getValueType(), N->getOperand(0),
- N->getOperand(1), LH, RH, N->getOperand(4));
-}
-
void DAGTypeLegalizer::ExpandIntRes_ADDSUB(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
// Expand the subcomponents.
@@ -1522,41 +1400,6 @@
Hi = DAG.getConstant(0, NVT);
}
-void DAGTypeLegalizer::ExpandIntRes_EXTRACT_VECTOR_ELT(SDNode *N,
- SDOperand &Lo,
- SDOperand &Hi) {
- SDOperand OldVec = N->getOperand(0);
- unsigned OldElts = OldVec.getValueType().getVectorNumElements();
-
- // Convert to a vector of the expanded element type, for example
- // <2 x i64> -> <4 x i32>.
- MVT OldVT = N->getValueType(0);
- MVT NewVT = TLI.getTypeToTransformTo(OldVT);
- assert(OldVT.getSizeInBits() == 2 * NewVT.getSizeInBits() &&
- "Do not know how to handle this expansion!");
-
- SDOperand NewVec = DAG.getNode(ISD::BIT_CONVERT,
- MVT::getVectorVT(NewVT, 2*OldElts),
- OldVec);
-
- // Extract the elements at 2 * Idx and 2 * Idx + 1 from the new vector.
- SDOperand Idx = N->getOperand(1);
-
- // Make sure the type of Idx is big enough to hold the new values.
- if (Idx.getValueType().bitsLT(TLI.getPointerTy()))
- Idx = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(), Idx);
-
- Idx = DAG.getNode(ISD::ADD, Idx.getValueType(), Idx, Idx);
- Lo = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewVT, NewVec, Idx);
-
- Idx = DAG.getNode(ISD::ADD, Idx.getValueType(), Idx,
- DAG.getConstant(1, Idx.getValueType()));
- Hi = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewVT, NewVec, Idx);
-
- if (TLI.isBigEndian())
- std::swap(Lo, Hi);
-}
-
/// ExpandShiftByConstant - N is a shift by a value that needs to be expanded,
/// and the shift amount is a constant 'Amt'. Expand the operation.
void DAGTypeLegalizer::ExpandShiftByConstant(SDNode *N, unsigned Amt,
@@ -1737,8 +1580,11 @@
assert(0 && "Do not know how to expand this operator's operand!");
abort();
+ case ISD::BUILD_VECTOR: Res = ExpandOp_BUILD_VECTOR(N); break;
+ case ISD::BIT_CONVERT: Res = ExpandOp_BIT_CONVERT(N); break;
+ case ISD::EXTRACT_ELEMENT: Res = ExpandOp_EXTRACT_ELEMENT(N); break;
+
case ISD::TRUNCATE: Res = ExpandIntOp_TRUNCATE(N); break;
- case ISD::BIT_CONVERT: Res = ExpandIntOp_BIT_CONVERT(N); break;
case ISD::SINT_TO_FP:
Res = ExpandIntOp_SINT_TO_FP(N->getOperand(0), N->getValueType(0));
@@ -1746,7 +1592,6 @@
case ISD::UINT_TO_FP:
Res = ExpandIntOp_UINT_TO_FP(N->getOperand(0), N->getValueType(0));
break;
- case ISD::EXTRACT_ELEMENT: Res = ExpandIntOp_EXTRACT_ELEMENT(N); break;
case ISD::BR_CC: Res = ExpandIntOp_BR_CC(N); break;
case ISD::SETCC: Res = ExpandIntOp_SETCC(N); break;
@@ -1754,8 +1599,6 @@
case ISD::STORE:
Res = ExpandIntOp_STORE(cast<StoreSDNode>(N), OpNo);
break;
-
- case ISD::BUILD_VECTOR: Res = ExpandIntOp_BUILD_VECTOR(N); break;
}
}
@@ -1785,32 +1628,6 @@
return DAG.getNode(ISD::TRUNCATE, N->getValueType(0), InL);
}
-SDOperand DAGTypeLegalizer::ExpandIntOp_BIT_CONVERT(SDNode *N) {
- if (N->getValueType(0).isVector()) {
- // An illegal integer type is being converted to a legal vector type.
- // Make a two element vector out of the expanded parts and convert that
- // instead, but only if the new vector type is legal (otherwise there
- // is no point, and it might create expansion loops). For example, on
- // x86 this turns v1i64 = BIT_CONVERT i64 into v1i64 = BIT_CONVERT v2i32.
- MVT OVT = N->getOperand(0).getValueType();
- MVT NVT = MVT::getVectorVT(TLI.getTypeToTransformTo(OVT), 2);
-
- if (isTypeLegal(NVT)) {
- SDOperand Parts[2];
- GetExpandedInteger(N->getOperand(0), Parts[0], Parts[1]);
-
- if (TLI.isBigEndian())
- std::swap(Parts[0], Parts[1]);
-
- SDOperand Vec = DAG.getNode(ISD::BUILD_VECTOR, NVT, Parts, 2);
- return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0), Vec);
- }
- }
-
- // Otherwise, store to a temporary and load out again as the new type.
- return CreateStackStoreLoad(N->getOperand(0), N->getValueType(0));
-}
-
SDOperand DAGTypeLegalizer::ExpandIntOp_SINT_TO_FP(SDOperand Source,
MVT DestTy) {
// We know the destination is legal, but that the input needs to be expanded.
@@ -1898,12 +1715,6 @@
return DAG.getNode(ISD::FADD, DestTy, SignedConv, FudgeInReg);
}
-SDOperand DAGTypeLegalizer::ExpandIntOp_EXTRACT_ELEMENT(SDNode *N) {
- SDOperand Lo, Hi;
- GetExpandedInteger(N->getOperand(0), Lo, Hi);
- return cast<ConstantSDNode>(N->getOperand(1))->getValue() ? Hi : Lo;
-}
-
SDOperand DAGTypeLegalizer::ExpandIntOp_BR_CC(SDNode *N) {
SDOperand NewLHS = N->getOperand(2), NewRHS = N->getOperand(3);
ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get();
@@ -2049,7 +1860,10 @@
}
SDOperand DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) {
- // FIXME: Add support for indexed stores.
+ if (ISD::isNON_TRUNCStore(N))
+ return ExpandOp_NON_TRUNCStore(N, OpNo);
+
+ assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!");
assert(OpNo == 1 && "Can only expand the stored value so far");
MVT VT = N->getOperand(1).getValueType();
@@ -2063,24 +1877,7 @@
assert(!(NVT.getSizeInBits() & 7) && "Expanded type not byte sized!");
- if (!N->isTruncatingStore()) {
- unsigned IncrementSize = 0;
- GetExpandedInteger(N->getValue(), Lo, Hi);
- IncrementSize = Hi.getValueType().getSizeInBits()/8;
-
- if (TLI.isBigEndian())
- std::swap(Lo, Hi);
-
- Lo = DAG.getStore(Ch, Lo, Ptr, N->getSrcValue(),
- SVOffset, isVolatile, Alignment);
-
- Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
- DAG.getIntPtrConstant(IncrementSize));
- assert(isTypeLegal(Ptr.getValueType()) && "Pointers must be legal!");
- Hi = DAG.getStore(Ch, Hi, Ptr, N->getSrcValue(), SVOffset+IncrementSize,
- isVolatile, MinAlign(Alignment, IncrementSize));
- return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
- } else if (N->getMemoryVT().bitsLE(NVT)) {
+ if (N->getMemoryVT().bitsLE(NVT)) {
GetExpandedInteger(N->getValue(), Lo, Hi);
return DAG.getTruncStore(Ch, Lo, Ptr, N->getSrcValue(), SVOffset,
N->getMemoryVT(), isVolatile, Alignment);
@@ -2140,35 +1937,3 @@
return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
}
}
-
-SDOperand DAGTypeLegalizer::ExpandIntOp_BUILD_VECTOR(SDNode *N) {
- // The vector type is legal but the element type needs expansion.
- MVT VecVT = N->getValueType(0);
- unsigned NumElts = VecVT.getVectorNumElements();
- MVT OldVT = N->getOperand(0).getValueType();
- MVT NewVT = TLI.getTypeToTransformTo(OldVT);
-
- assert(OldVT.getSizeInBits() == 2 * NewVT.getSizeInBits() &&
- "Do not know how to expand this operand!");
-
- // Build a vector of twice the length out of the expanded elements.
- // For example <2 x i64> -> <4 x i32>.
- std::vector<SDOperand> NewElts;
- NewElts.reserve(NumElts*2);
-
- for (unsigned i = 0; i < NumElts; ++i) {
- SDOperand Lo, Hi;
- GetExpandedInteger(N->getOperand(i), Lo, Hi);
- if (TLI.isBigEndian())
- std::swap(Lo, Hi);
- NewElts.push_back(Lo);
- NewElts.push_back(Hi);
- }
-
- SDOperand NewVec = DAG.getNode(ISD::BUILD_VECTOR,
- MVT::getVectorVT(NewVT, NewElts.size()),
- &NewElts[0], NewElts.size());
-
- // Convert the new vector to the old vector type.
- return DAG.getNode(ISD::BIT_CONVERT, VecVT, NewVec);
-}
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp?rev=52548&r1=52547&r2=52548&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp Fri Jun 20 13:40:50 2008
@@ -543,6 +543,10 @@
}
+//===----------------------------------------------------------------------===//
+// Utilities.
+//===----------------------------------------------------------------------===//
+
/// BitConvertToInteger - Convert to an integer of the same size.
SDOperand DAGTypeLegalizer::BitConvertToInteger(SDOperand Op) {
unsigned BitWidth = Op.getValueType().getSizeInBits();
@@ -637,6 +641,26 @@
return DAG.getNode(ISD::ADD, Index.getValueType(), Index, VecPtr);
}
+/// GetSplitDestVTs - Compute the VTs needed for the low/hi parts of a type
+/// which is split into two not necessarily identical pieces.
+void DAGTypeLegalizer::GetSplitDestVTs(MVT InVT, MVT &LoVT, MVT &HiVT) {
+ if (!InVT.isVector()) {
+ LoVT = HiVT = TLI.getTypeToTransformTo(InVT);
+ } else {
+ MVT NewEltVT = InVT.getVectorElementType();
+ unsigned NumElements = InVT.getVectorNumElements();
+ if ((NumElements & (NumElements-1)) == 0) { // Simple power of two vector.
+ NumElements >>= 1;
+ LoVT = HiVT = MVT::getVectorVT(NewEltVT, NumElements);
+ } else { // Non-power-of-two vectors.
+ unsigned NewNumElts_Lo = 1 << Log2_32(NumElements);
+ unsigned NewNumElts_Hi = NumElements - NewNumElts_Lo;
+ LoVT = MVT::getVectorVT(NewEltVT, NewNumElts_Lo);
+ HiVT = MVT::getVectorVT(NewEltVT, NewNumElts_Hi);
+ }
+ }
+}
+
//===----------------------------------------------------------------------===//
// Entry Point
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h?rev=52548&r1=52547&r2=52548&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Fri Jun 20 13:40:50 2008
@@ -267,19 +267,14 @@
void ExpandIntegerResult(SDNode *N, unsigned ResNo);
void ExpandIntRes_ANY_EXTEND (SDNode *N, SDOperand &Lo, SDOperand &Hi);
void ExpandIntRes_AssertZext (SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void ExpandIntRes_BIT_CONVERT (SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void ExpandIntRes_BUILD_PAIR (SDNode *N, SDOperand &Lo, SDOperand &Hi);
void ExpandIntRes_Constant (SDNode *N, SDOperand &Lo, SDOperand &Hi);
void ExpandIntRes_CTLZ (SDNode *N, SDOperand &Lo, SDOperand &Hi);
void ExpandIntRes_CTPOP (SDNode *N, SDOperand &Lo, SDOperand &Hi);
void ExpandIntRes_CTTZ (SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void ExpandIntRes_EXTRACT_VECTOR_ELT(SDNode *N, SDOperand &Lo, SDOperand &Hi);
void ExpandIntRes_LOAD (LoadSDNode *N, SDOperand &Lo, SDOperand &Hi);
- void ExpandIntRes_MERGE_VALUES (SDNode *N, SDOperand &Lo, SDOperand &Hi);
void ExpandIntRes_SIGN_EXTEND (SDNode *N, SDOperand &Lo, SDOperand &Hi);
void ExpandIntRes_SIGN_EXTEND_INREG (SDNode *N, SDOperand &Lo, SDOperand &Hi);
void ExpandIntRes_TRUNCATE (SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void ExpandIntRes_UNDEF (SDNode *N, SDOperand &Lo, SDOperand &Hi);
void ExpandIntRes_ZERO_EXTEND (SDNode *N, SDOperand &Lo, SDOperand &Hi);
void ExpandIntRes_FP_TO_SINT (SDNode *N, SDOperand &Lo, SDOperand &Hi);
void ExpandIntRes_FP_TO_UINT (SDNode *N, SDOperand &Lo, SDOperand &Hi);
@@ -289,8 +284,6 @@
void ExpandIntRes_ADDSUB (SDNode *N, SDOperand &Lo, SDOperand &Hi);
void ExpandIntRes_ADDSUBC (SDNode *N, SDOperand &Lo, SDOperand &Hi);
void ExpandIntRes_ADDSUBE (SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void ExpandIntRes_SELECT (SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void ExpandIntRes_SELECT_CC (SDNode *N, SDOperand &Lo, SDOperand &Hi);
void ExpandIntRes_MUL (SDNode *N, SDOperand &Lo, SDOperand &Hi);
void ExpandIntRes_SDIV (SDNode *N, SDOperand &Lo, SDOperand &Hi);
void ExpandIntRes_SREM (SDNode *N, SDOperand &Lo, SDOperand &Hi);
@@ -372,22 +365,22 @@
// Vector Result Scalarization: <1 x ty> -> ty.
void ScalarizeResult(SDNode *N, unsigned OpNo);
- SDOperand ScalarizeRes_BinOp(SDNode *N);
- SDOperand ScalarizeRes_UnaryOp(SDNode *N);
+ SDOperand ScalarizeVecRes_BinOp(SDNode *N);
+ SDOperand ScalarizeVecRes_UnaryOp(SDNode *N);
- SDOperand ScalarizeRes_BIT_CONVERT(SDNode *N);
- SDOperand ScalarizeRes_FPOWI(SDNode *N);
- SDOperand ScalarizeRes_INSERT_VECTOR_ELT(SDNode *N);
- SDOperand ScalarizeRes_LOAD(LoadSDNode *N);
- SDOperand ScalarizeRes_SELECT(SDNode *N);
- SDOperand ScalarizeRes_UNDEF(SDNode *N);
- SDOperand ScalarizeRes_VECTOR_SHUFFLE(SDNode *N);
+ SDOperand ScalarizeVecRes_BIT_CONVERT(SDNode *N);
+ SDOperand ScalarizeVecRes_FPOWI(SDNode *N);
+ SDOperand ScalarizeVecRes_INSERT_VECTOR_ELT(SDNode *N);
+ SDOperand ScalarizeVecRes_LOAD(LoadSDNode *N);
+ SDOperand ScalarizeVecRes_SELECT(SDNode *N);
+ SDOperand ScalarizeVecRes_UNDEF(SDNode *N);
+ SDOperand ScalarizeVecRes_VECTOR_SHUFFLE(SDNode *N);
// Vector Operand Scalarization: <1 x ty> -> ty.
bool ScalarizeOperand(SDNode *N, unsigned OpNo);
- SDOperand ScalarizeOp_BIT_CONVERT(SDNode *N);
- SDOperand ScalarizeOp_EXTRACT_VECTOR_ELT(SDNode *N);
- SDOperand ScalarizeOp_STORE(StoreSDNode *N, unsigned OpNo);
+ SDOperand ScalarizeVecOp_BIT_CONVERT(SDNode *N);
+ SDOperand ScalarizeVecOp_EXTRACT_VECTOR_ELT(SDNode *N);
+ SDOperand ScalarizeVecOp_STORE(StoreSDNode *N, unsigned OpNo);
//===--------------------------------------------------------------------===//
// Vector Splitting Support: LegalizeVectorTypes.cpp
@@ -399,29 +392,85 @@
// Vector Result Splitting: <128 x ty> -> 2 x <64 x ty>.
void SplitResult(SDNode *N, unsigned OpNo);
- void SplitRes_UNDEF(SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void SplitRes_LOAD(LoadSDNode *N, SDOperand &Lo, SDOperand &Hi);
- void SplitRes_BUILD_PAIR(SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void SplitRes_INSERT_VECTOR_ELT(SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void SplitRes_VECTOR_SHUFFLE(SDNode *N, SDOperand &Lo, SDOperand &Hi);
-
- void SplitRes_BUILD_VECTOR(SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void SplitRes_CONCAT_VECTORS(SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void SplitRes_BIT_CONVERT(SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void SplitRes_UnOp(SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void SplitRes_BinOp(SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void SplitRes_FPOWI(SDNode *N, SDOperand &Lo, SDOperand &Hi);
- void SplitRes_SELECT(SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void SplitVecRes_UNDEF(SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void SplitVecRes_LOAD(LoadSDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void SplitVecRes_BUILD_PAIR(SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void SplitVecRes_INSERT_VECTOR_ELT(SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void SplitVecRes_VECTOR_SHUFFLE(SDNode *N, SDOperand &Lo, SDOperand &Hi);
+
+ void SplitVecRes_BUILD_VECTOR(SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void SplitVecRes_CONCAT_VECTORS(SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void SplitVecRes_BIT_CONVERT(SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void SplitVecRes_UnOp(SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void SplitVecRes_BinOp(SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void SplitVecRes_FPOWI(SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void SplitVecRes_SELECT(SDNode *N, SDOperand &Lo, SDOperand &Hi);
// Vector Operand Splitting: <128 x ty> -> 2 x <64 x ty>.
bool SplitOperand(SDNode *N, unsigned OpNo);
- SDOperand SplitOp_BIT_CONVERT(SDNode *N);
- SDOperand SplitOp_EXTRACT_SUBVECTOR(SDNode *N);
- SDOperand SplitOp_EXTRACT_VECTOR_ELT(SDNode *N);
- SDOperand SplitOp_RET(SDNode *N, unsigned OpNo);
- SDOperand SplitOp_STORE(StoreSDNode *N, unsigned OpNo);
- SDOperand SplitOp_VECTOR_SHUFFLE(SDNode *N, unsigned OpNo);
+ SDOperand SplitVecOp_BIT_CONVERT(SDNode *N);
+ SDOperand SplitVecOp_EXTRACT_SUBVECTOR(SDNode *N);
+ SDOperand SplitVecOp_EXTRACT_VECTOR_ELT(SDNode *N);
+ SDOperand SplitVecOp_RET(SDNode *N, unsigned OpNo);
+ SDOperand SplitVecOp_STORE(StoreSDNode *N, unsigned OpNo);
+ SDOperand SplitVecOp_VECTOR_SHUFFLE(SDNode *N, unsigned OpNo);
+
+ //===--------------------------------------------------------------------===//
+ // Generic Splitting: LegalizeTypesGeneric.cpp
+ //===--------------------------------------------------------------------===//
+
+ // Legalization methods which only use that the illegal type is split into two
+ // not necessarily identical types. As such they can be used for splitting
+ // vectors and expanding integers and floats.
+
+ void GetSplitOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi) {
+ if (Op.getValueType().isVector())
+ GetSplitVector(Op, Lo, Hi);
+ else if (Op.getValueType().isInteger())
+ GetExpandedInteger(Op, Lo, Hi);
+ else
+ GetExpandedFloat(Op, Lo, Hi);
+ }
+
+ /// GetSplitDestVTs - Compute the VTs needed for the low/hi parts of a type
+ /// which is split (or expanded) into two not necessarily identical pieces.
+ void GetSplitDestVTs(MVT InVT, MVT &LoVT, MVT &HiVT);
+
+ // Generic Result Splitting.
+ void SplitRes_MERGE_VALUES(SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void SplitRes_SELECT (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void SplitRes_SELECT_CC (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void SplitRes_UNDEF (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+
+ //===--------------------------------------------------------------------===//
+ // Generic Expansion: LegalizeTypesGeneric.cpp
+ //===--------------------------------------------------------------------===//
+
+ // Legalization methods which only use that the illegal type is split into two
+ // identical types of half the size, and that the Lo/Hi part is stored first
+ // in memory on little/big-endian machines, followed by the Hi/Lo part. As
+ // such they can be used for expanding integers and floats.
+
+ void GetExpandedOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi) {
+ if (Op.getValueType().isInteger())
+ GetExpandedInteger(Op, Lo, Hi);
+ else
+ GetExpandedFloat(Op, Lo, Hi);
+ }
+
+ // Generic Result Expansion.
+ void ExpandRes_BIT_CONVERT (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandRes_BUILD_PAIR (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandRes_EXTRACT_VECTOR_ELT(SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void ExpandRes_NON_EXTLOAD (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+
+ // Generic Operand Expansion.
+ SDOperand ExpandOp_BIT_CONVERT (SDNode *N);
+ SDOperand ExpandOp_BUILD_VECTOR (SDNode *N);
+ SDOperand ExpandOp_EXTRACT_ELEMENT(SDNode *N);
+ SDOperand ExpandOp_NON_TRUNCStore (SDNode *N, unsigned OpNo);
+
};
} // end namespace llvm.
Added: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp?rev=52548&view=auto
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp (added)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp Fri Jun 20 13:40:50 2008
@@ -0,0 +1,318 @@
+//===-------- LegalizeTypesGeneric.cpp - Generic type legalization --------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements generic type expansion and splitting for LegalizeTypes.
+// The routines here perform legalization when the details of the type (such as
+// whether it is an integer or a float) do not matter.
+// Expansion is the act of changing a computation in an illegal type to be a
+// computation in two identical registers of a smaller type.
+// Splitting is the act of changing a computation in an illegal type to be a
+// computation in two not necessarily identical registers of a smaller type.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LegalizeTypes.h"
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+// Generic Result Expansion.
+//===----------------------------------------------------------------------===//
+
+// These routines assume that the Lo/Hi part is stored first in memory on
+// little/big-endian machines, followed by the Hi/Lo part. This means that
+// they cannot be used as is on vectors, for which Lo is always stored first.
+
+void DAGTypeLegalizer::ExpandRes_BIT_CONVERT(SDNode *N,
+ SDOperand &Lo, SDOperand &Hi) {
+ MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
+ SDOperand InOp = N->getOperand(0);
+ MVT InVT = InOp.getValueType();
+
+ // Handle some special cases efficiently.
+ switch (getTypeAction(InVT)) {
+ default:
+ assert(false && "Unknown type action!");
+ case Legal:
+ case PromoteInteger:
+ break;
+ case SoftenFloat:
+ // Convert the integer operand instead.
+ SplitInteger(GetSoftenedFloat(InOp), Lo, Hi);
+ Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Lo);
+ Hi = DAG.getNode(ISD::BIT_CONVERT, NVT, Hi);
+ return;
+ case ExpandInteger:
+ case ExpandFloat:
+ // Convert the expanded pieces of the input.
+ GetExpandedOp(InOp, Lo, Hi);
+ Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Lo);
+ Hi = DAG.getNode(ISD::BIT_CONVERT, NVT, Hi);
+ return;
+ case Split:
+ // Convert the split parts of the input if it was split in two.
+ GetSplitVector(InOp, Lo, Hi);
+ if (Lo.getValueType() == Hi.getValueType()) {
+ if (TLI.isBigEndian())
+ std::swap(Lo, Hi);
+ Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Lo);
+ Hi = DAG.getNode(ISD::BIT_CONVERT, NVT, Hi);
+ return;
+ }
+ break;
+ case Scalarize:
+ // Convert the element instead.
+ SplitInteger(BitConvertToInteger(GetScalarizedVector(InOp)), Lo, Hi);
+ Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Lo);
+ Hi = DAG.getNode(ISD::BIT_CONVERT, NVT, Hi);
+ return;
+ }
+
+ // Lower the bit-convert to a store/load from the stack, then expand the load.
+ SDOperand Op = CreateStackStoreLoad(InOp, N->getValueType(0));
+ ExpandRes_NON_EXTLOAD(Op.Val, Lo, Hi);
+}
+
+void DAGTypeLegalizer::ExpandRes_BUILD_PAIR(SDNode *N,
+ SDOperand &Lo, SDOperand &Hi) {
+ // Return the operands.
+ Lo = N->getOperand(0);
+ Hi = N->getOperand(1);
+}
+
+void DAGTypeLegalizer::ExpandRes_EXTRACT_VECTOR_ELT(SDNode *N,
+ SDOperand &Lo,
+ SDOperand &Hi) {
+ SDOperand OldVec = N->getOperand(0);
+ unsigned OldElts = OldVec.getValueType().getVectorNumElements();
+
+ // Convert to a vector of the expanded element type, for example
+ // <3 x i64> -> <6 x i32>.
+ MVT OldVT = N->getValueType(0);
+ MVT NewVT = TLI.getTypeToTransformTo(OldVT);
+
+ SDOperand NewVec = DAG.getNode(ISD::BIT_CONVERT,
+ MVT::getVectorVT(NewVT, 2*OldElts),
+ OldVec);
+
+ // Extract the elements at 2 * Idx and 2 * Idx + 1 from the new vector.
+ SDOperand Idx = N->getOperand(1);
+
+ // Make sure the type of Idx is big enough to hold the new values.
+ if (Idx.getValueType().bitsLT(TLI.getPointerTy()))
+ Idx = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(), Idx);
+
+ Idx = DAG.getNode(ISD::ADD, Idx.getValueType(), Idx, Idx);
+ Lo = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewVT, NewVec, Idx);
+
+ Idx = DAG.getNode(ISD::ADD, Idx.getValueType(), Idx,
+ DAG.getConstant(1, Idx.getValueType()));
+ Hi = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewVT, NewVec, Idx);
+
+ if (TLI.isBigEndian())
+ std::swap(Lo, Hi);
+}
+
+void DAGTypeLegalizer::ExpandRes_NON_EXTLOAD(SDNode *N, SDOperand &Lo,
+ SDOperand &Hi) {
+ assert(ISD::isNON_EXTLoad(N) && "This routine is not for extending loads!");
+ assert(ISD::isUNINDEXEDLoad(N) && "Indexed load during type legalization!");
+
+ LoadSDNode *LD = cast<LoadSDNode>(N);
+ MVT NVT = TLI.getTypeToTransformTo(LD->getValueType(0));
+ SDOperand Chain = LD->getChain();
+ SDOperand Ptr = LD->getBasePtr();
+ int SVOffset = LD->getSrcValueOffset();
+ unsigned Alignment = LD->getAlignment();
+ bool isVolatile = LD->isVolatile();
+
+ assert(NVT.isByteSized() && "Expanded type not byte sized!");
+
+ Lo = DAG.getLoad(NVT, Chain, Ptr, LD->getSrcValue(), SVOffset,
+ isVolatile, Alignment);
+
+ // Increment the pointer to the other half.
+ unsigned IncrementSize = NVT.getSizeInBits() / 8;
+ Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
+ DAG.getIntPtrConstant(IncrementSize));
+ Hi = DAG.getLoad(NVT, Chain, Ptr, LD->getSrcValue(), SVOffset+IncrementSize,
+ isVolatile, MinAlign(Alignment, IncrementSize));
+
+ // Build a factor node to remember that this load is independent of the
+ // other one.
+ Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1),
+ Hi.getValue(1));
+
+ // Handle endianness of the load.
+ if (TLI.isBigEndian())
+ std::swap(Lo, Hi);
+
+ // Modified the chain - switch anything that used the old chain to use
+ // the new one.
+ ReplaceValueWith(SDOperand(N, 1), Chain);
+}
+
+//===--------------------------------------------------------------------===//
+// Generic Operand Expansion.
+//===--------------------------------------------------------------------===//
+
+SDOperand DAGTypeLegalizer::ExpandOp_BIT_CONVERT(SDNode *N) {
+ if (N->getValueType(0).isVector()) {
+ // An illegal expanding type is being converted to a legal vector type.
+ // Make a two element vector out of the expanded parts and convert that
+ // instead, but only if the new vector type is legal (otherwise there
+ // is no point, and it might create expansion loops). For example, on
+ // x86 this turns v1i64 = BIT_CONVERT i64 into v1i64 = BIT_CONVERT v2i32.
+ MVT OVT = N->getOperand(0).getValueType();
+ MVT NVT = MVT::getVectorVT(TLI.getTypeToTransformTo(OVT), 2);
+
+ if (isTypeLegal(NVT)) {
+ SDOperand Parts[2];
+ GetExpandedOp(N->getOperand(0), Parts[0], Parts[1]);
+
+ if (TLI.isBigEndian())
+ std::swap(Parts[0], Parts[1]);
+
+ SDOperand Vec = DAG.getNode(ISD::BUILD_VECTOR, NVT, Parts, 2);
+ return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0), Vec);
+ }
+ }
+
+ // Otherwise, store to a temporary and load out again as the new type.
+ return CreateStackStoreLoad(N->getOperand(0), N->getValueType(0));
+}
+
+SDOperand DAGTypeLegalizer::ExpandOp_BUILD_VECTOR(SDNode *N) {
+ // The vector type is legal but the element type needs expansion.
+ MVT VecVT = N->getValueType(0);
+ unsigned NumElts = VecVT.getVectorNumElements();
+ MVT OldVT = N->getOperand(0).getValueType();
+ MVT NewVT = TLI.getTypeToTransformTo(OldVT);
+
+ // Build a vector of twice the length out of the expanded elements.
+ // For example <3 x i64> -> <6 x i32>.
+ std::vector<SDOperand> NewElts;
+ NewElts.reserve(NumElts*2);
+
+ for (unsigned i = 0; i < NumElts; ++i) {
+ SDOperand Lo, Hi;
+ GetExpandedOp(N->getOperand(i), Lo, Hi);
+ if (TLI.isBigEndian())
+ std::swap(Lo, Hi);
+ NewElts.push_back(Lo);
+ NewElts.push_back(Hi);
+ }
+
+ SDOperand NewVec = DAG.getNode(ISD::BUILD_VECTOR,
+ MVT::getVectorVT(NewVT, NewElts.size()),
+ &NewElts[0], NewElts.size());
+
+ // Convert the new vector to the old vector type.
+ return DAG.getNode(ISD::BIT_CONVERT, VecVT, NewVec);
+}
+
+SDOperand DAGTypeLegalizer::ExpandOp_EXTRACT_ELEMENT(SDNode *N) {
+ SDOperand Lo, Hi;
+ GetExpandedOp(N->getOperand(0), Lo, Hi);
+ return cast<ConstantSDNode>(N->getOperand(1))->getValue() ? Hi : Lo;
+}
+
+SDOperand DAGTypeLegalizer::ExpandOp_NON_TRUNCStore(SDNode *N, unsigned OpNo) {
+ assert(ISD::isNON_TRUNCStore(N) && "This routine not for truncating stores!");
+ assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!");
+ assert(OpNo == 1 && "Can only expand the stored value so far");
+
+ StoreSDNode *St = cast<StoreSDNode>(N);
+ MVT NVT = TLI.getTypeToTransformTo(St->getValue().getValueType());
+ SDOperand Chain = St->getChain();
+ SDOperand Ptr = St->getBasePtr();
+ int SVOffset = St->getSrcValueOffset();
+ unsigned Alignment = St->getAlignment();
+ bool isVolatile = St->isVolatile();
+
+ assert(NVT.isByteSized() && "Expanded type not byte sized!");
+ unsigned IncrementSize = NVT.getSizeInBits() / 8;
+
+ SDOperand Lo, Hi;
+ GetExpandedOp(St->getValue(), Lo, Hi);
+
+ if (TLI.isBigEndian())
+ std::swap(Lo, Hi);
+
+ Lo = DAG.getStore(Chain, Lo, Ptr, St->getSrcValue(), SVOffset,
+ isVolatile, Alignment);
+
+ Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
+ DAG.getIntPtrConstant(IncrementSize));
+ assert(isTypeLegal(Ptr.getValueType()) && "Pointers must be legal!");
+ Hi = DAG.getStore(Chain, Hi, Ptr, St->getSrcValue(), SVOffset + IncrementSize,
+ isVolatile, MinAlign(Alignment, IncrementSize));
+
+ return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
+}
+
+
+//===--------------------------------------------------------------------===//
+// Generic Result Splitting.
+//===--------------------------------------------------------------------===//
+
+// Be careful to make no assumptions about which of Lo/Hi is stored first in
+// memory (for vectors it is always Lo first followed by Hi in the following
+// bytes; for integers and floats it is Lo first if and only if the machine is
+// little-endian).
+
+void DAGTypeLegalizer::SplitRes_MERGE_VALUES(SDNode *N,
+ SDOperand &Lo, SDOperand &Hi) {
+ // A MERGE_VALUES node can produce any number of values. We know that the
+ // first illegal one needs to be expanded into Lo/Hi.
+ unsigned i;
+
+ // The string of legal results gets turns into the input operands, which have
+ // the same type.
+ for (i = 0; isTypeLegal(N->getValueType(i)); ++i)
+ ReplaceValueWith(SDOperand(N, i), SDOperand(N->getOperand(i)));
+
+ // The first illegal result must be the one that needs to be expanded.
+ GetSplitOp(N->getOperand(i), Lo, Hi);
+
+ // Legalize the rest of the results into the input operands whether they are
+ // legal or not.
+ unsigned e = N->getNumValues();
+ for (++i; i != e; ++i)
+ ReplaceValueWith(SDOperand(N, i), SDOperand(N->getOperand(i)));
+}
+
+void DAGTypeLegalizer::SplitRes_SELECT(SDNode *N, SDOperand &Lo,
+ SDOperand &Hi) {
+ SDOperand LL, LH, RL, RH;
+ GetSplitOp(N->getOperand(1), LL, LH);
+ GetSplitOp(N->getOperand(2), RL, RH);
+
+ SDOperand Cond = N->getOperand(0);
+ Lo = DAG.getNode(ISD::SELECT, LL.getValueType(), Cond, LL, RL);
+ Hi = DAG.getNode(ISD::SELECT, LH.getValueType(), Cond, LH, RH);
+}
+
+void DAGTypeLegalizer::SplitRes_SELECT_CC(SDNode *N, SDOperand &Lo,
+ SDOperand &Hi) {
+ SDOperand LL, LH, RL, RH;
+ GetSplitOp(N->getOperand(2), LL, LH);
+ GetSplitOp(N->getOperand(3), RL, RH);
+
+ Lo = DAG.getNode(ISD::SELECT_CC, LL.getValueType(), N->getOperand(0),
+ N->getOperand(1), LL, RL, N->getOperand(4));
+ Hi = DAG.getNode(ISD::SELECT_CC, LH.getValueType(), N->getOperand(0),
+ N->getOperand(1), LH, RH, N->getOperand(4));
+}
+
+void DAGTypeLegalizer::SplitRes_UNDEF(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
+ MVT LoVT, HiVT;
+ GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
+ Lo = DAG.getNode(ISD::UNDEF, LoVT);
+ Hi = DAG.getNode(ISD::UNDEF, HiVT);
+}
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp?rev=52548&r1=52547&r2=52548&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp Fri Jun 20 13:40:50 2008
@@ -56,8 +56,9 @@
assert(0 && "Do not know how to scalarize the result of this operator!");
abort();
- case ISD::UNDEF: R = ScalarizeRes_UNDEF(N); break;
- case ISD::LOAD: R = ScalarizeRes_LOAD(cast<LoadSDNode>(N)); break;
+ case ISD::UNDEF: R = ScalarizeVecRes_UNDEF(N); break;
+ case ISD::LOAD: R = ScalarizeVecRes_LOAD(cast<LoadSDNode>(N)); break;
+
case ISD::ADD:
case ISD::FADD:
case ISD::SUB:
@@ -73,18 +74,20 @@
case ISD::FPOW:
case ISD::AND:
case ISD::OR:
- case ISD::XOR: R = ScalarizeRes_BinOp(N); break;
+ case ISD::XOR: R = ScalarizeVecRes_BinOp(N); break;
+
case ISD::FNEG:
case ISD::FABS:
case ISD::FSQRT:
case ISD::FSIN:
- case ISD::FCOS: R = ScalarizeRes_UnaryOp(N); break;
- case ISD::FPOWI: R = ScalarizeRes_FPOWI(N); break;
+ case ISD::FCOS: R = ScalarizeVecRes_UnaryOp(N); break;
+
+ case ISD::FPOWI: R = ScalarizeVecRes_FPOWI(N); break;
case ISD::BUILD_VECTOR: R = N->getOperand(0); break;
- case ISD::INSERT_VECTOR_ELT: R = ScalarizeRes_INSERT_VECTOR_ELT(N); break;
- case ISD::VECTOR_SHUFFLE: R = ScalarizeRes_VECTOR_SHUFFLE(N); break;
- case ISD::BIT_CONVERT: R = ScalarizeRes_BIT_CONVERT(N); break;
- case ISD::SELECT: R = ScalarizeRes_SELECT(N); break;
+ case ISD::INSERT_VECTOR_ELT: R = ScalarizeVecRes_INSERT_VECTOR_ELT(N); break;
+ case ISD::VECTOR_SHUFFLE: R = ScalarizeVecRes_VECTOR_SHUFFLE(N); break;
+ case ISD::BIT_CONVERT: R = ScalarizeVecRes_BIT_CONVERT(N); break;
+ case ISD::SELECT: R = ScalarizeVecRes_SELECT(N); break;
}
// If R is null, the sub-method took care of registering the result.
@@ -92,11 +95,11 @@
SetScalarizedVector(SDOperand(N, ResNo), R);
}
-SDOperand DAGTypeLegalizer::ScalarizeRes_UNDEF(SDNode *N) {
+SDOperand DAGTypeLegalizer::ScalarizeVecRes_UNDEF(SDNode *N) {
return DAG.getNode(ISD::UNDEF, N->getValueType(0).getVectorElementType());
}
-SDOperand DAGTypeLegalizer::ScalarizeRes_LOAD(LoadSDNode *N) {
+SDOperand DAGTypeLegalizer::ScalarizeVecRes_LOAD(LoadSDNode *N) {
// FIXME: Add support for indexed loads.
SDOperand Result = DAG.getLoad(N->getValueType(0).getVectorElementType(),
N->getChain(), N->getBasePtr(),
@@ -109,23 +112,23 @@
return Result;
}
-SDOperand DAGTypeLegalizer::ScalarizeRes_BinOp(SDNode *N) {
+SDOperand DAGTypeLegalizer::ScalarizeVecRes_BinOp(SDNode *N) {
SDOperand LHS = GetScalarizedVector(N->getOperand(0));
SDOperand RHS = GetScalarizedVector(N->getOperand(1));
return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS);
}
-SDOperand DAGTypeLegalizer::ScalarizeRes_UnaryOp(SDNode *N) {
+SDOperand DAGTypeLegalizer::ScalarizeVecRes_UnaryOp(SDNode *N) {
SDOperand Op = GetScalarizedVector(N->getOperand(0));
return DAG.getNode(N->getOpcode(), Op.getValueType(), Op);
}
-SDOperand DAGTypeLegalizer::ScalarizeRes_FPOWI(SDNode *N) {
+SDOperand DAGTypeLegalizer::ScalarizeVecRes_FPOWI(SDNode *N) {
SDOperand Op = GetScalarizedVector(N->getOperand(0));
return DAG.getNode(ISD::FPOWI, Op.getValueType(), Op, N->getOperand(1));
}
-SDOperand DAGTypeLegalizer::ScalarizeRes_INSERT_VECTOR_ELT(SDNode *N) {
+SDOperand DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(SDNode *N) {
// The value to insert may have a wider type than the vector element type,
// so be sure to truncate it to the element type if necessary.
SDOperand Op = N->getOperand(1);
@@ -136,19 +139,19 @@
return Op;
}
-SDOperand DAGTypeLegalizer::ScalarizeRes_VECTOR_SHUFFLE(SDNode *N) {
+SDOperand DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(SDNode *N) {
// Figure out if the scalar is the LHS or RHS and return it.
SDOperand EltNum = N->getOperand(2).getOperand(0);
unsigned Op = cast<ConstantSDNode>(EltNum)->getValue() != 0;
return GetScalarizedVector(N->getOperand(Op));
}
-SDOperand DAGTypeLegalizer::ScalarizeRes_BIT_CONVERT(SDNode *N) {
+SDOperand DAGTypeLegalizer::ScalarizeVecRes_BIT_CONVERT(SDNode *N) {
MVT NewVT = N->getValueType(0).getVectorElementType();
return DAG.getNode(ISD::BIT_CONVERT, NewVT, N->getOperand(0));
}
-SDOperand DAGTypeLegalizer::ScalarizeRes_SELECT(SDNode *N) {
+SDOperand DAGTypeLegalizer::ScalarizeVecRes_SELECT(SDNode *N) {
SDOperand LHS = GetScalarizedVector(N->getOperand(1));
return DAG.getNode(ISD::SELECT, LHS.getValueType(), N->getOperand(0), LHS,
GetScalarizedVector(N->getOperand(2)));
@@ -182,13 +185,13 @@
abort();
case ISD::BIT_CONVERT:
- Res = ScalarizeOp_BIT_CONVERT(N); break;
+ Res = ScalarizeVecOp_BIT_CONVERT(N); break;
case ISD::EXTRACT_VECTOR_ELT:
- Res = ScalarizeOp_EXTRACT_VECTOR_ELT(N); break;
+ Res = ScalarizeVecOp_EXTRACT_VECTOR_ELT(N); break;
case ISD::STORE:
- Res = ScalarizeOp_STORE(cast<StoreSDNode>(N), OpNo); break;
+ Res = ScalarizeVecOp_STORE(cast<StoreSDNode>(N), OpNo); break;
}
}
@@ -212,23 +215,23 @@
return false;
}
-/// ScalarizeOp_BIT_CONVERT - If the value to convert is a vector that needs
+/// ScalarizeVecOp_BIT_CONVERT - If the value to convert is a vector that needs
/// to be scalarized, it must be <1 x ty>. Convert the element instead.
-SDOperand DAGTypeLegalizer::ScalarizeOp_BIT_CONVERT(SDNode *N) {
+SDOperand DAGTypeLegalizer::ScalarizeVecOp_BIT_CONVERT(SDNode *N) {
SDOperand Elt = GetScalarizedVector(N->getOperand(0));
return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0), Elt);
}
-/// ScalarizeOp_EXTRACT_VECTOR_ELT - If the input is a vector that needs to be
-/// scalarized, it must be <1 x ty>, so just return the element, ignoring the
+/// ScalarizeVecOp_EXTRACT_VECTOR_ELT - If the input is a vector that needs to
+/// be scalarized, it must be <1 x ty>, so just return the element, ignoring the
/// index.
-SDOperand DAGTypeLegalizer::ScalarizeOp_EXTRACT_VECTOR_ELT(SDNode *N) {
+SDOperand DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(SDNode *N) {
return GetScalarizedVector(N->getOperand(0));
}
-/// ScalarizeOp_STORE - If the value to store is a vector that needs to be
+/// ScalarizeVecOp_STORE - If the value to store is a vector that needs to be
/// scalarized, it must be <1 x ty>. Just store the element.
-SDOperand DAGTypeLegalizer::ScalarizeOp_STORE(StoreSDNode *N, unsigned OpNo) {
+SDOperand DAGTypeLegalizer::ScalarizeVecOp_STORE(StoreSDNode *N, unsigned OpNo){
// FIXME: Add support for indexed stores.
assert(OpNo == 1 && "Do not know how to scalarize this operand!");
return DAG.getStore(N->getChain(), GetScalarizedVector(N->getOperand(1)),
@@ -237,23 +240,6 @@
}
-/// GetSplitDestVTs - Compute the VTs needed for the low/hi parts of a vector
-/// type that needs to be split. This handles non-power of two vectors.
-static void GetSplitDestVTs(MVT InVT, MVT &Lo, MVT &Hi) {
- MVT NewEltVT = InVT.getVectorElementType();
- unsigned NumElements = InVT.getVectorNumElements();
- if ((NumElements & (NumElements-1)) == 0) { // Simple power of two vector.
- NumElements >>= 1;
- Lo = Hi = MVT::getVectorVT(NewEltVT, NumElements);
- } else { // Non-power-of-two vectors.
- unsigned NewNumElts_Lo = 1 << Log2_32(NumElements);
- unsigned NewNumElts_Hi = NumElements - NewNumElts_Lo;
- Lo = MVT::getVectorVT(NewEltVT, NewNumElts_Lo);
- Hi = MVT::getVectorVT(NewEltVT, NewNumElts_Hi);
- }
-}
-
-
//===----------------------------------------------------------------------===//
// Result Vector Splitting
//===----------------------------------------------------------------------===//
@@ -290,14 +276,20 @@
assert(0 && "Do not know how to split the result of this operator!");
abort();
- case ISD::UNDEF: SplitRes_UNDEF(N, Lo, Hi); break;
- case ISD::LOAD: SplitRes_LOAD(cast<LoadSDNode>(N), Lo, Hi); break;
- case ISD::BUILD_PAIR: SplitRes_BUILD_PAIR(N, Lo, Hi); break;
- case ISD::INSERT_VECTOR_ELT:SplitRes_INSERT_VECTOR_ELT(N, Lo, Hi); break;
- case ISD::VECTOR_SHUFFLE: SplitRes_VECTOR_SHUFFLE(N, Lo, Hi); break;
- case ISD::BUILD_VECTOR: SplitRes_BUILD_VECTOR(N, Lo, Hi); break;
- case ISD::CONCAT_VECTORS: SplitRes_CONCAT_VECTORS(N, Lo, Hi); break;
- case ISD::BIT_CONVERT: SplitRes_BIT_CONVERT(N, Lo, Hi); break;
+ case ISD::MERGE_VALUES: SplitRes_MERGE_VALUES(N, Lo, Hi); break;
+ case ISD::SELECT: SplitRes_SELECT(N, Lo, Hi); break;
+ case ISD::SELECT_CC: SplitRes_SELECT_CC(N, Lo, Hi); break;
+ case ISD::UNDEF: SplitRes_UNDEF(N, Lo, Hi); break;
+
+ case ISD::LOAD:
+ SplitVecRes_LOAD(cast<LoadSDNode>(N), Lo, Hi);
+ break;
+ case ISD::BUILD_PAIR: SplitVecRes_BUILD_PAIR(N, Lo, Hi); break;
+ case ISD::INSERT_VECTOR_ELT:SplitVecRes_INSERT_VECTOR_ELT(N, Lo, Hi); break;
+ case ISD::VECTOR_SHUFFLE: SplitVecRes_VECTOR_SHUFFLE(N, Lo, Hi); break;
+ case ISD::BUILD_VECTOR: SplitVecRes_BUILD_VECTOR(N, Lo, Hi); break;
+ case ISD::CONCAT_VECTORS: SplitVecRes_CONCAT_VECTORS(N, Lo, Hi); break;
+ case ISD::BIT_CONVERT: SplitVecRes_BIT_CONVERT(N, Lo, Hi); break;
case ISD::CTTZ:
case ISD::CTLZ:
case ISD::CTPOP:
@@ -309,7 +301,7 @@
case ISD::FP_TO_SINT:
case ISD::FP_TO_UINT:
case ISD::SINT_TO_FP:
- case ISD::UINT_TO_FP: SplitRes_UnOp(N, Lo, Hi); break;
+ case ISD::UINT_TO_FP: SplitVecRes_UnOp(N, Lo, Hi); break;
case ISD::ADD:
case ISD::SUB:
case ISD::MUL:
@@ -325,9 +317,8 @@
case ISD::XOR:
case ISD::UREM:
case ISD::SREM:
- case ISD::FREM: SplitRes_BinOp(N, Lo, Hi); break;
- case ISD::FPOWI: SplitRes_FPOWI(N, Lo, Hi); break;
- case ISD::SELECT: SplitRes_SELECT(N, Lo, Hi); break;
+ case ISD::FREM: SplitVecRes_BinOp(N, Lo, Hi); break;
+ case ISD::FPOWI: SplitVecRes_FPOWI(N, Lo, Hi); break;
}
// If Lo/Hi is null, the sub-method took care of registering results etc.
@@ -335,16 +326,8 @@
SetSplitVector(SDOperand(N, ResNo), Lo, Hi);
}
-void DAGTypeLegalizer::SplitRes_UNDEF(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
- MVT LoVT, HiVT;
- GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
-
- Lo = DAG.getNode(ISD::UNDEF, LoVT);
- Hi = DAG.getNode(ISD::UNDEF, HiVT);
-}
-
-void DAGTypeLegalizer::SplitRes_LOAD(LoadSDNode *LD,
- SDOperand &Lo, SDOperand &Hi) {
+void DAGTypeLegalizer::SplitVecRes_LOAD(LoadSDNode *LD, SDOperand &Lo,
+ SDOperand &Hi) {
// FIXME: Add support for indexed loads.
MVT LoVT, HiVT;
GetSplitDestVTs(LD->getValueType(0), LoVT, HiVT);
@@ -374,14 +357,19 @@
ReplaceValueWith(SDOperand(LD, 1), TF);
}
-void DAGTypeLegalizer::SplitRes_BUILD_PAIR(SDNode *N, SDOperand &Lo,
- SDOperand &Hi) {
+void DAGTypeLegalizer::SplitVecRes_BUILD_PAIR(SDNode *N, SDOperand &Lo,
+ SDOperand &Hi) {
+#ifndef NDEBUG
+ MVT LoVT, HiVT;
+ GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
+ assert(LoVT == HiVT && "Non-power-of-two vectors not supported!");
+#endif
Lo = N->getOperand(0);
Hi = N->getOperand(1);
}
-void DAGTypeLegalizer::SplitRes_INSERT_VECTOR_ELT(SDNode *N, SDOperand &Lo,
- SDOperand &Hi) {
+void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(SDNode *N, SDOperand &Lo,
+ SDOperand &Hi) {
SDOperand Vec = N->getOperand(0);
SDOperand Elt = N->getOperand(1);
SDOperand Idx = N->getOperand(2);
@@ -412,11 +400,11 @@
SDOperand Load = DAG.getLoad(VecVT, Store, StackPtr, NULL, 0);
// Split it.
- SplitRes_LOAD(cast<LoadSDNode>(Load.Val), Lo, Hi);
+ SplitVecRes_LOAD(cast<LoadSDNode>(Load.Val), Lo, Hi);
}
-void DAGTypeLegalizer::SplitRes_VECTOR_SHUFFLE(SDNode *N,
- SDOperand &Lo, SDOperand &Hi) {
+void DAGTypeLegalizer::SplitVecRes_VECTOR_SHUFFLE(SDNode *N, SDOperand &Lo,
+ SDOperand &Hi) {
// Build the low part.
SDOperand Mask = N->getOperand(2);
SmallVector<SDOperand, 16> Ops;
@@ -455,8 +443,8 @@
Hi = DAG.getNode(ISD::BUILD_VECTOR, HiVT, &Ops[0], Ops.size());
}
-void DAGTypeLegalizer::SplitRes_BUILD_VECTOR(SDNode *N, SDOperand &Lo,
- SDOperand &Hi) {
+void DAGTypeLegalizer::SplitVecRes_BUILD_VECTOR(SDNode *N, SDOperand &Lo,
+ SDOperand &Hi) {
MVT LoVT, HiVT;
GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
unsigned LoNumElts = LoVT.getVectorNumElements();
@@ -467,8 +455,8 @@
Hi = DAG.getNode(ISD::BUILD_VECTOR, HiVT, &HiOps[0], HiOps.size());
}
-void DAGTypeLegalizer::SplitRes_CONCAT_VECTORS(SDNode *N,
- SDOperand &Lo, SDOperand &Hi) {
+void DAGTypeLegalizer::SplitVecRes_CONCAT_VECTORS(SDNode *N, SDOperand &Lo,
+ SDOperand &Hi) {
// FIXME: Handle non-power-of-two vectors?
unsigned NumSubvectors = N->getNumOperands() / 2;
if (NumSubvectors == 1) {
@@ -487,8 +475,8 @@
Hi = DAG.getNode(ISD::CONCAT_VECTORS, HiVT, &HiOps[0], HiOps.size());
}
-void DAGTypeLegalizer::SplitRes_BIT_CONVERT(SDNode *N,
- SDOperand &Lo, SDOperand &Hi) {
+void DAGTypeLegalizer::SplitVecRes_BIT_CONVERT(SDNode *N, SDOperand &Lo,
+ SDOperand &Hi) {
// We know the result is a vector. The input may be either a vector or a
// scalar value.
MVT LoVT, HiVT;
@@ -512,10 +500,7 @@
// If the vector is being split in two then we can just convert the
// expanded pieces.
if (LoVT == HiVT) {
- if (InVT.isInteger())
- GetExpandedInteger(InOp, Lo, Hi);
- else
- GetExpandedFloat(InOp, Lo, Hi);
+ GetExpandedOp(InOp, Lo, Hi);
if (TLI.isBigEndian())
std::swap(Lo, Hi);
Lo = DAG.getNode(ISD::BIT_CONVERT, LoVT, Lo);
@@ -546,7 +531,8 @@
Hi = DAG.getNode(ISD::BIT_CONVERT, HiVT, Hi);
}
-void DAGTypeLegalizer::SplitRes_BinOp(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
+void DAGTypeLegalizer::SplitVecRes_BinOp(SDNode *N, SDOperand &Lo,
+ SDOperand &Hi) {
SDOperand LHSLo, LHSHi;
GetSplitVector(N->getOperand(0), LHSLo, LHSHi);
SDOperand RHSLo, RHSHi;
@@ -556,7 +542,8 @@
Hi = DAG.getNode(N->getOpcode(), LHSHi.getValueType(), LHSHi, RHSHi);
}
-void DAGTypeLegalizer::SplitRes_UnOp(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
+void DAGTypeLegalizer::SplitVecRes_UnOp(SDNode *N, SDOperand &Lo,
+ SDOperand &Hi) {
// Get the dest types. This doesn't always match input types, e.g. int_to_fp.
MVT LoVT, HiVT;
GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
@@ -566,24 +553,14 @@
Hi = DAG.getNode(N->getOpcode(), HiVT, Hi);
}
-void DAGTypeLegalizer::SplitRes_FPOWI(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
+void DAGTypeLegalizer::SplitVecRes_FPOWI(SDNode *N, SDOperand &Lo,
+ SDOperand &Hi) {
GetSplitVector(N->getOperand(0), Lo, Hi);
Lo = DAG.getNode(ISD::FPOWI, Lo.getValueType(), Lo, N->getOperand(1));
Hi = DAG.getNode(ISD::FPOWI, Lo.getValueType(), Hi, N->getOperand(1));
}
-void DAGTypeLegalizer::SplitRes_SELECT(SDNode *N, SDOperand &Lo, SDOperand &Hi){
- SDOperand LL, LH, RL, RH;
- GetSplitVector(N->getOperand(1), LL, LH);
- GetSplitVector(N->getOperand(2), RL, RH);
-
- SDOperand Cond = N->getOperand(0);
- Lo = DAG.getNode(ISD::SELECT, LL.getValueType(), Cond, LL, RL);
- Hi = DAG.getNode(ISD::SELECT, LH.getValueType(), Cond, LH, RH);
-}
-
-
//===----------------------------------------------------------------------===//
// Operand Vector Splitting
//===----------------------------------------------------------------------===//
@@ -611,14 +588,16 @@
#endif
assert(0 && "Do not know how to split this operator's operand!");
abort();
- case ISD::STORE: Res = SplitOp_STORE(cast<StoreSDNode>(N), OpNo); break;
- case ISD::RET: Res = SplitOp_RET(N, OpNo); break;
+ case ISD::STORE: Res = SplitVecOp_STORE(cast<StoreSDNode>(N), OpNo); break;
+ case ISD::RET: Res = SplitVecOp_RET(N, OpNo); break;
- case ISD::BIT_CONVERT: Res = SplitOp_BIT_CONVERT(N); break;
+ case ISD::BIT_CONVERT: Res = SplitVecOp_BIT_CONVERT(N); break;
- case ISD::EXTRACT_VECTOR_ELT: Res = SplitOp_EXTRACT_VECTOR_ELT(N); break;
- case ISD::EXTRACT_SUBVECTOR: Res = SplitOp_EXTRACT_SUBVECTOR(N); break;
- case ISD::VECTOR_SHUFFLE: Res = SplitOp_VECTOR_SHUFFLE(N, OpNo); break;
+ case ISD::EXTRACT_VECTOR_ELT: Res = SplitVecOp_EXTRACT_VECTOR_ELT(N); break;
+ case ISD::EXTRACT_SUBVECTOR: Res = SplitVecOp_EXTRACT_SUBVECTOR(N); break;
+ case ISD::VECTOR_SHUFFLE:
+ Res = SplitVecOp_VECTOR_SHUFFLE(N, OpNo);
+ break;
}
}
@@ -642,7 +621,7 @@
return false;
}
-SDOperand DAGTypeLegalizer::SplitOp_STORE(StoreSDNode *N, unsigned OpNo) {
+SDOperand DAGTypeLegalizer::SplitVecOp_STORE(StoreSDNode *N, unsigned OpNo) {
// FIXME: Add support for indexed stores.
assert(OpNo == 1 && "Can only split the stored value");
@@ -667,7 +646,7 @@
return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
}
-SDOperand DAGTypeLegalizer::SplitOp_RET(SDNode *N, unsigned OpNo) {
+SDOperand DAGTypeLegalizer::SplitVecOp_RET(SDNode *N, unsigned OpNo) {
assert(N->getNumOperands() == 3 &&"Can only handle ret of one vector so far");
// FIXME: Returns of gcc generic vectors larger than a legal vector
// type should be returned by reference!
@@ -680,7 +659,7 @@
return DAG.getNode(ISD::RET, MVT::Other, Chain, Lo, Sign, Hi, Sign);
}
-SDOperand DAGTypeLegalizer::SplitOp_BIT_CONVERT(SDNode *N) {
+SDOperand DAGTypeLegalizer::SplitVecOp_BIT_CONVERT(SDNode *N) {
// For example, i64 = BIT_CONVERT v4i16 on alpha. Typically the vector will
// end up being split all the way down to individual components. Convert the
// split pieces into integers and reassemble.
@@ -696,7 +675,7 @@
JoinIntegers(Lo, Hi));
}
-SDOperand DAGTypeLegalizer::SplitOp_EXTRACT_VECTOR_ELT(SDNode *N) {
+SDOperand DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(SDNode *N) {
SDOperand Vec = N->getOperand(0);
SDOperand Idx = N->getOperand(1);
MVT VecVT = Vec.getValueType();
@@ -728,7 +707,7 @@
return DAG.getLoad(EltVT, Store, StackPtr, NULL, 0);
}
-SDOperand DAGTypeLegalizer::SplitOp_EXTRACT_SUBVECTOR(SDNode *N) {
+SDOperand DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(SDNode *N) {
// We know that the extracted result type is legal. For now, assume the index
// is a constant.
MVT SubVT = N->getValueType(0);
@@ -749,7 +728,7 @@
}
}
-SDOperand DAGTypeLegalizer::SplitOp_VECTOR_SHUFFLE(SDNode *N, unsigned OpNo) {
+SDOperand DAGTypeLegalizer::SplitVecOp_VECTOR_SHUFFLE(SDNode *N, unsigned OpNo){
assert(OpNo == 2 && "Shuffle source type differs from result type?");
SDOperand Mask = N->getOperand(2);
unsigned MaskLength = Mask.getValueType().getVectorNumElements();
More information about the llvm-commits
mailing list