mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-18 09:27:27 +00:00
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:
parent
365c53e328
commit
3ac1884509
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user