From 044eb2f6afba375a914ac9d8024f8f5142bb912e Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Mon, 18 Dec 2017 20:10:56 +0000 Subject: Vendor import of llvm trunk r321017: https://llvm.org/svn/llvm-project/llvm/trunk@321017 --- lib/Target/PowerPC/PPCLoopPreIncPrep.cpp | 65 ++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) (limited to 'lib/Target/PowerPC/PPCLoopPreIncPrep.cpp') diff --git a/lib/Target/PowerPC/PPCLoopPreIncPrep.cpp b/lib/Target/PowerPC/PPCLoopPreIncPrep.cpp index a349fa1b40907..cdf544bdfac35 100644 --- a/lib/Target/PowerPC/PPCLoopPreIncPrep.cpp +++ b/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 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(); } + 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 PHIIter = BB->phis(); + for (auto & CurrentPHI : PHIIter) { + PHINode *CurrentPHINode = dyn_cast(&CurrentPHI); + if (!CurrentPHINode) + continue; + + if (!SE->isSCEVable(CurrentPHINode->getType())) + continue; + + const SCEV *PHISCEV = SE->getSCEVAtScope(CurrentPHINode, L); + + const SCEVAddRecExpr *PHIBasePtrSCEV = dyn_cast(PHISCEV); + if (!PHIBasePtrSCEV) + continue; + + const SCEVConstant *PHIBasePtrIncSCEV = + dyn_cast(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()); -- cgit v1.3