split the vector case of getCopyFromParts out to its own function,

no functionality change.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@111994 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2010-08-24 23:20:40 +00:00
parent 365c53e328
commit 3ac1884509

View File

@ -70,22 +70,29 @@ LimitFPPrecision("limit-float-precision",
cl::location(LimitFloatPrecision), cl::location(LimitFloatPrecision),
cl::init(0)); cl::init(0));
static SDValue getCopyFromPartsVector(SelectionDAG &DAG, DebugLoc DL,
const SDValue *Parts, unsigned NumParts,
EVT PartVT, EVT ValueVT);
/// getCopyFromParts - Create a value that contains the specified legal parts /// getCopyFromParts - Create a value that contains the specified legal parts
/// combined into the value they represent. If the parts combine to a type /// combined into the value they represent. If the parts combine to a type
/// larger then ValueVT then AssertOp can be used to specify whether the extra /// larger then ValueVT then AssertOp can be used to specify whether the extra
/// bits are known to be zero (ISD::AssertZext) or sign extended from ValueVT /// bits are known to be zero (ISD::AssertZext) or sign extended from ValueVT
/// (ISD::AssertSext). /// (ISD::AssertSext).
static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc dl, static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc DL,
const SDValue *Parts, const SDValue *Parts,
unsigned NumParts, EVT PartVT, EVT ValueVT, unsigned NumParts, EVT PartVT, EVT ValueVT,
ISD::NodeType AssertOp = ISD::DELETED_NODE) { ISD::NodeType AssertOp = ISD::DELETED_NODE) {
if (ValueVT.isVector())
return getCopyFromPartsVector(DAG, DL, Parts, NumParts, PartVT, ValueVT);
assert(NumParts > 0 && "No parts to assemble!"); assert(NumParts > 0 && "No parts to assemble!");
const TargetLowering &TLI = DAG.getTargetLoweringInfo(); const TargetLowering &TLI = DAG.getTargetLoweringInfo();
SDValue Val = Parts[0]; SDValue Val = Parts[0];
if (NumParts > 1) { if (NumParts > 1) {
// Assemble the value from multiple parts. // Assemble the value from multiple parts.
if (!ValueVT.isVector() && ValueVT.isInteger()) { if (ValueVT.isInteger()) {
unsigned PartBits = PartVT.getSizeInBits(); unsigned PartBits = PartVT.getSizeInBits();
unsigned ValueBits = ValueVT.getSizeInBits(); unsigned ValueBits = ValueVT.getSizeInBits();
@ -100,25 +107,25 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc dl,
EVT HalfVT = EVT::getIntegerVT(*DAG.getContext(), RoundBits/2); EVT HalfVT = EVT::getIntegerVT(*DAG.getContext(), RoundBits/2);
if (RoundParts > 2) { if (RoundParts > 2) {
Lo = getCopyFromParts(DAG, dl, Parts, RoundParts / 2, Lo = getCopyFromParts(DAG, DL, Parts, RoundParts / 2,
PartVT, HalfVT); PartVT, HalfVT);
Hi = getCopyFromParts(DAG, dl, Parts + RoundParts / 2, Hi = getCopyFromParts(DAG, DL, Parts + RoundParts / 2,
RoundParts / 2, PartVT, HalfVT); RoundParts / 2, PartVT, HalfVT);
} else { } else {
Lo = DAG.getNode(ISD::BIT_CONVERT, dl, HalfVT, Parts[0]); Lo = DAG.getNode(ISD::BIT_CONVERT, DL, HalfVT, Parts[0]);
Hi = DAG.getNode(ISD::BIT_CONVERT, dl, HalfVT, Parts[1]); Hi = DAG.getNode(ISD::BIT_CONVERT, DL, HalfVT, Parts[1]);
} }
if (TLI.isBigEndian()) if (TLI.isBigEndian())
std::swap(Lo, Hi); std::swap(Lo, Hi);
Val = DAG.getNode(ISD::BUILD_PAIR, dl, RoundVT, Lo, Hi); Val = DAG.getNode(ISD::BUILD_PAIR, DL, RoundVT, Lo, Hi);
if (RoundParts < NumParts) { if (RoundParts < NumParts) {
// Assemble the trailing non-power-of-2 part. // Assemble the trailing non-power-of-2 part.
unsigned OddParts = NumParts - RoundParts; unsigned OddParts = NumParts - RoundParts;
EVT OddVT = EVT::getIntegerVT(*DAG.getContext(), OddParts * PartBits); EVT OddVT = EVT::getIntegerVT(*DAG.getContext(), OddParts * PartBits);
Hi = getCopyFromParts(DAG, dl, Hi = getCopyFromParts(DAG, DL,
Parts + RoundParts, OddParts, PartVT, OddVT); Parts + RoundParts, OddParts, PartVT, OddVT);
// Combine the round and odd parts. // Combine the round and odd parts.
@ -126,68 +133,29 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc dl,
if (TLI.isBigEndian()) if (TLI.isBigEndian())
std::swap(Lo, Hi); std::swap(Lo, Hi);
EVT TotalVT = EVT::getIntegerVT(*DAG.getContext(), NumParts * PartBits); EVT TotalVT = EVT::getIntegerVT(*DAG.getContext(), NumParts * PartBits);
Hi = DAG.getNode(ISD::ANY_EXTEND, dl, TotalVT, Hi); Hi = DAG.getNode(ISD::ANY_EXTEND, DL, TotalVT, Hi);
Hi = DAG.getNode(ISD::SHL, dl, TotalVT, Hi, Hi = DAG.getNode(ISD::SHL, DL, TotalVT, Hi,
DAG.getConstant(Lo.getValueType().getSizeInBits(), DAG.getConstant(Lo.getValueType().getSizeInBits(),
TLI.getPointerTy())); TLI.getPointerTy()));
Lo = DAG.getNode(ISD::ZERO_EXTEND, dl, TotalVT, Lo); Lo = DAG.getNode(ISD::ZERO_EXTEND, DL, TotalVT, Lo);
Val = DAG.getNode(ISD::OR, dl, TotalVT, Lo, Hi); Val = DAG.getNode(ISD::OR, DL, TotalVT, Lo, Hi);
} }
} else if (ValueVT.isVector()) {
// Handle a multi-element vector.
EVT IntermediateVT, RegisterVT;
unsigned NumIntermediates;
unsigned NumRegs =
TLI.getVectorTypeBreakdown(*DAG.getContext(), ValueVT, IntermediateVT,
NumIntermediates, RegisterVT);
assert(NumRegs == NumParts
&& "Part count doesn't match vector breakdown!");
NumParts = NumRegs; // Silence a compiler warning.
assert(RegisterVT == PartVT
&& "Part type doesn't match vector breakdown!");
assert(RegisterVT == Parts[0].getValueType() &&
"Part type doesn't match part!");
// Assemble the parts into intermediate operands.
SmallVector<SDValue, 8> Ops(NumIntermediates);
if (NumIntermediates == NumParts) {
// If the register was not expanded, truncate or copy the value,
// as appropriate.
for (unsigned i = 0; i != NumParts; ++i)
Ops[i] = getCopyFromParts(DAG, dl, &Parts[i], 1,
PartVT, IntermediateVT);
} else if (NumParts > 0) {
// If the intermediate type was expanded, build the intermediate
// operands from the parts.
assert(NumParts % NumIntermediates == 0 &&
"Must expand into a divisible number of parts!");
unsigned Factor = NumParts / NumIntermediates;
for (unsigned i = 0; i != NumIntermediates; ++i)
Ops[i] = getCopyFromParts(DAG, dl, &Parts[i * Factor], Factor,
PartVT, IntermediateVT);
}
// Build a vector with BUILD_VECTOR or CONCAT_VECTORS from the
// intermediate operands.
Val = DAG.getNode(IntermediateVT.isVector() ?
ISD::CONCAT_VECTORS : ISD::BUILD_VECTOR, dl,
ValueVT, &Ops[0], NumIntermediates);
} else if (PartVT.isFloatingPoint()) { } else if (PartVT.isFloatingPoint()) {
// FP split into multiple FP parts (for ppcf128) // FP split into multiple FP parts (for ppcf128)
assert(ValueVT == EVT(MVT::ppcf128) && PartVT == EVT(MVT::f64) && assert(ValueVT == EVT(MVT::ppcf128) && PartVT == EVT(MVT::f64) &&
"Unexpected split"); "Unexpected split");
SDValue Lo, Hi; SDValue Lo, Hi;
Lo = DAG.getNode(ISD::BIT_CONVERT, dl, EVT(MVT::f64), Parts[0]); Lo = DAG.getNode(ISD::BIT_CONVERT, DL, EVT(MVT::f64), Parts[0]);
Hi = DAG.getNode(ISD::BIT_CONVERT, dl, EVT(MVT::f64), Parts[1]); Hi = DAG.getNode(ISD::BIT_CONVERT, DL, EVT(MVT::f64), Parts[1]);
if (TLI.isBigEndian()) if (TLI.isBigEndian())
std::swap(Lo, Hi); std::swap(Lo, Hi);
Val = DAG.getNode(ISD::BUILD_PAIR, dl, ValueVT, Lo, Hi); Val = DAG.getNode(ISD::BUILD_PAIR, DL, ValueVT, Lo, Hi);
} else { } else {
// FP split into integer parts (soft fp) // FP split into integer parts (soft fp)
assert(ValueVT.isFloatingPoint() && PartVT.isInteger() && assert(ValueVT.isFloatingPoint() && PartVT.isInteger() &&
!PartVT.isVector() && "Unexpected split"); !PartVT.isVector() && "Unexpected split");
EVT IntVT = EVT::getIntegerVT(*DAG.getContext(), ValueVT.getSizeInBits()); EVT IntVT = EVT::getIntegerVT(*DAG.getContext(), ValueVT.getSizeInBits());
Val = getCopyFromParts(DAG, dl, Parts, NumParts, PartVT, IntVT); Val = getCopyFromParts(DAG, DL, Parts, NumParts, PartVT, IntVT);
} }
} }
@ -197,50 +165,104 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc dl,
if (PartVT == ValueVT) if (PartVT == ValueVT)
return Val; return Val;
if (PartVT.isVector()) { if (PartVT.isInteger() && ValueVT.isInteger()) {
assert(ValueVT.isVector() && "Unknown vector conversion!");
return DAG.getNode(ISD::BIT_CONVERT, dl, ValueVT, Val);
}
if (ValueVT.isVector()) {
assert(ValueVT.getVectorElementType() == PartVT &&
ValueVT.getVectorNumElements() == 1 &&
"Only trivial scalar-to-vector conversions should get here!");
return DAG.getNode(ISD::BUILD_VECTOR, dl, ValueVT, Val);
}
if (PartVT.isInteger() &&
ValueVT.isInteger()) {
if (ValueVT.bitsLT(PartVT)) { if (ValueVT.bitsLT(PartVT)) {
// For a truncate, see if we have any information to // For a truncate, see if we have any information to
// indicate whether the truncated bits will always be // indicate whether the truncated bits will always be
// zero or sign-extension. // zero or sign-extension.
if (AssertOp != ISD::DELETED_NODE) if (AssertOp != ISD::DELETED_NODE)
Val = DAG.getNode(AssertOp, dl, PartVT, Val, Val = DAG.getNode(AssertOp, DL, PartVT, Val,
DAG.getValueType(ValueVT)); DAG.getValueType(ValueVT));
return DAG.getNode(ISD::TRUNCATE, dl, ValueVT, Val); return DAG.getNode(ISD::TRUNCATE, DL, ValueVT, Val);
} else {
return DAG.getNode(ISD::ANY_EXTEND, dl, ValueVT, Val);
} }
return DAG.getNode(ISD::ANY_EXTEND, DL, ValueVT, Val);
} }
if (PartVT.isFloatingPoint() && ValueVT.isFloatingPoint()) { if (PartVT.isFloatingPoint() && ValueVT.isFloatingPoint()) {
if (ValueVT.bitsLT(Val.getValueType())) { // FP_ROUND's are always exact here.
// FP_ROUND's are always exact here. if (ValueVT.bitsLT(Val.getValueType()))
return DAG.getNode(ISD::FP_ROUND, dl, ValueVT, Val, return DAG.getNode(ISD::FP_ROUND, DL, ValueVT, Val,
DAG.getIntPtrConstant(1)); DAG.getIntPtrConstant(1));
}
return DAG.getNode(ISD::FP_EXTEND, dl, ValueVT, Val); return DAG.getNode(ISD::FP_EXTEND, DL, ValueVT, Val);
} }
if (PartVT.getSizeInBits() == ValueVT.getSizeInBits()) if (PartVT.getSizeInBits() == ValueVT.getSizeInBits())
return DAG.getNode(ISD::BIT_CONVERT, dl, ValueVT, Val); return DAG.getNode(ISD::BIT_CONVERT, DL, ValueVT, Val);
llvm_unreachable("Unknown mismatch!"); llvm_unreachable("Unknown mismatch!");
return SDValue(); return SDValue();
} }
/// getCopyFromParts - Create a value that contains the specified legal parts
/// combined into the value they represent. If the parts combine to a type
/// larger then ValueVT then AssertOp can be used to specify whether the extra
/// bits are known to be zero (ISD::AssertZext) or sign extended from ValueVT
/// (ISD::AssertSext).
static SDValue getCopyFromPartsVector(SelectionDAG &DAG, DebugLoc DL,
const SDValue *Parts, unsigned NumParts,
EVT PartVT, EVT ValueVT) {
assert(ValueVT.isVector() && "Not a vector value");
assert(NumParts > 0 && "No parts to assemble!");
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
SDValue Val = Parts[0];
// Handle a multi-element vector.
if (NumParts > 1) {
EVT IntermediateVT, RegisterVT;
unsigned NumIntermediates;
unsigned NumRegs =
TLI.getVectorTypeBreakdown(*DAG.getContext(), ValueVT, IntermediateVT,
NumIntermediates, RegisterVT);
assert(NumRegs == NumParts && "Part count doesn't match vector breakdown!");
NumParts = NumRegs; // Silence a compiler warning.
assert(RegisterVT == PartVT && "Part type doesn't match vector breakdown!");
assert(RegisterVT == Parts[0].getValueType() &&
"Part type doesn't match part!");
// Assemble the parts into intermediate operands.
SmallVector<SDValue, 8> Ops(NumIntermediates);
if (NumIntermediates == NumParts) {
// If the register was not expanded, truncate or copy the value,
// as appropriate.
for (unsigned i = 0; i != NumParts; ++i)
Ops[i] = getCopyFromParts(DAG, DL, &Parts[i], 1,
PartVT, IntermediateVT);
} else if (NumParts > 0) {
// If the intermediate type was expanded, build the intermediate
// operands from the parts.
assert(NumParts % NumIntermediates == 0 &&
"Must expand into a divisible number of parts!");
unsigned Factor = NumParts / NumIntermediates;
for (unsigned i = 0; i != NumIntermediates; ++i)
Ops[i] = getCopyFromParts(DAG, DL, &Parts[i * Factor], Factor,
PartVT, IntermediateVT);
}
// Build a vector with BUILD_VECTOR or CONCAT_VECTORS from the
// intermediate operands.
Val = DAG.getNode(IntermediateVT.isVector() ?
ISD::CONCAT_VECTORS : ISD::BUILD_VECTOR, DL,
ValueVT, &Ops[0], NumIntermediates);
}
// There is now one part, held in Val. Correct it to match ValueVT.
PartVT = Val.getValueType();
if (PartVT == ValueVT)
return Val;
if (PartVT.isVector()) // Vector/Vector bitcast.
return DAG.getNode(ISD::BIT_CONVERT, DL, ValueVT, Val);
assert(ValueVT.getVectorElementType() == PartVT &&
ValueVT.getVectorNumElements() == 1 &&
"Only trivial scalar-to-vector conversions should get here!");
return DAG.getNode(ISD::BUILD_VECTOR, DL, ValueVT, Val);
}
static void getCopyToPartsVector(SelectionDAG &DAG, DebugLoc dl, static void getCopyToPartsVector(SelectionDAG &DAG, DebugLoc dl,
SDValue Val, SDValue *Parts, unsigned NumParts, SDValue Val, SDValue *Parts, unsigned NumParts,
@ -636,8 +658,7 @@ void RegsForValue::getCopyToRegs(SDValue Val, SelectionDAG &DAG, DebugLoc dl,
unsigned NumParts = TLI.getNumRegisters(*DAG.getContext(), ValueVT); unsigned NumParts = TLI.getNumRegisters(*DAG.getContext(), ValueVT);
EVT RegisterVT = RegVTs[Value]; EVT RegisterVT = RegVTs[Value];
getCopyToParts(DAG, dl, getCopyToParts(DAG, dl, Val.getValue(Val.getResNo() + Value),
Val.getValue(Val.getResNo() + Value),
&Parts[Part], NumParts, RegisterVT); &Parts[Part], NumParts, RegisterVT);
Part += NumParts; Part += NumParts;
} }