summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Utils/LoopUtils.cpp
diff options
context:
space:
mode:
authorKarthik Bhat <kv.bhat@samsung.com>2015-04-23 08:29:20 +0000
committerKarthik Bhat <kv.bhat@samsung.com>2015-04-23 08:29:20 +0000
commit24e6cc2de4603bda679868d2baa2c472c1540719 (patch)
treea1daec4a1170c0aa3b4e9cc28cdfa1fe2406618d /llvm/lib/Transforms/Utils/LoopUtils.cpp
parent112a7bf961bb24121b3f7b057a000a3b843fc1a1 (diff)
downloadbcm5719-llvm-24e6cc2de4603bda679868d2baa2c472c1540719.tar.gz
bcm5719-llvm-24e6cc2de4603bda679868d2baa2c472c1540719.zip
Move common loop utility function isInductionPHI into LoopUtils.cpp
This patch refactors the definition of common utility function "isInductionPHI" to LoopUtils.cpp. This fixes compilation error when configured with -DBUILD_SHARED_LIBS=ON llvm-svn: 235577
Diffstat (limited to 'llvm/lib/Transforms/Utils/LoopUtils.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/LoopUtils.cpp46
1 files changed, 46 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Utils/LoopUtils.cpp b/llvm/lib/Transforms/Utils/LoopUtils.cpp
index 153cdc04edf..a5890c0adb0 100644
--- a/llvm/lib/Transforms/Utils/LoopUtils.cpp
+++ b/llvm/lib/Transforms/Utils/LoopUtils.cpp
@@ -16,6 +16,9 @@
#include "llvm/IR/PatternMatch.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Analysis/ScalarEvolution.h"
+#include "llvm/Analysis/ScalarEvolutionExpressions.h"
+#include "llvm/IR/Module.h"
#include "llvm/Transforms/Utils/LoopUtils.h"
using namespace llvm;
@@ -451,3 +454,46 @@ ReductionDescriptor::createMinMaxOp(IRBuilder<> &Builder,
Value *Select = Builder.CreateSelect(Cmp, Left, Right, "rdx.minmax.select");
return Select;
}
+
+bool llvm::isInductionPHI(PHINode *Phi, ScalarEvolution *SE,
+ ConstantInt *&StepValue) {
+ Type *PhiTy = Phi->getType();
+ // We only handle integer and pointer inductions variables.
+ if (!PhiTy->isIntegerTy() && !PhiTy->isPointerTy())
+ return false;
+
+ // Check that the PHI is consecutive.
+ const SCEV *PhiScev = SE->getSCEV(Phi);
+ const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(PhiScev);
+ if (!AR) {
+ DEBUG(dbgs() << "LV: PHI is not a poly recurrence.\n");
+ return false;
+ }
+
+ const SCEV *Step = AR->getStepRecurrence(*SE);
+ // Calculate the pointer stride and check if it is consecutive.
+ const SCEVConstant *C = dyn_cast<SCEVConstant>(Step);
+ if (!C)
+ return false;
+
+ ConstantInt *CV = C->getValue();
+ if (PhiTy->isIntegerTy()) {
+ StepValue = CV;
+ return true;
+ }
+
+ assert(PhiTy->isPointerTy() && "The PHI must be a pointer");
+ Type *PointerElementType = PhiTy->getPointerElementType();
+ // The pointer stride cannot be determined if the pointer element type is not
+ // sized.
+ if (!PointerElementType->isSized())
+ return false;
+
+ const DataLayout &DL = Phi->getModule()->getDataLayout();
+ int64_t Size = static_cast<int64_t>(DL.getTypeAllocSize(PointerElementType));
+ int64_t CVSize = CV->getSExtValue();
+ if (CVSize % Size)
+ return false;
+ StepValue = ConstantInt::getSigned(CV->getType(), CVSize / Size);
+ return true;
+}
OpenPOWER on IntegriCloud