22 #define DEBUG_TYPE "ppc-loop-preinc-prep"
61 cl::desc(
"Potential PHI threshold for PPC preinc loop prep"));
91 bool runOnLoop(
Loop *
L);
92 void simplifyLoopLatch(
Loop *
L);
93 bool rotateLoop(
Loop *
L);
106 static const char *
name =
"Prepare loop for pre-inc. addressing modes";
113 return new PPCLoopPreIncPrep(TM);
118 struct BucketElement {
128 Elements(1, BucketElement(I)) {}
130 const SCEV *BaseSCEV;
137 Value *StrippedBasePtr = BasePtr;
138 while (
BitCastInst *BC = dyn_cast<BitCastInst>(StrippedBasePtr))
139 StrippedBasePtr = BC->getOperand(0);
141 return GEP->isInBounds();
147 if (
LoadInst *LMemI = dyn_cast<LoadInst>(MemI)) {
148 return LMemI->getPointerOperand();
149 }
else if (
StoreInst *SMemI = dyn_cast<StoreInst>(MemI)) {
150 return SMemI->getPointerOperand();
151 }
else if (
IntrinsicInst *IMemI = dyn_cast<IntrinsicInst>(MemI)) {
153 return IMemI->getArgOperand(0);
159 bool PPCLoopPreIncPrep::runOnFunction(
Function &
F) {
163 LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
164 SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
165 auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>();
166 DT = DTWP ? &DTWP->getDomTree() :
nullptr;
167 PreserveLCSSA = mustPreserveAnalysisID(
LCSSAID);
169 bool MadeChange =
false;
171 for (
auto I = LI->begin(),
IE = LI->end();
I !=
IE; ++
I)
173 MadeChange |= runOnLoop(*
L);
178 bool PPCLoopPreIncPrep::runOnLoop(
Loop *
L) {
179 bool MadeChange =
false;
185 DEBUG(
dbgs() <<
"PIP: Examining: " << *L <<
"\n");
192 unsigned HeaderLoopPredCount =
204 if (
LoadInst *LMemI = dyn_cast<LoadInst>(J)) {
206 PtrValue = LMemI->getPointerOperand();
207 }
else if (
StoreInst *SMemI = dyn_cast<StoreInst>(J)) {
209 PtrValue = SMemI->getPointerOperand();
210 }
else if (
IntrinsicInst *IMemI = dyn_cast<IntrinsicInst>(J)) {
213 PtrValue = IMemI->getArgOperand(0);
229 const SCEV *LSCEV = SE->getSCEVAtScope(PtrValue, L);
230 if (
const SCEVAddRecExpr *LARSCEV = dyn_cast<SCEVAddRecExpr>(LSCEV)) {
231 if (LARSCEV->getLoop() !=
L)
237 bool FoundBucket =
false;
238 for (
auto &
B : Buckets) {
239 const SCEV *Diff = SE->getMinusSCEV(LSCEV,
B.BaseSCEV);
240 if (
const auto *CDiff = dyn_cast<SCEVConstant>(Diff)) {
241 B.Elements.push_back(BucketElement(CDiff, MemI));
250 Buckets.push_back(Bucket(LSCEV, MemI));
262 if (!LoopPredecessor ||
268 if (!LoopPredecessor)
271 DEBUG(
dbgs() <<
"PIP: Found " << Buckets.size() <<
" buckets\n");
274 for (
unsigned i = 0, e = Buckets.size();
i != e; ++
i) {
287 for (
int j = 0, je = Buckets[
i].Elements.size(); j != je; ++j) {
288 if (
auto *II = dyn_cast<IntrinsicInst>(Buckets[
i].Elements[j].Instr))
298 if (!Buckets[
i].Elements[j].
Offset ||
299 Buckets[
i].Elements[j].
Offset->isZero())
302 const SCEV *
Offset = Buckets[
i].Elements[j].Offset;
303 Buckets[
i].BaseSCEV = SE->getAddExpr(Buckets[
i].BaseSCEV, Offset);
304 for (
auto &
E : Buckets[
i].Elements) {
306 E.Offset = cast<SCEVConstant>(SE->getMinusSCEV(
E.Offset, Offset));
308 E.Offset = cast<SCEVConstant>(SE->getNegativeSCEV(Offset));
311 std::swap(Buckets[
i].Elements[j], Buckets[
i].Elements[0]);
316 cast<SCEVAddRecExpr>(Buckets[
i].BaseSCEV);
320 DEBUG(
dbgs() <<
"PIP: Transforming: " << *BasePtrSCEV <<
"\n");
322 "AddRec for the wrong loop?");
328 assert(BasePtr &&
"No pointer operand");
335 if (!SE->isLoopInvariant(BasePtrStartSCEV, L))
342 BasePtrStartSCEV = SE->getMinusSCEV(BasePtrStartSCEV, BasePtrIncSCEV);
346 DEBUG(
dbgs() <<
"PIP: New start is: " << *BasePtrStartSCEV <<
"\n");
349 MemI->hasName() ? MemI->getName() +
".phi" :
"",
353 Value *BasePtrStart = SCEVE.expandCodeFor(BasePtrStartSCEV, I8PtrTy,
360 if (*PI != LoopPredecessor)
363 NewPHI->
addIncoming(BasePtrStart, LoopPredecessor);
368 I8Ty, NewPHI, BasePtrIncSCEV->
getValue(),
369 MemI->
hasName() ? MemI->getName() +
".inc" :
"", InsPoint);
373 if (*PI == LoopPredecessor)
386 if (
Instruction *IDel = dyn_cast<Instruction>(BasePtr))
387 BBChanged.insert(IDel->getParent());
394 NewPtrs.
insert( NewBasePtr);
396 for (
auto I = std::next(Buckets[
i].Elements.begin()),
397 IE = Buckets[
i].Elements.end();
I !=
IE; ++
I) {
399 assert(Ptr &&
"No pointer operand");
400 if (NewPtrs.
count(Ptr))
404 if (!
I->Offset ||
I->Offset->getValue()->isZero()) {
405 RealNewPtr = NewBasePtr;
408 if (PtrIP && isa<Instruction>(NewBasePtr) &&
411 else if (isa<PHINode>(PtrIP))
417 I8Ty, PtrInc,
I->Offset->getValue(),
418 I->Instr->hasName() ?
I->Instr->getName() +
".off" :
"", PtrIP);
425 if (
Instruction *IDel = dyn_cast<Instruction>(Ptr))
426 BBChanged.insert(IDel->getParent());
434 ReplNewPtr = RealNewPtr;
439 NewPtrs.
insert(RealNewPtr);
447 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.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
The main scalar evolution driver.
size_type count(PtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
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...
const SCEV * getStepRecurrence(ScalarEvolution &SE) const
Constructs and returns the recurrence indicating how much this expression steps by.
const Function * getParent() const
Return the enclosing method, or null if none.
An instruction for reading from memory.
BlockT * getHeader() const
Type * getPointerElementType() const
const SCEV * getStart() const
StringRef getName() const
Return a constant reference to the value's name.
static Value * GetPointerOperand(Value *MemI)
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
const Module * getModule() const
Return the module owning the function this basic block belongs to, or nullptr it the function does no...
void setIsInBounds(bool b=true)
Set or clear the inbounds flag on this GEP instruction.
Instruction * getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
bool isLoopInvariant(const Value *V) const
Return true if the specified value is loop invariant.
void initializePPCLoopPreIncPrepPass(PassRegistry &)
This node represents a polynomial recurrence on the trip count of the specified loop.
Function Alias Analysis false
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.
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
An instruction for storing to memory.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
an instruction for type-safe pointer arithmetic to access elements of arrays and structs ...
initializer< Ty > init(const Ty &Val)
bool isAffine() const
Return true if this represents an expression A + B*x where A and B are loop invariant values...
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
bool isVectorTy() const
True if this is an instance of VectorType.
df_iterator< T > df_end(const T &G)
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.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE,"Assign register bank of generic virtual registers", false, false) RegBankSelect
FunctionPass class - This class is used to implement most global optimizations.
Interval::pred_iterator pred_end(Interval *I)
Common code between 32-bit and 64-bit PowerPC targets.
bool RecursivelyDeleteTriviallyDeadInstructions(Value *V, const TargetLibraryInfo *TLI=nullptr)
If the specified value is a trivially dead instruction, delete it.
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
static GetElementPtrInst * Create(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
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.
Type * getType() const
All values are typed, get the type of this value.
#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...
ConstantInt * getValue() const
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)
This class uses information about analyze scalars to rewrite expressions in canonical form...
std::vector< BlockT * >::const_iterator block_iterator
block_iterator block_end() const
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
This class represents an analyzed expression in the program.
Represents a single loop in the control flow graph.
void insertAfter(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately after the specified instruction...
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
BlockT * getLoopPredecessor() const
If the given loop's header has exactly one unique predecessor outside the loop, return it...
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
const Loop * getLoop() const
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)
block_iterator block_begin() const
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.
iterator getFirstInsertionPt()
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
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...
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
static IntegerType * getInt8Ty(LLVMContext &C)
const BasicBlock * getParent() const
A wrapper class for inspecting calls to intrinsic functions.
bool isVoidTy() const
Return true if this is 'void'.
This class represents a constant integer value.