forked from OSchip/llvm-project
Some LegalizeTypes code factorization and minor
enhancements. llvm-svn: 48215
This commit is contained in:
parent
819e9b6f39
commit
b29f93613d
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue