summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorNirav Dave <niravd@google.com>2017-06-21 15:40:43 +0000
committerNirav Dave <niravd@google.com>2017-06-21 15:40:43 +0000
commitc1b6aa77bbdb7c022a47f435ecfc557f01988d3f (patch)
tree27f74d8409212fab919b175332e22f3f4ea93620 /llvm/lib
parentd1f8b8162b11bebb948f9361f578263e4b847039 (diff)
downloadbcm5719-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')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/CMakeLists.txt1
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp115
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp95
3 files changed, 97 insertions, 114 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/CMakeLists.txt b/llvm/lib/CodeGen/SelectionDAG/CMakeLists.txt
index a668ddb7389..ae9c5adb039 100644
--- a/llvm/lib/CodeGen/SelectionDAG/CMakeLists.txt
+++ b/llvm/lib/CodeGen/SelectionDAG/CMakeLists.txt
@@ -17,6 +17,7 @@ add_llvm_library(LLVMSelectionDAG
ScheduleDAGVLIW.cpp
SelectionDAGBuilder.cpp
SelectionDAG.cpp
+ SelectionDAGAddressAnalysis.cpp
SelectionDAGDumper.cpp
SelectionDAGISel.cpp
SelectionDAGPrinter.cpp
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 {
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp
new file mode 100644
index 00000000000..d2e0dbbf88e
--- /dev/null
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp
@@ -0,0 +1,95 @@
+//===-- llvm/CodeGen/SelectionDAGAddressAnalysis.cpp ------- DAG Address
+//Analysis ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+
+#include "llvm/CodeGen/SelectionDAGAddressAnalysis.h"
+#include "llvm/CodeGen/ISDOpcodes.h"
+#include "llvm/CodeGen/SelectionDAG.h"
+#include "llvm/CodeGen/SelectionDAGNodes.h"
+
+namespace llvm {
+
+bool BaseIndexOffset::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.
+BaseIndexOffset 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);
+}
+} // end namespace llvm
OpenPOWER on IntegriCloud