Some LegalizeTypes code factorization and minor

enhancements.

llvm-svn: 48215
This commit is contained in:
Duncan Sands 2008-03-11 06:41:14 +00:00
parent 819e9b6f39
commit b29f93613d
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);
}
/// SplitOp - Return the lower and upper halves of Op's bits in a value type
/// half the size of Op's.
void DAGTypeLegalizer::SplitOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi) {
unsigned NVTBits = MVT::getSizeInBits(Op.getValueType())/2;
assert(MVT::getSizeInBits(Op.getValueType()) == 2*NVTBits &&
"Cannot split odd sized integer type");
MVT::ValueType NVT = MVT::getIntegerType(NVTBits);
Lo = DAG.getNode(ISD::TRUNCATE, NVT, Op);
Hi = DAG.getNode(ISD::SRL, Op.getValueType(), Op,
DAG.getConstant(NVTBits, TLI.getShiftAmountTy()));
Hi = DAG.getNode(ISD::TRUNCATE, NVT, Hi);
/// JoinIntegers - Build an integer with low bits Lo and high bits Hi.
SDOperand DAGTypeLegalizer::JoinIntegers(SDOperand Lo, SDOperand Hi) {
MVT::ValueType LVT = Lo.getValueType();
MVT::ValueType HVT = Hi.getValueType();
MVT::ValueType NVT = MVT::getIntegerType(MVT::getSizeInBits(LVT) +
MVT::getSizeInBits(HVT));
Lo = DAG.getNode(ISD::ZERO_EXTEND, NVT, Lo);
Hi = DAG.getNode(ISD::ANY_EXTEND, NVT, Hi);
Hi = DAG.getNode(ISD::SHL, NVT, Hi, DAG.getConstant(MVT::getSizeInBits(LVT),
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

View File

@ -154,7 +154,10 @@ private:
// Common routines.
SDOperand CreateStackStoreLoad(SDOperand Op, MVT::ValueType DestVT);
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

View File

@ -157,7 +157,7 @@ void DAGTypeLegalizer::ExpandResult_ANY_EXTEND(SDNode *N,
assert(Res.getValueType() == N->getValueType(0) &&
"Operand over promoted?");
// 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) &&
"Operand over promoted?");
// Split the promoted operand. This will simplify when it is expanded.
SplitOp(Res, Lo, Hi);
SplitInteger(Res, Lo, Hi);
unsigned ExcessBits =
MVT::getSizeInBits(Op.getValueType()) - MVT::getSizeInBits(NVT);
Hi = DAG.getZeroExtendInReg(Hi, MVT::getIntegerType(ExcessBits));
@ -205,7 +205,7 @@ void DAGTypeLegalizer::ExpandResult_SIGN_EXTEND(SDNode *N,
assert(Res.getValueType() == N->getValueType(0) &&
"Operand over promoted?");
// Split the promoted operand. This will simplify when it is expanded.
SplitOp(Res, Lo, Hi);
SplitInteger(Res, Lo, Hi);
unsigned ExcessBits =
MVT::getSizeInBits(Op.getValueType()) - MVT::getSizeInBits(NVT);
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,
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.
// TODO: If the operand also needs expansion then this could be turned into
// conversion of the expanded pieces. But there needs to be a testcase first!
SDOperand Op = CreateStackStoreLoad(N->getOperand(0), N->getValueType(0));
SDOperand Op = CreateStackStoreLoad(InOp, N->getValueType(0));
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);
// Make sure the type of Idx is big enough to hold the new values.
if (MVT::getSizeInBits(Idx.getValueType()) < 32)
Idx = DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Idx);
if (MVT::getSizeInBits(Idx.getValueType()) <
MVT::getSizeInBits(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);

View File

@ -209,15 +209,10 @@ SDOperand DAGTypeLegalizer::PromoteResult_LOAD(LoadSDNode *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 result, for example i16 = BUILD_PAIR (i8, i8) when i8 is legal but i16
// is not. Handle all cases.
MVT::ValueType LVT = N->getOperand(0).getValueType();
MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0));
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);
// the result, for example i14 = BUILD_PAIR (i7, i7). Handle all cases.
return DAG.getNode(ISD::ANY_EXTEND,
TLI.getTypeToTransformTo(N->getValueType(0)),
JoinIntegers(N->getOperand(0), N->getOperand(1)));
}
SDOperand DAGTypeLegalizer::PromoteResult_BIT_CONVERT(SDNode *N) {
@ -262,15 +257,10 @@ SDOperand DAGTypeLegalizer::PromoteResult_BIT_CONVERT(SDNode *N) {
if (TLI.isBigEndian())
std::swap(Lo, Hi);
MVT::ValueType TargetTy = MVT::getIntegerType(MVT::getSizeInBits(OutVT));
Hi = DAG.getNode(ISD::ANY_EXTEND, TargetTy, Hi);
Hi = DAG.getNode(ISD::SHL, TargetTy, Hi,
DAG.getConstant(MVT::getSizeInBits(Lo.getValueType()),
TLI.getShiftAmountTy()));
Lo = DAG.getNode(ISD::ZERO_EXTEND, TargetTy, Lo);
return DAG.getNode(ISD::BIT_CONVERT, OutVT,
DAG.getNode(ISD::OR, TargetTy, Lo, Hi));
InOp = DAG.getNode(ISD::ANY_EXTEND,
MVT::getIntegerType(MVT::getSizeInBits(OutVT)),
JoinIntegers(Lo, Hi));
return DAG.getNode(ISD::BIT_CONVERT, OutVT, InOp);
}
// 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);
if (TLI.isBigEndian())
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,

View File

@ -45,7 +45,7 @@ static void GetSplitDestVTs(MVT::ValueType InVT,
/// legalization, we just know that (at least) one result needs vector
/// splitting.
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;
#if 0
@ -257,26 +257,20 @@ void DAGTypeLegalizer::SplitRes_BIT_CONVERT(SDNode *N,
SDOperand InOp = N->getOperand(0);
MVT::ValueType InVT = InOp.getValueType();
MVT::ValueType NewInVT = TLI.getTypeToTransformTo(InVT);
// Handle some special cases efficiently.
switch (getTypeAction(InVT)) {
default:
assert(false && "Unknown type action!");
case Legal:
break;
case Promote:
break;
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;
case Expand:
// A scalar to vector conversion, where the scalar needs expansion.
// Check that the vector is being split in two.
if (MVT::getSizeInBits(NewInVT) == MVT::getSizeInBits(LoVT)) {
// Convert each expanded piece of the scalar now.
// If the vector is being split in two then we can just convert the
// expanded pieces.
if (LoVT == HiVT) {
GetExpandedOp(InOp, Lo, Hi);
if (TLI.isBigEndian())
std::swap(Lo, Hi);
@ -294,9 +288,21 @@ void DAGTypeLegalizer::SplitRes_BIT_CONVERT(SDNode *N,
return;
}
// Lower the bit-convert to a store/load from the stack, then split the load.
SDOperand Op = CreateStackStoreLoad(InOp, N->getValueType(0));
SplitRes_LOAD(cast<LoadSDNode>(Op.Val), Lo, Hi);
// In the general case, convert the input to an integer and split it by hand.
InVT = MVT::getIntegerType(MVT::getSizeInBits(InVT));
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) {
@ -448,11 +454,8 @@ SDOperand DAGTypeLegalizer::SplitOp_BIT_CONVERT(SDNode *N) {
if (TLI.isBigEndian())
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),
DAG.getNode(ISD::BUILD_PAIR,
MVT::getIntegerType(LoBits+HiBits), Lo, Hi));
JoinIntegers(Lo, Hi));
}
SDOperand DAGTypeLegalizer::SplitOp_EXTRACT_VECTOR_ELT(SDNode *N) {