mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-05 14:34:55 +00:00
[ARM] Move the store combiner function down. NFC.
And flip its final condition. In preparation for a future patch. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@223833 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
a31421e2dc
commit
a1aa4d3b36
@ -8648,147 +8648,6 @@ static SDValue PerformVMOVDRRCombine(SDNode *N, SelectionDAG &DAG) {
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
/// PerformSTORECombine - Target-specific dag combine xforms for
|
||||
/// ISD::STORE.
|
||||
static SDValue PerformSTORECombine(SDNode *N,
|
||||
TargetLowering::DAGCombinerInfo &DCI) {
|
||||
StoreSDNode *St = cast<StoreSDNode>(N);
|
||||
if (St->isVolatile())
|
||||
return SDValue();
|
||||
|
||||
// Optimize trunc store (of multiple scalars) to shuffle and store. First,
|
||||
// pack all of the elements in one place. Next, store to memory in fewer
|
||||
// chunks.
|
||||
SDValue StVal = St->getValue();
|
||||
EVT VT = StVal.getValueType();
|
||||
if (St->isTruncatingStore() && VT.isVector()) {
|
||||
SelectionDAG &DAG = DCI.DAG;
|
||||
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
|
||||
EVT StVT = St->getMemoryVT();
|
||||
unsigned NumElems = VT.getVectorNumElements();
|
||||
assert(StVT != VT && "Cannot truncate to the same type");
|
||||
unsigned FromEltSz = VT.getVectorElementType().getSizeInBits();
|
||||
unsigned ToEltSz = StVT.getVectorElementType().getSizeInBits();
|
||||
|
||||
// From, To sizes and ElemCount must be pow of two
|
||||
if (!isPowerOf2_32(NumElems * FromEltSz * ToEltSz)) return SDValue();
|
||||
|
||||
// We are going to use the original vector elt for storing.
|
||||
// Accumulated smaller vector elements must be a multiple of the store size.
|
||||
if (0 != (NumElems * FromEltSz) % ToEltSz) return SDValue();
|
||||
|
||||
unsigned SizeRatio = FromEltSz / ToEltSz;
|
||||
assert(SizeRatio * NumElems * ToEltSz == VT.getSizeInBits());
|
||||
|
||||
// Create a type on which we perform the shuffle.
|
||||
EVT WideVecVT = EVT::getVectorVT(*DAG.getContext(), StVT.getScalarType(),
|
||||
NumElems*SizeRatio);
|
||||
assert(WideVecVT.getSizeInBits() == VT.getSizeInBits());
|
||||
|
||||
SDLoc DL(St);
|
||||
SDValue WideVec = DAG.getNode(ISD::BITCAST, DL, WideVecVT, StVal);
|
||||
SmallVector<int, 8> ShuffleVec(NumElems * SizeRatio, -1);
|
||||
for (unsigned i = 0; i < NumElems; ++i)
|
||||
ShuffleVec[i] = TLI.isBigEndian() ? (i+1) * SizeRatio - 1 : i * SizeRatio;
|
||||
|
||||
// Can't shuffle using an illegal type.
|
||||
if (!TLI.isTypeLegal(WideVecVT)) return SDValue();
|
||||
|
||||
SDValue Shuff = DAG.getVectorShuffle(WideVecVT, DL, WideVec,
|
||||
DAG.getUNDEF(WideVec.getValueType()),
|
||||
ShuffleVec.data());
|
||||
// At this point all of the data is stored at the bottom of the
|
||||
// register. We now need to save it to mem.
|
||||
|
||||
// Find the largest store unit
|
||||
MVT StoreType = MVT::i8;
|
||||
for (unsigned tp = MVT::FIRST_INTEGER_VALUETYPE;
|
||||
tp < MVT::LAST_INTEGER_VALUETYPE; ++tp) {
|
||||
MVT Tp = (MVT::SimpleValueType)tp;
|
||||
if (TLI.isTypeLegal(Tp) && Tp.getSizeInBits() <= NumElems * ToEltSz)
|
||||
StoreType = Tp;
|
||||
}
|
||||
// Didn't find a legal store type.
|
||||
if (!TLI.isTypeLegal(StoreType))
|
||||
return SDValue();
|
||||
|
||||
// Bitcast the original vector into a vector of store-size units
|
||||
EVT StoreVecVT = EVT::getVectorVT(*DAG.getContext(),
|
||||
StoreType, VT.getSizeInBits()/EVT(StoreType).getSizeInBits());
|
||||
assert(StoreVecVT.getSizeInBits() == VT.getSizeInBits());
|
||||
SDValue ShuffWide = DAG.getNode(ISD::BITCAST, DL, StoreVecVT, Shuff);
|
||||
SmallVector<SDValue, 8> Chains;
|
||||
SDValue Increment = DAG.getConstant(StoreType.getSizeInBits()/8,
|
||||
TLI.getPointerTy());
|
||||
SDValue BasePtr = St->getBasePtr();
|
||||
|
||||
// Perform one or more big stores into memory.
|
||||
unsigned E = (ToEltSz*NumElems)/StoreType.getSizeInBits();
|
||||
for (unsigned I = 0; I < E; I++) {
|
||||
SDValue SubVec = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL,
|
||||
StoreType, ShuffWide,
|
||||
DAG.getIntPtrConstant(I));
|
||||
SDValue Ch = DAG.getStore(St->getChain(), DL, SubVec, BasePtr,
|
||||
St->getPointerInfo(), St->isVolatile(),
|
||||
St->isNonTemporal(), St->getAlignment());
|
||||
BasePtr = DAG.getNode(ISD::ADD, DL, BasePtr.getValueType(), BasePtr,
|
||||
Increment);
|
||||
Chains.push_back(Ch);
|
||||
}
|
||||
return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chains);
|
||||
}
|
||||
|
||||
if (!ISD::isNormalStore(St))
|
||||
return SDValue();
|
||||
|
||||
// Split a store of a VMOVDRR into two integer stores to avoid mixing NEON and
|
||||
// ARM stores of arguments in the same cache line.
|
||||
if (StVal.getNode()->getOpcode() == ARMISD::VMOVDRR &&
|
||||
StVal.getNode()->hasOneUse()) {
|
||||
SelectionDAG &DAG = DCI.DAG;
|
||||
bool isBigEndian = DAG.getTargetLoweringInfo().isBigEndian();
|
||||
SDLoc DL(St);
|
||||
SDValue BasePtr = St->getBasePtr();
|
||||
SDValue NewST1 = DAG.getStore(St->getChain(), DL,
|
||||
StVal.getNode()->getOperand(isBigEndian ? 1 : 0 ),
|
||||
BasePtr, St->getPointerInfo(), St->isVolatile(),
|
||||
St->isNonTemporal(), St->getAlignment());
|
||||
|
||||
SDValue OffsetPtr = DAG.getNode(ISD::ADD, DL, MVT::i32, BasePtr,
|
||||
DAG.getConstant(4, MVT::i32));
|
||||
return DAG.getStore(NewST1.getValue(0), DL,
|
||||
StVal.getNode()->getOperand(isBigEndian ? 0 : 1),
|
||||
OffsetPtr, St->getPointerInfo(), St->isVolatile(),
|
||||
St->isNonTemporal(),
|
||||
std::min(4U, St->getAlignment() / 2));
|
||||
}
|
||||
|
||||
if (StVal.getValueType() != MVT::i64 ||
|
||||
StVal.getNode()->getOpcode() != ISD::EXTRACT_VECTOR_ELT)
|
||||
return SDValue();
|
||||
|
||||
// Bitcast an i64 store extracted from a vector to f64.
|
||||
// Otherwise, the i64 value will be legalized to a pair of i32 values.
|
||||
SelectionDAG &DAG = DCI.DAG;
|
||||
SDLoc dl(StVal);
|
||||
SDValue IntVec = StVal.getOperand(0);
|
||||
EVT FloatVT = EVT::getVectorVT(*DAG.getContext(), MVT::f64,
|
||||
IntVec.getValueType().getVectorNumElements());
|
||||
SDValue Vec = DAG.getNode(ISD::BITCAST, dl, FloatVT, IntVec);
|
||||
SDValue ExtElt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64,
|
||||
Vec, StVal.getOperand(1));
|
||||
dl = SDLoc(N);
|
||||
SDValue V = DAG.getNode(ISD::BITCAST, dl, MVT::i64, ExtElt);
|
||||
// Make the DAGCombiner fold the bitcasts.
|
||||
DCI.AddToWorklist(Vec.getNode());
|
||||
DCI.AddToWorklist(ExtElt.getNode());
|
||||
DCI.AddToWorklist(V.getNode());
|
||||
return DAG.getStore(St->getChain(), dl, V, St->getBasePtr(),
|
||||
St->getPointerInfo(), St->isVolatile(),
|
||||
St->isNonTemporal(), St->getAlignment(),
|
||||
St->getAAInfo());
|
||||
}
|
||||
|
||||
/// hasNormalLoadOperand - Check if any of the operands of a BUILD_VECTOR node
|
||||
/// are normal, non-volatile loads. If so, it is profitable to bitcast an
|
||||
/// i64 vector to have f64 elements, since the value can then be loaded
|
||||
@ -9253,6 +9112,149 @@ static SDValue PerformVDUPLANECombine(SDNode *N,
|
||||
return DCI.DAG.getNode(ISD::BITCAST, SDLoc(N), VT, Op);
|
||||
}
|
||||
|
||||
/// PerformSTORECombine - Target-specific dag combine xforms for
|
||||
/// ISD::STORE.
|
||||
static SDValue PerformSTORECombine(SDNode *N,
|
||||
TargetLowering::DAGCombinerInfo &DCI) {
|
||||
StoreSDNode *St = cast<StoreSDNode>(N);
|
||||
if (St->isVolatile())
|
||||
return SDValue();
|
||||
|
||||
// Optimize trunc store (of multiple scalars) to shuffle and store. First,
|
||||
// pack all of the elements in one place. Next, store to memory in fewer
|
||||
// chunks.
|
||||
SDValue StVal = St->getValue();
|
||||
EVT VT = StVal.getValueType();
|
||||
if (St->isTruncatingStore() && VT.isVector()) {
|
||||
SelectionDAG &DAG = DCI.DAG;
|
||||
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
|
||||
EVT StVT = St->getMemoryVT();
|
||||
unsigned NumElems = VT.getVectorNumElements();
|
||||
assert(StVT != VT && "Cannot truncate to the same type");
|
||||
unsigned FromEltSz = VT.getVectorElementType().getSizeInBits();
|
||||
unsigned ToEltSz = StVT.getVectorElementType().getSizeInBits();
|
||||
|
||||
// From, To sizes and ElemCount must be pow of two
|
||||
if (!isPowerOf2_32(NumElems * FromEltSz * ToEltSz)) return SDValue();
|
||||
|
||||
// We are going to use the original vector elt for storing.
|
||||
// Accumulated smaller vector elements must be a multiple of the store size.
|
||||
if (0 != (NumElems * FromEltSz) % ToEltSz) return SDValue();
|
||||
|
||||
unsigned SizeRatio = FromEltSz / ToEltSz;
|
||||
assert(SizeRatio * NumElems * ToEltSz == VT.getSizeInBits());
|
||||
|
||||
// Create a type on which we perform the shuffle.
|
||||
EVT WideVecVT = EVT::getVectorVT(*DAG.getContext(), StVT.getScalarType(),
|
||||
NumElems*SizeRatio);
|
||||
assert(WideVecVT.getSizeInBits() == VT.getSizeInBits());
|
||||
|
||||
SDLoc DL(St);
|
||||
SDValue WideVec = DAG.getNode(ISD::BITCAST, DL, WideVecVT, StVal);
|
||||
SmallVector<int, 8> ShuffleVec(NumElems * SizeRatio, -1);
|
||||
for (unsigned i = 0; i < NumElems; ++i)
|
||||
ShuffleVec[i] = TLI.isBigEndian() ? (i+1) * SizeRatio - 1 : i * SizeRatio;
|
||||
|
||||
// Can't shuffle using an illegal type.
|
||||
if (!TLI.isTypeLegal(WideVecVT)) return SDValue();
|
||||
|
||||
SDValue Shuff = DAG.getVectorShuffle(WideVecVT, DL, WideVec,
|
||||
DAG.getUNDEF(WideVec.getValueType()),
|
||||
ShuffleVec.data());
|
||||
// At this point all of the data is stored at the bottom of the
|
||||
// register. We now need to save it to mem.
|
||||
|
||||
// Find the largest store unit
|
||||
MVT StoreType = MVT::i8;
|
||||
for (unsigned tp = MVT::FIRST_INTEGER_VALUETYPE;
|
||||
tp < MVT::LAST_INTEGER_VALUETYPE; ++tp) {
|
||||
MVT Tp = (MVT::SimpleValueType)tp;
|
||||
if (TLI.isTypeLegal(Tp) && Tp.getSizeInBits() <= NumElems * ToEltSz)
|
||||
StoreType = Tp;
|
||||
}
|
||||
// Didn't find a legal store type.
|
||||
if (!TLI.isTypeLegal(StoreType))
|
||||
return SDValue();
|
||||
|
||||
// Bitcast the original vector into a vector of store-size units
|
||||
EVT StoreVecVT = EVT::getVectorVT(*DAG.getContext(),
|
||||
StoreType, VT.getSizeInBits()/EVT(StoreType).getSizeInBits());
|
||||
assert(StoreVecVT.getSizeInBits() == VT.getSizeInBits());
|
||||
SDValue ShuffWide = DAG.getNode(ISD::BITCAST, DL, StoreVecVT, Shuff);
|
||||
SmallVector<SDValue, 8> Chains;
|
||||
SDValue Increment = DAG.getConstant(StoreType.getSizeInBits()/8,
|
||||
TLI.getPointerTy());
|
||||
SDValue BasePtr = St->getBasePtr();
|
||||
|
||||
// Perform one or more big stores into memory.
|
||||
unsigned E = (ToEltSz*NumElems)/StoreType.getSizeInBits();
|
||||
for (unsigned I = 0; I < E; I++) {
|
||||
SDValue SubVec = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL,
|
||||
StoreType, ShuffWide,
|
||||
DAG.getIntPtrConstant(I));
|
||||
SDValue Ch = DAG.getStore(St->getChain(), DL, SubVec, BasePtr,
|
||||
St->getPointerInfo(), St->isVolatile(),
|
||||
St->isNonTemporal(), St->getAlignment());
|
||||
BasePtr = DAG.getNode(ISD::ADD, DL, BasePtr.getValueType(), BasePtr,
|
||||
Increment);
|
||||
Chains.push_back(Ch);
|
||||
}
|
||||
return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chains);
|
||||
}
|
||||
|
||||
if (!ISD::isNormalStore(St))
|
||||
return SDValue();
|
||||
|
||||
// Split a store of a VMOVDRR into two integer stores to avoid mixing NEON and
|
||||
// ARM stores of arguments in the same cache line.
|
||||
if (StVal.getNode()->getOpcode() == ARMISD::VMOVDRR &&
|
||||
StVal.getNode()->hasOneUse()) {
|
||||
SelectionDAG &DAG = DCI.DAG;
|
||||
bool isBigEndian = DAG.getTargetLoweringInfo().isBigEndian();
|
||||
SDLoc DL(St);
|
||||
SDValue BasePtr = St->getBasePtr();
|
||||
SDValue NewST1 = DAG.getStore(St->getChain(), DL,
|
||||
StVal.getNode()->getOperand(isBigEndian ? 1 : 0 ),
|
||||
BasePtr, St->getPointerInfo(), St->isVolatile(),
|
||||
St->isNonTemporal(), St->getAlignment());
|
||||
|
||||
SDValue OffsetPtr = DAG.getNode(ISD::ADD, DL, MVT::i32, BasePtr,
|
||||
DAG.getConstant(4, MVT::i32));
|
||||
return DAG.getStore(NewST1.getValue(0), DL,
|
||||
StVal.getNode()->getOperand(isBigEndian ? 0 : 1),
|
||||
OffsetPtr, St->getPointerInfo(), St->isVolatile(),
|
||||
St->isNonTemporal(),
|
||||
std::min(4U, St->getAlignment() / 2));
|
||||
}
|
||||
|
||||
if (StVal.getValueType() == MVT::i64 &&
|
||||
StVal.getNode()->getOpcode() == ISD::EXTRACT_VECTOR_ELT) {
|
||||
|
||||
// Bitcast an i64 store extracted from a vector to f64.
|
||||
// Otherwise, the i64 value will be legalized to a pair of i32 values.
|
||||
SelectionDAG &DAG = DCI.DAG;
|
||||
SDLoc dl(StVal);
|
||||
SDValue IntVec = StVal.getOperand(0);
|
||||
EVT FloatVT = EVT::getVectorVT(*DAG.getContext(), MVT::f64,
|
||||
IntVec.getValueType().getVectorNumElements());
|
||||
SDValue Vec = DAG.getNode(ISD::BITCAST, dl, FloatVT, IntVec);
|
||||
SDValue ExtElt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64,
|
||||
Vec, StVal.getOperand(1));
|
||||
dl = SDLoc(N);
|
||||
SDValue V = DAG.getNode(ISD::BITCAST, dl, MVT::i64, ExtElt);
|
||||
// Make the DAGCombiner fold the bitcasts.
|
||||
DCI.AddToWorklist(Vec.getNode());
|
||||
DCI.AddToWorklist(ExtElt.getNode());
|
||||
DCI.AddToWorklist(V.getNode());
|
||||
return DAG.getStore(St->getChain(), dl, V, St->getBasePtr(),
|
||||
St->getPointerInfo(), St->isVolatile(),
|
||||
St->isNonTemporal(), St->getAlignment(),
|
||||
St->getAAInfo());
|
||||
}
|
||||
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
// isConstVecPow2 - Return true if each vector element is a power of 2, all
|
||||
// elements are the same constant, C, and Log2(C) ranges from 1 to 32.
|
||||
static bool isConstVecPow2(SDValue ConstVec, bool isSigned, uint64_t &C)
|
||||
|
Loading…
x
Reference in New Issue
Block a user