diff options
author | Nirav Dave <niravd@google.com> | 2017-06-21 15:40:43 +0000 |
---|---|---|
committer | Nirav Dave <niravd@google.com> | 2017-06-21 15:40:43 +0000 |
commit | c1b6aa77bbdb7c022a47f435ecfc557f01988d3f (patch) | |
tree | 27f74d8409212fab919b175332e22f3f4ea93620 /llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | |
parent | d1f8b8162b11bebb948f9361f578263e4b847039 (diff) | |
download | bcm5719-llvm-c1b6aa77bbdb7c022a47f435ecfc557f01988d3f.tar.gz bcm5719-llvm-c1b6aa77bbdb7c022a47f435ecfc557f01988d3f.zip |
[DAG] Move BaseIndexOffset into separate Libarary. NFC.
Move BaseIndexOffset analysis out of DAGCombiner for use in other
files.
llvm-svn: 305921
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 115 |
1 files changed, 1 insertions, 114 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 0e092927974..14a722a59e8 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -25,6 +25,7 @@ #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/SelectionDAG.h" +#include "llvm/CodeGen/SelectionDAGAddressAnalysis.h" #include "llvm/CodeGen/SelectionDAGTargetInfo.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DerivedTypes.h" @@ -4695,120 +4696,6 @@ SDNode *DAGCombiner::MatchRotate(SDValue LHS, SDValue RHS, const SDLoc &DL) { } namespace { -/// Helper struct to parse and store a memory address as base + index + offset. -/// We ignore sign extensions when it is safe to do so. -/// The following two expressions are not equivalent. To differentiate we need -/// to store whether there was a sign extension involved in the index -/// computation. -/// (load (i64 add (i64 copyfromreg %c) -/// (i64 signextend (add (i8 load %index) -/// (i8 1)))) -/// vs -/// -/// (load (i64 add (i64 copyfromreg %c) -/// (i64 signextend (i32 add (i32 signextend (i8 load %index)) -/// (i32 1))))) -class BaseIndexOffset { -private: - SDValue Base; - SDValue Index; - int64_t Offset; - bool IsIndexSignExt; - -public: - BaseIndexOffset() : Offset(0), IsIndexSignExt(false) {} - - BaseIndexOffset(SDValue Base, SDValue Index, int64_t Offset, - bool IsIndexSignExt) : - Base(Base), Index(Index), Offset(Offset), IsIndexSignExt(IsIndexSignExt) {} - - SDValue getBase() { return Base; } - SDValue getIndex() { return Index; } - - bool equalBaseIndex(BaseIndexOffset &Other, const SelectionDAG &DAG) { - int64_t Off; - return equalBaseIndex(Other, DAG, Off); - } - - bool equalBaseIndex(BaseIndexOffset &Other, const SelectionDAG &DAG, - int64_t &Off) { - // Obvious equivalent - Off = Other.Offset - Offset; - if (Other.Base == Base && Other.Index == Index && - Other.IsIndexSignExt == IsIndexSignExt) - return true; - - // Match GlobalAddresses - if (Index == Other.Index) - if (GlobalAddressSDNode *A = dyn_cast<GlobalAddressSDNode>(Base)) - if (GlobalAddressSDNode *B = dyn_cast<GlobalAddressSDNode>(Other.Base)) - if (A->getGlobal() == B->getGlobal()) { - Off += B->getOffset() - A->getOffset(); - return true; - } - - // TODO: we should be able to add FrameIndex analysis improvements here. - - return false; - } - - /// Parses tree in Ptr for base, index, offset addresses. - static BaseIndexOffset match(SDValue Ptr) { - // (((B + I*M) + c)) + c ... - SDValue Base = Ptr; - SDValue Index = SDValue(); - int64_t Offset = 0; - bool IsIndexSignExt = false; - - //Consume constant adds - while (Base->getOpcode() == ISD::ADD && - isa<ConstantSDNode>(Base->getOperand(1))) { - int64_t POffset = cast<ConstantSDNode>(Base->getOperand(1))->getSExtValue(); - Offset += POffset; - Base = Base->getOperand(0); - } - - if (Base->getOpcode() == ISD::ADD) { - // TODO: The following code appears to be needless as it just - // bails on some Ptrs early, reducing the cases where we - // find equivalence. We should be able to remove this. - // Inside a loop the current BASE pointer is calculated using an ADD and a - // MUL instruction. In this case Base is the actual BASE pointer. - // (i64 add (i64 %array_ptr) - // (i64 mul (i64 %induction_var) - // (i64 %element_size))) - if (Base->getOperand(1)->getOpcode() == ISD::MUL) - return BaseIndexOffset(Base, Index, Offset, IsIndexSignExt); - - // Look at Base + Index + Offset cases. - Index = Base->getOperand(1); - SDValue PotentialBase = Base->getOperand(0); - - // Skip signextends. - if (Index->getOpcode() == ISD::SIGN_EXTEND) { - Index = Index->getOperand(0); - IsIndexSignExt = true; - } - - // Check if Index Offset pattern - if (Index->getOpcode() != ISD::ADD || - !isa<ConstantSDNode>(Index->getOperand(1))) - return BaseIndexOffset(PotentialBase, Index, Offset, IsIndexSignExt); - - Offset += cast<ConstantSDNode>(Index->getOperand(1))->getSExtValue(); - Index = Index->getOperand(0); - if (Index->getOpcode() == ISD::SIGN_EXTEND) { - Index = Index->getOperand(0); - IsIndexSignExt = true; - } else IsIndexSignExt = false; - Base = PotentialBase; - } - return BaseIndexOffset(Base, Index, Offset, IsIndexSignExt); - } -}; -} // namespace - -namespace { /// Represents known origin of an individual byte in load combine pattern. The /// value of the byte is either constant zero or comes from memory. struct ByteProvider { |