diff options
author | Hal Finkel <hfinkel@anl.gov> | 2013-05-27 02:06:39 +0000 |
---|---|---|
committer | Hal Finkel <hfinkel@anl.gov> | 2013-05-27 02:06:39 +0000 |
commit | 119da2eb20fffce88fa659d761ef5cea43f09ab6 (patch) | |
tree | 323be3f1309bed5fb2eddc3d47b833650105acca | |
parent | d1c99b2aaeda2210769d2125dc9126a7ccd898ef (diff) | |
download | external_llvm-119da2eb20fffce88fa659d761ef5cea43f09ab6.zip external_llvm-119da2eb20fffce88fa659d761ef5cea43f09ab6.tar.gz external_llvm-119da2eb20fffce88fa659d761ef5cea43f09ab6.tar.bz2 |
PPC: Add a isConsecutiveLS utility function
isConsecutiveLS is a slightly more general form of
SelectionDAG::isConsecutiveLoad. Aside from also handling stores, it also does
not assume equality of the chain operands is necessary. In the case of the PPC
backend, this chain condition is checked in a more general way by the
surrounding code.
Mostly, this part of the refactoring in preparation for supporting optimized
unaligned stores.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@182723 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/PowerPC/PPCISelLowering.cpp | 44 |
1 files changed, 42 insertions, 2 deletions
diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index 87b63a8..ddf31bd 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -6781,6 +6781,46 @@ SDValue PPCTargetLowering::DAGCombineFastRecipFSQRT(SDValue Op, return SDValue(); } +// Like SelectionDAG::isConsecutiveLoad, but also works for stores, and does +// not enforce equality of the chain operands. +static bool isConsecutiveLS(LSBaseSDNode *LS, LSBaseSDNode *Base, + unsigned Bytes, int Dist, + SelectionDAG &DAG) { + EVT VT = LS->getMemoryVT(); + if (VT.getSizeInBits() / 8 != Bytes) + return false; + + SDValue Loc = LS->getBasePtr(); + SDValue BaseLoc = Base->getBasePtr(); + if (Loc.getOpcode() == ISD::FrameIndex) { + if (BaseLoc.getOpcode() != ISD::FrameIndex) + return false; + const MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); + int FI = cast<FrameIndexSDNode>(Loc)->getIndex(); + int BFI = cast<FrameIndexSDNode>(BaseLoc)->getIndex(); + int FS = MFI->getObjectSize(FI); + int BFS = MFI->getObjectSize(BFI); + if (FS != BFS || FS != (int)Bytes) return false; + return MFI->getObjectOffset(FI) == (MFI->getObjectOffset(BFI) + Dist*Bytes); + } + + // Handle X+C + if (DAG.isBaseWithConstantOffset(Loc) && Loc.getOperand(0) == BaseLoc && + cast<ConstantSDNode>(Loc.getOperand(1))->getSExtValue() == Dist*Bytes) + return true; + + const TargetLowering &TLI = DAG.getTargetLoweringInfo(); + const GlobalValue *GV1 = NULL; + const GlobalValue *GV2 = NULL; + int64_t Offset1 = 0; + int64_t Offset2 = 0; + bool isGA1 = TLI.isGAPlusOffset(Loc.getNode(), GV1, Offset1); + bool isGA2 = TLI.isGAPlusOffset(BaseLoc.getNode(), GV2, Offset2); + if (isGA1 && isGA2 && GV1 == GV2) + return Offset1 == (Offset2 + Dist*Bytes); + return false; +} + // Return true is there is a nearyby consecutive load to the one provided // (regardless of alignment). We search up and down the chain, looking though // token factors and other loads (but nothing else). As a result, a true @@ -6803,7 +6843,7 @@ static bool findConsecutiveLoad(LoadSDNode *LD, SelectionDAG &DAG) { continue; if (LoadSDNode *ChainLD = dyn_cast<LoadSDNode>(ChainNext)) { - if (DAG.isConsecutiveLoad(ChainLD, LD, VT.getStoreSize(), 1)) + if (isConsecutiveLS(ChainLD, LD, VT.getStoreSize(), 1, DAG)) return true; if (!Visited.count(ChainLD->getChain().getNode())) @@ -6835,7 +6875,7 @@ static bool findConsecutiveLoad(LoadSDNode *LD, SelectionDAG &DAG) { continue; if (LoadSDNode *ChainLD = dyn_cast<LoadSDNode>(LoadRoot)) - if (DAG.isConsecutiveLoad(ChainLD, LD, VT.getStoreSize(), 1)) + if (isConsecutiveLS(ChainLD, LD, VT.getStoreSize(), 1, DAG)) return true; for (SDNode::use_iterator UI = LoadRoot->use_begin(), |