Some LegalizeTypes code factorization and minor

enhancements.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48215 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Duncan Sands 2008-03-11 06:41:14 +00:00
parent 5d03f21744
commit ac7613a326
5 changed files with 114 additions and 57 deletions

View File

@ -464,19 +464,42 @@ SDOperand DAGTypeLegalizer::HandleMemIntrinsic(SDNode *N) {
return DAG.UpdateNodeOperands(SDOperand(N, 0), Ops, 6); return DAG.UpdateNodeOperands(SDOperand(N, 0), Ops, 6);
} }
/// SplitOp - Return the lower and upper halves of Op's bits in a value type /// JoinIntegers - Build an integer with low bits Lo and high bits Hi.
/// half the size of Op's. SDOperand DAGTypeLegalizer::JoinIntegers(SDOperand Lo, SDOperand Hi) {
void DAGTypeLegalizer::SplitOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi) { MVT::ValueType LVT = Lo.getValueType();
unsigned NVTBits = MVT::getSizeInBits(Op.getValueType())/2; MVT::ValueType HVT = Hi.getValueType();
assert(MVT::getSizeInBits(Op.getValueType()) == 2*NVTBits && MVT::ValueType NVT = MVT::getIntegerType(MVT::getSizeInBits(LVT) +
"Cannot split odd sized integer type"); MVT::getSizeInBits(HVT));
MVT::ValueType NVT = MVT::getIntegerType(NVTBits);
Lo = DAG.getNode(ISD::TRUNCATE, NVT, Op); Lo = DAG.getNode(ISD::ZERO_EXTEND, NVT, Lo);
Hi = DAG.getNode(ISD::SRL, Op.getValueType(), Op, Hi = DAG.getNode(ISD::ANY_EXTEND, NVT, Hi);
DAG.getConstant(NVTBits, TLI.getShiftAmountTy())); Hi = DAG.getNode(ISD::SHL, NVT, Hi, DAG.getConstant(MVT::getSizeInBits(LVT),
Hi = DAG.getNode(ISD::TRUNCATE, NVT, Hi); TLI.getShiftAmountTy()));
return DAG.getNode(ISD::OR, NVT, Lo, Hi);
} }
/// SplitInteger - Return the lower LoVT bits of Op in Lo and the upper HiVT
/// bits in Hi.
void DAGTypeLegalizer::SplitInteger(SDOperand Op,
MVT::ValueType LoVT, MVT::ValueType HiVT,
SDOperand &Lo, SDOperand &Hi) {
assert(MVT::getSizeInBits(LoVT) + MVT::getSizeInBits(HiVT) ==
MVT::getSizeInBits(Op.getValueType()) && "Invalid integer splitting!");
Lo = DAG.getNode(ISD::TRUNCATE, LoVT, Op);
Hi = DAG.getNode(ISD::SRL, Op.getValueType(), Op,
DAG.getConstant(MVT::getSizeInBits(LoVT),
TLI.getShiftAmountTy()));
Hi = DAG.getNode(ISD::TRUNCATE, HiVT, Hi);
}
/// SplitInteger - Return the lower and upper halves of Op's bits in a value type
/// half the size of Op's.
void DAGTypeLegalizer::SplitInteger(SDOperand Op,
SDOperand &Lo, SDOperand &Hi) {
MVT::ValueType HalfVT =
MVT::getIntegerType(MVT::getSizeInBits(Op.getValueType())/2);
SplitInteger(Op, HalfVT, HalfVT, Lo, Hi);
}
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Entry Point // Entry Point

View File

@ -154,7 +154,10 @@ private:
// Common routines. // Common routines.
SDOperand CreateStackStoreLoad(SDOperand Op, MVT::ValueType DestVT); SDOperand CreateStackStoreLoad(SDOperand Op, MVT::ValueType DestVT);
SDOperand HandleMemIntrinsic(SDNode *N); SDOperand HandleMemIntrinsic(SDNode *N);
void SplitOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi); SDOperand JoinIntegers(SDOperand Lo, SDOperand Hi);
void SplitInteger(SDOperand Op, SDOperand &Lo, SDOperand &Hi);
void SplitInteger(SDOperand Op, MVT::ValueType LoVT, MVT::ValueType HiVT,
SDOperand &Lo, SDOperand &Hi);
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
// Promotion Support: LegalizeTypesPromote.cpp // Promotion Support: LegalizeTypesPromote.cpp

