22 #define DEBUG_TYPE "ppc-loop-preinc-prep" 64 cl::desc(
"Potential PHI threshold for PPC preinc loop prep"));
66 STATISTIC(PHINodeAlreadyExists,
"PHI node already in pre-increment form");
96 const SCEV *BasePtrStartSCEV,
100 bool runOnLoop(
Loop *L);
101 void simplifyLoopLatch(
Loop *L);
102 bool rotateLoop(
Loop *L);
115 static const char *
name =
"Prepare loop for pre-inc. addressing modes";
122 return new PPCLoopPreIncPrep(TM);
127 struct BucketElement {
137 Elements(1, BucketElement(I)) {}
139 const SCEV *BaseSCEV;
146 Value *StrippedBasePtr = BasePtr;
147 while (
BitCastInst *BC = dyn_cast<BitCastInst>(StrippedBasePtr))
148 StrippedBasePtr = BC->getOperand(0);
150 return GEP->isInBounds();
156 if (
LoadInst *LMemI = dyn_cast<LoadInst>(MemI)) {
157 return LMemI->getPointerOperand();
158 }
else if (
StoreInst *SMemI = dyn_cast<StoreInst>(MemI)) {
159 return SMemI->getPointerOperand();
160 }
else if (
IntrinsicInst *IMemI = dyn_cast<IntrinsicInst>(MemI)) {
162 return IMemI->getArgOperand(0);
172 LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
173 SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
174 auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>();
175 DT = DTWP ? &DTWP->getDomTree() :
nullptr;
176 PreserveLCSSA = mustPreserveAnalysisID(
LCSSAID);
178 bool MadeChange =
false;
180 for (
auto I = LI->begin(),
IE = LI->end();
I !=
IE; ++
I)
182 MadeChange |= runOnLoop(*L);
192 const SCEV *BasePtrStartSCEV,
201 if (!PredBB || !LatchBB)
206 for (
auto & CurrentPHI : PHIIter) {
211 if (!SE->isSCEVable(CurrentPHINode->
getType()))
214 const SCEV *PHISCEV = SE->getSCEVAtScope(CurrentPHINode, L);
222 if (!PHIBasePtrIncSCEV)
230 if (PHIBasePtrSCEV->
getStart() == BasePtrStartSCEV &&
231 PHIBasePtrIncSCEV == BasePtrIncSCEV) {
234 ++PHINodeAlreadyExists;
243 bool PPCLoopPreIncPrep::runOnLoop(
Loop *L) {
244 bool MadeChange =
false;
257 unsigned HeaderLoopPredCount =
pred_size(Header);
268 if (
LoadInst *LMemI = dyn_cast<LoadInst>(J)) {
270 PtrValue = LMemI->getPointerOperand();
271 }
else if (
StoreInst *SMemI = dyn_cast<StoreInst>(J)) {
273 PtrValue = SMemI->getPointerOperand();
274 }
else if (
IntrinsicInst *IMemI = dyn_cast<IntrinsicInst>(J)) {
277 PtrValue = IMemI->getArgOperand(0);
293 const SCEV *LSCEV = SE->getSCEVAtScope(PtrValue, L);
294 if (
const SCEVAddRecExpr *LARSCEV = dyn_cast<SCEVAddRecExpr>(LSCEV)) {
295 if (LARSCEV->getLoop() != L)
304 dyn_cast<SCEVConstant>(LARSCEV->getStepRecurrence(*SE))) {
305 const APInt &ConstInt = StepConst->getValue()->getValue();
314 bool FoundBucket =
false;
315 for (
auto &
B : Buckets) {
316 const SCEV *Diff = SE->getMinusSCEV(LSCEV,
B.BaseSCEV);
317 if (
const auto *CDiff = dyn_cast<SCEVConstant>(Diff)) {
318 B.Elements.push_back(BucketElement(CDiff, MemI));
327 Buckets.push_back(Bucket(LSCEV, MemI));
339 if (!LoopPredecessor ||
345 if (!LoopPredecessor)
351 for (
unsigned i = 0, e = Buckets.
size(); i != e; ++i) {
364 for (
int j = 0, je = Buckets[i].Elements.
size(); j != je; ++j) {
365 if (
auto *II = dyn_cast<IntrinsicInst>(Buckets[i].Elements[j].Instr))
375 if (!Buckets[i].Elements[j].
Offset ||
376 Buckets[i].Elements[j].
Offset->isZero())
379 const SCEV *
Offset = Buckets[i].Elements[j].Offset;
380 Buckets[i].BaseSCEV = SE->getAddExpr(Buckets[i].BaseSCEV, Offset);
381 for (
auto &
E : Buckets[i].Elements) {
383 E.Offset = cast<SCEVConstant>(SE->getMinusSCEV(
E.Offset, Offset));
385 E.Offset = cast<SCEVConstant>(SE->getNegativeSCEV(Offset));
388 std::swap(Buckets[i].Elements[j], Buckets[i].Elements[0]);
393 cast<SCEVAddRecExpr>(Buckets[i].BaseSCEV);
397 LLVM_DEBUG(
dbgs() <<
"PIP: Transforming: " << *BasePtrSCEV <<
"\n");
399 "AddRec for the wrong loop?");
405 assert(BasePtr &&
"No pointer operand");
412 if (!SE->isLoopInvariant(BasePtrStartSCEV, L))
419 BasePtrStartSCEV = SE->getMinusSCEV(BasePtrStartSCEV, BasePtrIncSCEV);
423 LLVM_DEBUG(
dbgs() <<
"PIP: New start is: " << *BasePtrStartSCEV <<
"\n");
425 if (alreadyPrepared(L, MemI, BasePtrStartSCEV, BasePtrIncSCEV))
429 MemI->hasName() ? MemI->getName() +
".phi" :
"",
433 Value *BasePtrStart = SCEVE.expandCodeFor(BasePtrStartSCEV, I8PtrTy,
440 if (*PI != LoopPredecessor)
443 NewPHI->
addIncoming(BasePtrStart, LoopPredecessor);
448 I8Ty, NewPHI, BasePtrIncSCEV->
getValue(),
449 MemI->
hasName() ? MemI->getName() +
".inc" :
"", InsPoint);
453 if (*PI == LoopPredecessor)
466 if (
Instruction *IDel = dyn_cast<Instruction>(BasePtr))
467 BBChanged.insert(IDel->getParent());
474 NewPtrs.
insert( NewBasePtr);
476 for (
auto I = std::next(Buckets[i].Elements.
begin()),
477 IE = Buckets[i].Elements.
end();
I !=
IE; ++
I) {
479 assert(Ptr &&
"No pointer operand");
480 if (NewPtrs.
count(Ptr))
484 if (!
I->Offset ||
I->Offset->getValue()->isZero()) {
485 RealNewPtr = NewBasePtr;
488 if (PtrIP && isa<Instruction>(NewBasePtr) &&
491 else if (isa<PHINode>(PtrIP))
497 I8Ty, PtrInc,
I->Offset->getValue(),
498 I->Instr->hasName() ?
I->Instr->getName() +
".off" :
"", PtrIP);
505 if (
Instruction *IDel = dyn_cast<Instruction>(Ptr))
506 BBChanged.insert(IDel->getParent());
514 ReplNewPtr = RealNewPtr;
519 NewPtrs.
insert(RealNewPtr);
527 if (BBChanged.count(*
I))
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
BlockT * getLoopLatch() const
If there is a single latch block for this loop, return it.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
This class represents lattice values for constants.
ArrayRef< BasicBlock *>::const_iterator block_iterator
The main scalar evolution driver.
static GetElementPtrInst * Create(Type *PointeeType, Value *Ptr, ArrayRef< Value *> IdxList, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
BasicBlock * InsertPreheaderForLoop(Loop *L, DominatorTree *DT, LoopInfo *LI, bool PreserveLCSSA)
InsertPreheaderForLoop - Once we discover that a loop doesn't have a preheader, this method is called...
STATISTIC(NumFunctions, "Total number of functions")
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
An instruction for reading from memory.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
bool isVectorTy() const
True if this is an instance of VectorType.
static Value * GetPointerOperand(Value *MemI)
AnalysisUsage & addRequired()
const Module * getModule() const
Return the module owning the function this basic block belongs to, or nullptr if the function does no...
#define INITIALIZE_PASS_DEPENDENCY(depName)
Type * getPointerElementType() const
const Loop * getLoop() const
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
void setIsInBounds(bool b=true)
Set or clear the inbounds flag on this GEP instruction.
bool isIntegerTy() const
True if this is an instance of IntegerType.
BlockT * getHeader() const
ConstantInt * getValue() const
Type * getType() const
All values are typed, get the type of this value.
void initializePPCLoopPreIncPrepPass(PassRegistry &)
This node represents a polynomial recurrence on the trip count of the specified loop.
bool DeleteDeadPHIs(BasicBlock *BB, const TargetLibraryInfo *TLI=nullptr)
Examine each PHI in the given block and delete it if it is dead.
This class represents a no-op cast from one type to another.
An instruction for storing to memory.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
const SCEV * getStepRecurrence(ScalarEvolution &SE) const
Constructs and returns the recurrence indicating how much this expression steps by.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
bool isVoidTy() const
Return true if this is 'void'.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs ...
static bool runOnFunction(Function &F, bool PostInlining)
initializer< Ty > init(const Ty &Val)
const Instruction * getFirstNonPHI() const
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
df_iterator< T > df_end(const T &G)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Interval::pred_iterator pred_begin(Interval *I)
pred_begin/pred_end - define methods so that Intervals may be used just like BasicBlocks can with the...
Represent the analysis usage information of a pass.
FunctionPass class - This class is used to implement most global optimizations.
Interval::pred_iterator pred_end(Interval *I)
bool isAffine() const
Return true if this represents an expression A + B*x where A and B are loop invariant values...
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
const SCEV * getStart() const
Common code between 32-bit and 64-bit PowerPC targets.
bool RecursivelyDeleteTriviallyDeadInstructions(Value *V, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr)
If the specified value is a trivially dead instruction, delete it.
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
bool isLoopInvariant(const Value *V) const
Return true if the specified value is loop invariant.
BlockT * getLoopPredecessor() const
If the given loop's header has exactly one unique predecessor outside the loop, return it...
Iterator for intrusive lists based on ilist_node.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Module.h This file contains the declarations for the Module class.
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
unsigned getNumIncomingValues() const
Return the number of incoming edges.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
df_iterator< T > df_begin(const T &G)
A range adaptor for a pair of iterators.
Class for arbitrary precision integers.
This class uses information about analyze scalars to rewrite expressions in canonical form...
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
This class represents an analyzed expression in the program.
LLVM_NODISCARD bool empty() const
Represents a single loop in the control flow graph.
APInt srem(const APInt &RHS) const
Function for signed remainder operation.
StringRef getName() const
Return a constant reference to the value's name.
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
const Function * getParent() const
Return the enclosing method, or null if none.
void insertAfter(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately after the specified instruction...
unsigned pred_size(const BasicBlock *BB)
Get the number of predecessors of BB.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
block_iterator block_end() const
iterator_range< const_phi_iterator > phis() const
Returns a range that iterates over the phis in the basic block.
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
static bool IsPtrInBounds(Value *BasePtr)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
FunctionPass * createPPCLoopPreIncPrepPass(PPCTargetMachine &TM)
LLVM Value Representation.
static const Function * getParent(const Value *V)
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"))
The legacy pass manager's analysis pass to compute loop information.
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
Legacy analysis pass which computes a DominatorTree.
bool isSafeToExpand(const SCEV *S, ScalarEvolution &SE)
Return true if the given expression is safe to expand in the sense that all materialized values are s...
block_iterator block_begin() const
static IntegerType * getInt8Ty(LLVMContext &C)
A wrapper class for inspecting calls to intrinsic functions.
const BasicBlock * getParent() const
This class represents a constant integer value.