diff options
author | Evan Cheng <evan.cheng@apple.com> | 2009-12-09 01:36:00 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2009-12-09 01:36:00 +0000 |
commit | 1a029cbee8f0bb7d1798aa474bdc46f017ba1871 (patch) | |
tree | c55aea88a170f7f0e35994d20b3170d13c960274 /lib/CodeGen/SelectionDAG/SelectionDAG.cpp | |
parent | 3b1d6462fe599fc9e17811b2d6bc8fad77183647 (diff) | |
download | external_llvm-1a029cbee8f0bb7d1798aa474bdc46f017ba1871.zip external_llvm-1a029cbee8f0bb7d1798aa474bdc46f017ba1871.tar.gz external_llvm-1a029cbee8f0bb7d1798aa474bdc46f017ba1871.tar.bz2 |
Move isConsecutiveLoad to SelectionDAG. It's not target dependent and it's primary used by selectdag passes.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@90922 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG/SelectionDAG.cpp')
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 28e991b..a4b3285 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -5868,6 +5868,49 @@ SDValue SelectionDAG::UnrollVectorOp(SDNode *N, unsigned ResNE) { &Scalars[0], Scalars.size()); } + +/// isConsecutiveLoad - Return true if LD is loading 'Bytes' bytes from a +/// location that is 'Dist' units away from the location that the 'Base' load +/// is loading from. +bool SelectionDAG::isConsecutiveLoad(LoadSDNode *LD, LoadSDNode *Base, + unsigned Bytes, int Dist) const { + if (LD->getChain() != Base->getChain()) + return false; + EVT VT = LD->getValueType(0); + if (VT.getSizeInBits() / 8 != Bytes) + return false; + + SDValue Loc = LD->getOperand(1); + SDValue BaseLoc = Base->getOperand(1); + if (Loc.getOpcode() == ISD::FrameIndex) { + if (BaseLoc.getOpcode() != ISD::FrameIndex) + return false; + const MachineFrameInfo *MFI = 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); + } + if (Loc.getOpcode() == ISD::ADD && Loc.getOperand(0) == BaseLoc) { + ConstantSDNode *V = dyn_cast<ConstantSDNode>(Loc.getOperand(1)); + if (V && (V->getSExtValue() == Dist*Bytes)) + return true; + } + + GlobalValue *GV1 = NULL; + 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; +} + + /// InferPtrAlignment - Infer alignment of a load / store address. Return 0 if /// it cannot be inferred. unsigned SelectionDAG::InferPtrAlignment(SDValue Ptr) const { |