mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-10-21 01:25:20 +00:00
Expand removal of MMX memory copies to allow 1 level
of TokenFactor underneath chain (seems to be enough) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@47554 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
4fc3d5dac2
commit
079f2a66ae
@ -5878,21 +5878,48 @@ static SDOperand PerformSTORECombine(StoreSDNode *St, SelectionDAG &DAG,
|
|||||||
const X86Subtarget *Subtarget) {
|
const X86Subtarget *Subtarget) {
|
||||||
// Turn load->store of MMX types into GPR load/stores. This avoids clobbering
|
// Turn load->store of MMX types into GPR load/stores. This avoids clobbering
|
||||||
// the FP state in cases where an emms may be missing.
|
// the FP state in cases where an emms may be missing.
|
||||||
|
// A preferable solution to the general problem is to figure out the right
|
||||||
|
// places to insert EMMS. This qualifies as a quick hack.
|
||||||
if (MVT::isVector(St->getValue().getValueType()) &&
|
if (MVT::isVector(St->getValue().getValueType()) &&
|
||||||
MVT::getSizeInBits(St->getValue().getValueType()) == 64 &&
|
MVT::getSizeInBits(St->getValue().getValueType()) == 64 &&
|
||||||
// Must be a store of a load.
|
isa<LoadSDNode>(St->getValue()) &&
|
||||||
isa<LoadSDNode>(St->getChain()) &&
|
!cast<LoadSDNode>(St->getValue())->isVolatile() &&
|
||||||
St->getChain().Val == St->getValue().Val &&
|
St->getChain().hasOneUse() && !St->isVolatile()) {
|
||||||
St->getValue().hasOneUse() && St->getChain().hasOneUse() &&
|
LoadSDNode *Ld = 0;
|
||||||
!St->isVolatile() && !cast<LoadSDNode>(St->getChain())->isVolatile()) {
|
int TokenFactorIndex = -1;
|
||||||
LoadSDNode *Ld = cast<LoadSDNode>(St->getChain());
|
SmallVector<SDOperand, 8> Ops;
|
||||||
|
SDNode* ChainVal = St->getChain().Val;
|
||||||
|
// Must be a store of a load. We currently handle two cases: the load
|
||||||
|
// is a direct child, and it's under an intervening TokenFactor. It is
|
||||||
|
// possible to dig deeper under nested TokenFactors.
|
||||||
|
if (ChainVal == St->getValue().Val)
|
||||||
|
Ld = cast<LoadSDNode>(St->getChain());
|
||||||
|
else if (St->getValue().hasOneUse() &&
|
||||||
|
ChainVal->getOpcode() == ISD::TokenFactor) {
|
||||||
|
for (unsigned i=0, e = ChainVal->getNumOperands(); i != e; ++i) {
|
||||||
|
if (ChainVal->getOperand(i).Val == St->getValue().Val) {
|
||||||
|
if (TokenFactorIndex != -1)
|
||||||
|
return SDOperand();
|
||||||
|
TokenFactorIndex = i;
|
||||||
|
Ld = cast<LoadSDNode>(St->getValue());
|
||||||
|
} else
|
||||||
|
Ops.push_back(ChainVal->getOperand(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Ld) {
|
||||||
// If we are a 64-bit capable x86, lower to a single movq load/store pair.
|
// If we are a 64-bit capable x86, lower to a single movq load/store pair.
|
||||||
if (Subtarget->is64Bit()) {
|
if (Subtarget->is64Bit()) {
|
||||||
SDOperand NewLd = DAG.getLoad(MVT::i64, Ld->getChain(), Ld->getBasePtr(),
|
SDOperand NewLd = DAG.getLoad(MVT::i64, Ld->getChain(),
|
||||||
Ld->getSrcValue(), Ld->getSrcValueOffset(),
|
Ld->getBasePtr(), Ld->getSrcValue(),
|
||||||
Ld->isVolatile(), Ld->getAlignment());
|
Ld->getSrcValueOffset(), Ld->isVolatile(),
|
||||||
return DAG.getStore(NewLd.getValue(1), NewLd, St->getBasePtr(),
|
Ld->getAlignment());
|
||||||
|
SDOperand NewChain = NewLd.getValue(1);
|
||||||
|
if (TokenFactorIndex != -1) {
|
||||||
|
Ops.push_back(NewLd);
|
||||||
|
NewChain = DAG.getNode(ISD::TokenFactor, MVT::Other, &Ops[0],
|
||||||
|
Ops.size());
|
||||||
|
}
|
||||||
|
return DAG.getStore(NewChain, NewLd, St->getBasePtr(),
|
||||||
St->getSrcValue(), St->getSrcValueOffset(),
|
St->getSrcValue(), St->getSrcValueOffset(),
|
||||||
St->isVolatile(), St->getAlignment());
|
St->isVolatile(), St->getAlignment());
|
||||||
}
|
}
|
||||||
@ -5910,19 +5937,28 @@ static SDOperand PerformSTORECombine(StoreSDNode *St, SelectionDAG &DAG,
|
|||||||
Ld->isVolatile(),
|
Ld->isVolatile(),
|
||||||
MinAlign(Ld->getAlignment(), 4));
|
MinAlign(Ld->getAlignment(), 4));
|
||||||
|
|
||||||
|
SDOperand NewChain = LoLd.getValue(1);
|
||||||
|
if (TokenFactorIndex != -1) {
|
||||||
|
Ops.push_back(LoLd);
|
||||||
|
Ops.push_back(HiLd);
|
||||||
|
NewChain = DAG.getNode(ISD::TokenFactor, MVT::Other, &Ops[0],
|
||||||
|
Ops.size());
|
||||||
|
}
|
||||||
|
|
||||||
LoAddr = St->getBasePtr();
|
LoAddr = St->getBasePtr();
|
||||||
HiAddr = DAG.getNode(ISD::ADD, MVT::i32, LoAddr,
|
HiAddr = DAG.getNode(ISD::ADD, MVT::i32, LoAddr,
|
||||||
DAG.getConstant(MVT::i32, 4));
|
DAG.getConstant(MVT::i32, 4));
|
||||||
|
|
||||||
SDOperand LoSt = DAG.getStore(LoLd.getValue(1), LoLd, LoAddr,
|
SDOperand LoSt = DAG.getStore(NewChain, LoLd, LoAddr,
|
||||||
St->getSrcValue(), St->getSrcValueOffset(),
|
St->getSrcValue(), St->getSrcValueOffset(),
|
||||||
St->isVolatile(), St->getAlignment());
|
St->isVolatile(), St->getAlignment());
|
||||||
SDOperand HiSt = DAG.getStore(HiLd.getValue(1), HiLd, HiAddr,
|
SDOperand HiSt = DAG.getStore(NewChain, HiLd, HiAddr,
|
||||||
St->getSrcValue(), St->getSrcValueOffset()+4,
|
St->getSrcValue(), St->getSrcValueOffset()+4,
|
||||||
St->isVolatile(),
|
St->isVolatile(),
|
||||||
MinAlign(St->getAlignment(), 4));
|
MinAlign(St->getAlignment(), 4));
|
||||||
return DAG.getNode(ISD::TokenFactor, MVT::Other, LoSt, HiSt);
|
return DAG.getNode(ISD::TokenFactor, MVT::Other, LoSt, HiSt);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return SDOperand();
|
return SDOperand();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user