llvm.org GIT mirror llvm / 079f2a6
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 Dale Johannesen 12 years ago
1 changed file(s) with 76 addition(s) and 40 deletion(s). Raw diff Collapse all Expand all
58775877 const X86Subtarget *Subtarget) {
58785878 // Turn load->store of MMX types into GPR load/stores. This avoids clobbering
58795879 // the FP state in cases where an emms may be missing.
5880 // A preferable solution to the general problem is to figure out the right
5881 // places to insert EMMS. This qualifies as a quick hack.
58805882 if (MVT::isVector(St->getValue().getValueType()) &&
58815883 MVT::getSizeInBits(St->getValue().getValueType()) == 64 &&
5882 // Must be a store of a load.
5883 isa(St->getChain()) &&
5884 St->getChain().Val == St->getValue().Val &&
5885 St->getValue().hasOneUse() && St->getChain().hasOneUse() &&
5886 !St->isVolatile() && !cast(St->getChain())->isVolatile()) {
5887 LoadSDNode *Ld = cast(St->getChain());
5888
5889 // If we are a 64-bit capable x86, lower to a single movq load/store pair.
5890 if (Subtarget->is64Bit()) {
5891 SDOperand NewLd = DAG.getLoad(MVT::i64, Ld->getChain(), Ld->getBasePtr(),
5892 Ld->getSrcValue(), Ld->getSrcValueOffset(),
5893 Ld->isVolatile(), Ld->getAlignment());
5894 return DAG.getStore(NewLd.getValue(1), NewLd, St->getBasePtr(),
5884 isa(St->getValue()) &&
5885 !cast(St->getValue())->isVolatile() &&
5886 St->getChain().hasOneUse() && !St->isVolatile()) {
5887 LoadSDNode *Ld = 0;
5888 int TokenFactorIndex = -1;
5889 SmallVector Ops;
5890 SDNode* ChainVal = St->getChain().Val;
5891 // Must be a store of a load. We currently handle two cases: the load
5892 // is a direct child, and it's under an intervening TokenFactor. It is
5893 // possible to dig deeper under nested TokenFactors.
5894 if (ChainVal == St->getValue().Val)
5895 Ld = cast(St->getChain());
5896 else if (St->getValue().hasOneUse() &&
5897 ChainVal->getOpcode() == ISD::TokenFactor) {
5898 for (unsigned i=0, e = ChainVal->getNumOperands(); i != e; ++i) {
5899 if (ChainVal->getOperand(i).Val == St->getValue().Val) {
5900 if (TokenFactorIndex != -1)
5901 return SDOperand();
5902 TokenFactorIndex = i;
5903 Ld = cast(St->getValue());
5904 } else
5905 Ops.push_back(ChainVal->getOperand(i));
5906 }
5907 }
5908 if (Ld) {
5909 // If we are a 64-bit capable x86, lower to a single movq load/store pair.
5910 if (Subtarget->is64Bit()) {
5911 SDOperand NewLd = DAG.getLoad(MVT::i64, Ld->getChain(),
5912 Ld->getBasePtr(), Ld->getSrcValue(),
5913 Ld->getSrcValueOffset(), Ld->isVolatile(),
5914 Ld->getAlignment());
5915 SDOperand NewChain = NewLd.getValue(1);
5916 if (TokenFactorIndex != -1) {
5917 Ops.push_back(NewLd);
5918 NewChain = DAG.getNode(ISD::TokenFactor, MVT::Other, &Ops[0],
5919 Ops.size());
5920 }
5921 return DAG.getStore(NewChain, NewLd, St->getBasePtr(),
5922 St->getSrcValue(), St->getSrcValueOffset(),
5923 St->isVolatile(), St->getAlignment());
5924 }
5925
5926 // Otherwise, lower to two 32-bit copies.
5927 SDOperand LoAddr = Ld->getBasePtr();
5928 SDOperand HiAddr = DAG.getNode(ISD::ADD, MVT::i32, LoAddr,
5929 DAG.getConstant(MVT::i32, 4));
5930
5931 SDOperand LoLd = DAG.getLoad(MVT::i32, Ld->getChain(), LoAddr,
5932 Ld->getSrcValue(), Ld->getSrcValueOffset(),
5933 Ld->isVolatile(), Ld->getAlignment());
5934 SDOperand HiLd = DAG.getLoad(MVT::i32, Ld->getChain(), HiAddr,
5935 Ld->getSrcValue(), Ld->getSrcValueOffset()+4,
5936 Ld->isVolatile(),
5937 MinAlign(Ld->getAlignment(), 4));
5938
5939 SDOperand NewChain = LoLd.getValue(1);
5940 if (TokenFactorIndex != -1) {
5941 Ops.push_back(LoLd);
5942 Ops.push_back(HiLd);
5943 NewChain = DAG.getNode(ISD::TokenFactor, MVT::Other, &Ops[0],
5944 Ops.size());
5945 }
5946
5947 LoAddr = St->getBasePtr();
5948 HiAddr = DAG.getNode(ISD::ADD, MVT::i32, LoAddr,
5949 DAG.getConstant(MVT::i32, 4));
5950
5951 SDOperand LoSt = DAG.getStore(NewChain, LoLd, LoAddr,
58955952 St->getSrcValue(), St->getSrcValueOffset(),
58965953 St->isVolatile(), St->getAlignment());
5897 }
5898
5899 // Otherwise, lower to two 32-bit copies.
5900 SDOperand LoAddr = Ld->getBasePtr();
5901 SDOperand HiAddr = DAG.getNode(ISD::ADD, MVT::i32, LoAddr,
5902 DAG.getConstant(MVT::i32, 4));
5903
5904 SDOperand LoLd = DAG.getLoad(MVT::i32, Ld->getChain(), LoAddr,
5905 Ld->getSrcValue(), Ld->getSrcValueOffset(),
5906 Ld->isVolatile(), Ld->getAlignment());
5907 SDOperand HiLd = DAG.getLoad(MVT::i32, Ld->getChain(), HiAddr,
5908 Ld->getSrcValue(), Ld->getSrcValueOffset()+4,
5909 Ld->isVolatile(),
5910 MinAlign(Ld->getAlignment(), 4));
5911
5912 LoAddr = St->getBasePtr();
5913 HiAddr = DAG.getNode(ISD::ADD, MVT::i32, LoAddr,
5914 DAG.getConstant(MVT::i32, 4));
5915
5916 SDOperand LoSt = DAG.getStore(LoLd.getValue(1), LoLd, LoAddr,
5917 St->getSrcValue(), St->getSrcValueOffset(),
5918 St->isVolatile(), St->getAlignment());
5919 SDOperand HiSt = DAG.getStore(HiLd.getValue(1), HiLd, HiAddr,
5920 St->getSrcValue(), St->getSrcValueOffset()+4,
5921 St->isVolatile(),
5922 MinAlign(St->getAlignment(), 4));
5923 return DAG.getNode(ISD::TokenFactor, MVT::Other, LoSt, HiSt);
5954 SDOperand HiSt = DAG.getStore(NewChain, HiLd, HiAddr,
5955 St->getSrcValue(), St->getSrcValueOffset()+4,
5956 St->isVolatile(),
5957 MinAlign(St->getAlignment(), 4));
5958 return DAG.getNode(ISD::TokenFactor, MVT::Other, LoSt, HiSt);
5959 }
59245960 }
59255961 return SDOperand();
59265962 }