summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorStefan Pintilie <stefanp@ca.ibm.com>2017-08-21 13:36:18 +0000
committerStefan Pintilie <stefanp@ca.ibm.com>2017-08-21 13:36:18 +0000
commit9495f33e457c1db54a412dbd3d839965acdd1268 (patch)
tree2c38ed7d2b1bfdbb596cf01f0547ae86a791e668 /llvm/lib
parent0a198dc18a7f6cc4a36a770fcff50847736cefd8 (diff)
downloadbcm5719-llvm-9495f33e457c1db54a412dbd3d839965acdd1268.tar.gz
bcm5719-llvm-9495f33e457c1db54a412dbd3d839965acdd1268.zip
[PowerPC] Check if the pre-increment PHI Node already exists
Preparations to use the per-increment are sometimes done in the target independent pass Loop Strength Reduction. We try to detect them in the PowerPC specific pass so that they are not done twice and so that we do not add PHIs that are not required. Differential Revision: https://reviews.llvm.org/D36736 llvm-svn: 311332
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/PowerPC/PPCLoopPreIncPrep.cpp65
1 files changed, 65 insertions, 0 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCLoopPreIncPrep.cpp b/llvm/lib/Target/PowerPC/PPCLoopPreIncPrep.cpp
index a349fa1b409..cdf544bdfac 100644
--- a/llvm/lib/Target/PowerPC/PPCLoopPreIncPrep.cpp
+++ b/llvm/lib/Target/PowerPC/PPCLoopPreIncPrep.cpp
@@ -28,6 +28,7 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Analysis/ScalarEvolutionExpander.h"
@@ -61,6 +62,8 @@ static cl::opt<unsigned> MaxVars("ppc-preinc-prep-max-vars",
cl::Hidden, cl::init(16),
cl::desc("Potential PHI threshold for PPC preinc loop prep"));
+STATISTIC(PHINodeAlreadyExists, "PHI node already in pre-increment form");
+
namespace llvm {
void initializePPCLoopPreIncPrepPass(PassRegistry&);
@@ -88,6 +91,9 @@ namespace {
AU.addRequired<ScalarEvolutionWrapperPass>();
}
+ bool alreadyPrepared(Loop *L, Instruction* MemI,
+ const SCEV *BasePtrStartSCEV,
+ const SCEVConstant *BasePtrIncSCEV);
bool runOnFunction(Function &F) override;
bool runOnLoop(Loop *L);
@@ -177,6 +183,62 @@ bool PPCLoopPreIncPrep::runOnFunction(Function &F) {
return MadeChange;
}
+// In order to prepare for the pre-increment a PHI is added.
+// This function will check to see if that PHI already exists and will return
+// true if it found an existing PHI with the same start and increment as the
+// one we wanted to create.
+bool PPCLoopPreIncPrep::alreadyPrepared(Loop *L, Instruction* MemI,
+ const SCEV *BasePtrStartSCEV,
+ const SCEVConstant *BasePtrIncSCEV) {
+ BasicBlock *BB = MemI->getParent();
+ if (!BB)
+ return false;
+
+ BasicBlock *PredBB = L->getLoopPredecessor();
+ BasicBlock *LatchBB = L->getLoopLatch();
+
+ if (!PredBB || !LatchBB)
+ return false;
+
+ // Run through the PHIs and see if we have some that looks like a preparation
+ iterator_range<BasicBlock::phi_iterator> PHIIter = BB->phis();
+ for (auto & CurrentPHI : PHIIter) {
+ PHINode *CurrentPHINode = dyn_cast<PHINode>(&CurrentPHI);
+ if (!CurrentPHINode)
+ continue;
+
+ if (!SE->isSCEVable(CurrentPHINode->getType()))
+ continue;
+
+ const SCEV *PHISCEV = SE->getSCEVAtScope(CurrentPHINode, L);
+
+ const SCEVAddRecExpr *PHIBasePtrSCEV = dyn_cast<SCEVAddRecExpr>(PHISCEV);
+ if (!PHIBasePtrSCEV)
+ continue;
+
+ const SCEVConstant *PHIBasePtrIncSCEV =
+ dyn_cast<SCEVConstant>(PHIBasePtrSCEV->getStepRecurrence(*SE));
+ if (!PHIBasePtrIncSCEV)
+ continue;
+
+ if (CurrentPHINode->getNumIncomingValues() == 2) {
+ if ( (CurrentPHINode->getIncomingBlock(0) == LatchBB &&
+ CurrentPHINode->getIncomingBlock(1) == PredBB) ||
+ (CurrentPHINode->getIncomingBlock(1) == LatchBB &&
+ CurrentPHINode->getIncomingBlock(0) == PredBB) ) {
+ if (PHIBasePtrSCEV->getStart() == BasePtrStartSCEV &&
+ PHIBasePtrIncSCEV == BasePtrIncSCEV) {
+ // The existing PHI (CurrentPHINode) has the same start and increment
+ // as the PHI that we wanted to create.
+ ++PHINodeAlreadyExists;
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
bool PPCLoopPreIncPrep::runOnLoop(Loop *L) {
bool MadeChange = false;
@@ -347,6 +409,9 @@ bool PPCLoopPreIncPrep::runOnLoop(Loop *L) {
DEBUG(dbgs() << "PIP: New start is: " << *BasePtrStartSCEV << "\n");
+ if (alreadyPrepared(L, MemI, BasePtrStartSCEV, BasePtrIncSCEV))
+ continue;
+
PHINode *NewPHI = PHINode::Create(I8PtrTy, HeaderLoopPredCount,
MemI->hasName() ? MemI->getName() + ".phi" : "",
Header->getFirstNonPHI());
OpenPOWER on IntegriCloud