mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-30 15:10:33 +00:00
[PowerPC] Improvements for BUILD_VECTOR Vol. 2
This patch corresponds to review: https://reviews.llvm.org/D26023 This patch adds support for converting a vector of loads into a single load if the loads are consecutive (in either direction). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@288219 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
17f24fa4e1
commit
502534bc2a
@ -10750,6 +10750,93 @@ combineElementTruncationToVectorTruncation(SDNode *N,
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
/// \brief Reduce the number of loads when building a vector.
|
||||
///
|
||||
/// Building a vector out of multiple loads can be converted to a load
|
||||
/// of the vector type if the loads are consecutive. If the loads are
|
||||
/// consecutive but in descending order, a shuffle is added at the end
|
||||
/// to reorder the vector.
|
||||
static SDValue combineBVOfConsecutiveLoads(SDNode *N, SelectionDAG &DAG) {
|
||||
assert(N->getOpcode() == ISD::BUILD_VECTOR &&
|
||||
"Should be called with a BUILD_VECTOR node");
|
||||
|
||||
SDLoc dl(N);
|
||||
bool InputsAreConsecutiveLoads = true;
|
||||
bool InputsAreReverseConsecutive = true;
|
||||
unsigned ElemSize = N->getValueType(0).getScalarSizeInBits() / 8;
|
||||
SDValue FirstInput = N->getOperand(0);
|
||||
bool IsRoundOfExtLoad = false;
|
||||
|
||||
if (FirstInput.getOpcode() == ISD::FP_ROUND &&
|
||||
FirstInput.getOperand(0).getOpcode() == ISD::LOAD) {
|
||||
LoadSDNode *LD = dyn_cast<LoadSDNode>(FirstInput.getOperand(0));
|
||||
IsRoundOfExtLoad = LD->getExtensionType() == ISD::EXTLOAD;
|
||||
}
|
||||
// Not a build vector of (possibly fp_rounded) loads.
|
||||
if (!IsRoundOfExtLoad && FirstInput.getOpcode() != ISD::LOAD)
|
||||
return SDValue();
|
||||
|
||||
for (int i = 1, e = N->getNumOperands(); i < e; ++i) {
|
||||
// If any inputs are fp_round(extload), they all must be.
|
||||
if (IsRoundOfExtLoad && N->getOperand(i).getOpcode() != ISD::FP_ROUND)
|
||||
return SDValue();
|
||||
|
||||
SDValue NextInput = IsRoundOfExtLoad ? N->getOperand(i).getOperand(0) :
|
||||
N->getOperand(i);
|
||||
if (NextInput.getOpcode() != ISD::LOAD)
|
||||
return SDValue();
|
||||
|
||||
SDValue PreviousInput =
|
||||
IsRoundOfExtLoad ? N->getOperand(i-1).getOperand(0) : N->getOperand(i-1);
|
||||
LoadSDNode *LD1 = dyn_cast<LoadSDNode>(PreviousInput);
|
||||
LoadSDNode *LD2 = dyn_cast<LoadSDNode>(NextInput);
|
||||
|
||||
// If any inputs are fp_round(extload), they all must be.
|
||||
if (IsRoundOfExtLoad && LD2->getExtensionType() != ISD::EXTLOAD)
|
||||
return SDValue();
|
||||
|
||||
if (!isConsecutiveLS(LD2, LD1, ElemSize, 1, DAG))
|
||||
InputsAreConsecutiveLoads = false;
|
||||
if (!isConsecutiveLS(LD1, LD2, ElemSize, 1, DAG))
|
||||
InputsAreReverseConsecutive = false;
|
||||
|
||||
// Exit early if the loads are neither consecutive nor reverse consecutive.
|
||||
if (!InputsAreConsecutiveLoads && !InputsAreReverseConsecutive)
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
assert(!(InputsAreConsecutiveLoads && InputsAreReverseConsecutive) &&
|
||||
"The loads cannot be both consecutive and reverse consecutive.");
|
||||
|
||||
SDValue FirstLoadOp =
|
||||
IsRoundOfExtLoad ? FirstInput.getOperand(0) : FirstInput;
|
||||
SDValue LastLoadOp =
|
||||
IsRoundOfExtLoad ? N->getOperand(N->getNumOperands()-1).getOperand(0) :
|
||||
N->getOperand(N->getNumOperands()-1);
|
||||
|
||||
LoadSDNode *LD1 = dyn_cast<LoadSDNode>(FirstLoadOp);
|
||||
LoadSDNode *LDL = dyn_cast<LoadSDNode>(LastLoadOp);
|
||||
if (InputsAreConsecutiveLoads) {
|
||||
assert(LD1 && "Input needs to be a LoadSDNode.");
|
||||
return DAG.getLoad(N->getValueType(0), dl, LD1->getChain(),
|
||||
LD1->getBasePtr(), LD1->getPointerInfo(),
|
||||
LD1->getAlignment());
|
||||
}
|
||||
if (InputsAreReverseConsecutive) {
|
||||
assert(LDL && "Input needs to be a LoadSDNode.");
|
||||
SDValue Load = DAG.getLoad(N->getValueType(0), dl, LDL->getChain(),
|
||||
LDL->getBasePtr(), LDL->getPointerInfo(),
|
||||
LDL->getAlignment());
|
||||
SmallVector<int, 16> Ops;
|
||||
for (int i = N->getNumOperands() - 1; i >= 0; i--)
|
||||
Ops.push_back(i);
|
||||
|
||||
return DAG.getVectorShuffle(N->getValueType(0), dl, Load,
|
||||
DAG.getUNDEF(N->getValueType(0)), Ops);
|
||||
}
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
SDValue PPCTargetLowering::DAGCombineBuildVector(SDNode *N,
|
||||
DAGCombinerInfo &DCI) const {
|
||||
assert(N->getOpcode() == ISD::BUILD_VECTOR &&
|
||||
@ -10770,21 +10857,28 @@ SDValue PPCTargetLowering::DAGCombineBuildVector(SDNode *N,
|
||||
if (Reduced)
|
||||
return Reduced;
|
||||
}
|
||||
|
||||
// If we're building a vector out of consecutive loads, just load that
|
||||
// vector type.
|
||||
SDValue Reduced = combineBVOfConsecutiveLoads(N, DAG);
|
||||
if (Reduced)
|
||||
return Reduced;
|
||||
|
||||
if (N->getValueType(0) != MVT::v2f64)
|
||||
return SDValue();
|
||||
|
||||
// Looking for:
|
||||
// (build_vector ([su]int_to_fp (extractelt 0)), [su]int_to_fp (extractelt 1))
|
||||
if (N->getOperand(0).getOpcode() != ISD::SINT_TO_FP &&
|
||||
N->getOperand(0).getOpcode() != ISD::UINT_TO_FP)
|
||||
if (FirstInput.getOpcode() != ISD::SINT_TO_FP &&
|
||||
FirstInput.getOpcode() != ISD::UINT_TO_FP)
|
||||
return SDValue();
|
||||
if (N->getOperand(1).getOpcode() != ISD::SINT_TO_FP &&
|
||||
N->getOperand(1).getOpcode() != ISD::UINT_TO_FP)
|
||||
return SDValue();
|
||||
if (N->getOperand(0).getOpcode() != N->getOperand(1).getOpcode())
|
||||
if (FirstInput.getOpcode() != N->getOperand(1).getOpcode())
|
||||
return SDValue();
|
||||
|
||||
SDValue Ext1 = N->getOperand(0).getOperand(0);
|
||||
SDValue Ext1 = FirstInput.getOperand(0);
|
||||
SDValue Ext2 = N->getOperand(1).getOperand(0);
|
||||
if(Ext1.getOpcode() != ISD::EXTRACT_VECTOR_ELT ||
|
||||
Ext2.getOpcode() != ISD::EXTRACT_VECTOR_ELT)
|
||||
|
Loading…
Reference in New Issue
Block a user