View File

@ -157,7 +157,7 @@ void DAGTypeLegalizer::ExpandResult_ANY_EXTEND(SDNode *N,
assert(Res.getValueType() == N->getValueType(0) && assert(Res.getValueType() == N->getValueType(0) &&
"Operand over promoted?"); "Operand over promoted?");
// Split the promoted operand. This will simplify when it is expanded. // Split the promoted operand. This will simplify when it is expanded.
SplitOp(Res, Lo, Hi); SplitInteger(Res, Lo, Hi);
} }
} }
@ -178,7 +178,7 @@ void DAGTypeLegalizer::ExpandResult_ZERO_EXTEND(SDNode *N,
assert(Res.getValueType() == N->getValueType(0) && assert(Res.getValueType() == N->getValueType(0) &&
"Operand over promoted?"); "Operand over promoted?");
// Split the promoted operand. This will simplify when it is expanded. // Split the promoted operand. This will simplify when it is expanded.
SplitOp(Res, Lo, Hi); SplitInteger(Res, Lo, Hi);
unsigned ExcessBits = unsigned ExcessBits =
MVT::getSizeInBits(Op.getValueType()) - MVT::getSizeInBits(NVT); MVT::getSizeInBits(Op.getValueType()) - MVT::getSizeInBits(NVT);
Hi = DAG.getZeroExtendInReg(Hi, MVT::getIntegerType(ExcessBits)); Hi = DAG.getZeroExtendInReg(Hi, MVT::getIntegerType(ExcessBits));
@ -205,7 +205,7 @@ void DAGTypeLegalizer::ExpandResult_SIGN_EXTEND(SDNode *N,
assert(Res.getValueType() == N->getValueType(0) && assert(Res.getValueType() == N->getValueType(0) &&
"Operand over promoted?"); "Operand over promoted?");
// Split the promoted operand. This will simplify when it is expanded. // Split the promoted operand. This will simplify when it is expanded.
SplitOp(Res, Lo, Hi); SplitInteger(Res, Lo, Hi);
unsigned ExcessBits = unsigned ExcessBits =
MVT::getSizeInBits(Op.getValueType()) - MVT::getSizeInBits(NVT); MVT::getSizeInBits(Op.getValueType()) - MVT::getSizeInBits(NVT);
Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, Hi.getValueType(), Hi, Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, Hi.getValueType(), Hi,
@ -243,10 +243,47 @@ void DAGTypeLegalizer::ExpandResult_TRUNCATE(SDNode *N,
void DAGTypeLegalizer::ExpandResult_BIT_CONVERT(SDNode *N, void DAGTypeLegalizer::ExpandResult_BIT_CONVERT(SDNode *N,
SDOperand &Lo, SDOperand &Hi) { SDOperand &Lo, SDOperand &Hi) {
MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0));
SDOperand InOp = N->getOperand(0);
MVT::ValueType InVT = InOp.getValueType();
// Handle some special cases efficiently.
switch (getTypeAction(InVT)) {
default:
assert(false && "Unknown type action!");
case Legal:
case Promote:
break;
case Expand:
// 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.
GetSplitOp(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.
InOp = DAG.getNode(ISD::BIT_CONVERT,
MVT::getIntegerType(MVT::getSizeInBits(InVT)),
GetScalarizedOp(InOp));
SplitInteger(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. // Lower the bit-convert to a store/load from the stack, then expand the load.
// TODO: If the operand also needs expansion then this could be turned into SDOperand Op = CreateStackStoreLoad(InOp, N->getValueType(0));
// conversion of the expanded pieces. But there needs to be a testcase first!
SDOperand Op = CreateStackStoreLoad(N->getOperand(0), N->getValueType(0));
ExpandResult_LOAD(cast<LoadSDNode>(Op.Val), Lo, Hi); ExpandResult_LOAD(cast<LoadSDNode>(Op.Val), Lo, Hi);
} }
@ -694,8 +731,9 @@ void DAGTypeLegalizer::ExpandResult_EXTRACT_VECTOR_ELT(SDNode *N,
SDOperand Idx = N->getOperand(1); SDOperand Idx = N->getOperand(1);
// Make sure the type of Idx is big enough to hold the new values. // Make sure the type of Idx is big enough to hold the new values.
if (MVT::getSizeInBits(Idx.getValueType()) < 32) if (MVT::getSizeInBits(Idx.getValueType()) <
Idx = DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Idx); MVT::getSizeInBits(TLI.getPointerTy()))
Idx = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(), Idx);
Idx = DAG.getNode(ISD::ADD, Idx.getValueType(), Idx, Idx); Idx = DAG.getNode(ISD::ADD, Idx.getValueType(), Idx, Idx);
Lo = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewVT, NewVec, Idx); Lo = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewVT, NewVec, Idx);

View File

@ -209,15 +209,10 @@ SDOperand DAGTypeLegalizer::PromoteResult_LOAD(LoadSDNode *N) {
SDOperand DAGTypeLegalizer::PromoteResult_BUILD_PAIR(SDNode *N) { SDOperand DAGTypeLegalizer::PromoteResult_BUILD_PAIR(SDNode *N) {
// The pair element type may be legal, or may not promote to the same type as // The pair element type may be legal, or may not promote to the same type as
// the result, for example i16 = BUILD_PAIR (i8, i8) when i8 is legal but i16 // the result, for example i14 = BUILD_PAIR (i7, i7). Handle all cases.
// is not. Handle all cases. return DAG.getNode(ISD::ANY_EXTEND,
MVT::ValueType LVT = N->getOperand(0).getValueType(); TLI.getTypeToTransformTo(N->getValueType(0)),
MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0)); JoinIntegers(N->getOperand(0), N->getOperand(1)));
SDOperand Lo = DAG.getNode(ISD::ZERO_EXTEND, NVT, N->getOperand(0));
SDOperand Hi = DAG.getNode(ISD::ANY_EXTEND, NVT, N->getOperand(1));
Hi = DAG.getNode(ISD::SHL, NVT, Hi, DAG.getConstant(MVT::getSizeInBits(LVT),
TLI.getShiftAmountTy()));
return DAG.getNode(ISD::OR, NVT, Lo, Hi);
} }
SDOperand DAGTypeLegalizer::PromoteResult_BIT_CONVERT(SDNode *N) { SDOperand DAGTypeLegalizer::PromoteResult_BIT_CONVERT(SDNode *N) {
@ -262,15 +257,10 @@ SDOperand DAGTypeLegalizer::PromoteResult_BIT_CONVERT(SDNode *N) {
if (TLI.isBigEndian()) if (TLI.isBigEndian())
std::swap(Lo, Hi); std::swap(Lo, Hi);
MVT::ValueType TargetTy = MVT::getIntegerType(MVT::getSizeInBits(OutVT)); InOp = DAG.getNode(ISD::ANY_EXTEND,
Hi = DAG.getNode(ISD::ANY_EXTEND, TargetTy, Hi); MVT::getIntegerType(MVT::getSizeInBits(OutVT)),
Hi = DAG.getNode(ISD::SHL, TargetTy, Hi, JoinIntegers(Lo, Hi));
DAG.getConstant(MVT::getSizeInBits(Lo.getValueType()), return DAG.getNode(ISD::BIT_CONVERT, OutVT, InOp);
TLI.getShiftAmountTy()));
Lo = DAG.getNode(ISD::ZERO_EXTEND, TargetTy, Lo);
return DAG.getNode(ISD::BIT_CONVERT, OutVT,
DAG.getNode(ISD::OR, TargetTy, Lo, Hi));
} }
// Otherwise, lower the bit-convert to a store/load from the stack, then // Otherwise, lower the bit-convert to a store/load from the stack, then
@ -693,7 +683,7 @@ SDOperand DAGTypeLegalizer::PromoteOperand_BUILD_VECTOR(SDNode *N) {
SDOperand Hi = N->getOperand(i+1); SDOperand Hi = N->getOperand(i+1);
if (TLI.isBigEndian()) if (TLI.isBigEndian())
std::swap(Lo, Hi); std::swap(Lo, Hi);
NewElts.push_back(DAG.getNode(ISD::BUILD_PAIR, NewVT, Lo, Hi)); NewElts.push_back(JoinIntegers(Lo, Hi));
} }
SDOperand NewVec = DAG.getNode(ISD::BUILD_VECTOR, SDOperand NewVec = DAG.getNode(ISD::BUILD_VECTOR,

View File

@ -45,7 +45,7 @@ static void GetSplitDestVTs(MVT::ValueType InVT,
/// legalization, we just know that (at least) one result needs vector /// legalization, we just know that (at least) one result needs vector
/// splitting. /// splitting.
void DAGTypeLegalizer::SplitResult(SDNode *N, unsigned ResNo) { void DAGTypeLegalizer::SplitResult(SDNode *N, unsigned ResNo) {
DEBUG(cerr << "Expand node result: "; N->dump(&DAG); cerr << "\n"); DEBUG(cerr << "Split node result: "; N->dump(&DAG); cerr << "\n");
SDOperand Lo, Hi; SDOperand Lo, Hi;
#if 0 #if 0
@ -257,26 +257,20 @@ void DAGTypeLegalizer::SplitRes_BIT_CONVERT(SDNode *N,
SDOperand InOp = N->getOperand(0); SDOperand InOp = N->getOperand(0);
MVT::ValueType InVT = InOp.getValueType(); MVT::ValueType InVT = InOp.getValueType();
MVT::ValueType NewInVT = TLI.getTypeToTransformTo(InVT);
// Handle some special cases efficiently.
switch (getTypeAction(InVT)) { switch (getTypeAction(InVT)) {
default: default:
assert(false && "Unknown type action!"); assert(false && "Unknown type action!");
case Legal: case Legal:
break;
case Promote: case Promote:
break;
case Scalarize: case Scalarize:
// While it is tempting to extract the scalarized operand, check whether it
// needs expansion, and if so process it in the Expand case below, there is
// no guarantee that the scalarized operand has been processed yet. If it
// hasn't then the call to GetExpandedOp will abort. So just give up.
break; break;
case Expand: case Expand:
// A scalar to vector conversion, where the scalar needs expansion. // A scalar to vector conversion, where the scalar needs expansion.
// Check that the vector is being split in two. // If the vector is being split in two then we can just convert the
if (MVT::getSizeInBits(NewInVT) == MVT::getSizeInBits(LoVT)) { // expanded pieces.
// Convert each expanded piece of the scalar now. if (LoVT == HiVT) {
GetExpandedOp(InOp, Lo, Hi); GetExpandedOp(InOp, Lo, Hi);
if (TLI.isBigEndian()) if (TLI.isBigEndian())
std::swap(Lo, Hi); std::swap(Lo, Hi);
@ -294,9 +288,21 @@ void DAGTypeLegalizer::SplitRes_BIT_CONVERT(SDNode *N,
return; return;
} }
// Lower the bit-convert to a store/load from the stack, then split the load. // In the general case, convert the input to an integer and split it by hand.
SDOperand Op = CreateStackStoreLoad(InOp, N->getValueType(0)); InVT = MVT::getIntegerType(MVT::getSizeInBits(InVT));
SplitRes_LOAD(cast<LoadSDNode>(Op.Val), Lo, Hi); InOp = DAG.getNode(ISD::BIT_CONVERT, InVT, InOp);
MVT::ValueType LoIntVT = MVT::getIntegerType(MVT::getSizeInBits(LoVT));
MVT::ValueType HiIntVT = MVT::getIntegerType(MVT::getSizeInBits(HiVT));
if (TLI.isBigEndian())
std::swap(LoIntVT, HiIntVT);
SplitInteger(InOp, LoIntVT, HiIntVT, Lo, Hi);
if (TLI.isBigEndian())
std::swap(Lo, Hi);
Lo = DAG.getNode(ISD::BIT_CONVERT, LoVT, Lo);
Hi = DAG.getNode(ISD::BIT_CONVERT, HiVT, Hi);
} }
void DAGTypeLegalizer::SplitRes_BinOp(SDNode *N, SDOperand &Lo, SDOperand &Hi) { void DAGTypeLegalizer::SplitRes_BinOp(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
@ -448,11 +454,8 @@ SDOperand DAGTypeLegalizer::SplitOp_BIT_CONVERT(SDNode *N) {
if (TLI.isBigEndian()) if (TLI.isBigEndian())
std::swap(Lo, Hi); std::swap(Lo, Hi);
assert(LoBits == HiBits && "Do not know how to assemble odd sized vectors!");
return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0), return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0),
DAG.getNode(ISD::BUILD_PAIR, JoinIntegers(Lo, Hi));
MVT::getIntegerType(LoBits+HiBits), Lo, Hi));
} }
SDOperand DAGTypeLegalizer::SplitOp_EXTRACT_VECTOR_ELT(SDNode *N) { SDOperand DAGTypeLegalizer::SplitOp_EXTRACT_VECTOR_ELT(SDNode *N) {