95#include "llvm/IR/IntrinsicsPowerPC.h"
113#define DEBUG_TYPE "ppc-loop-instr-form-prep"
119 cl::desc(
"Potential common base number threshold per function "
120 "for PPC loop prep"));
124 cl::desc(
"prefer update form when ds form is also a update form"));
128 cl::desc(
"prepare update form when the load/store increment is a loop "
129 "invariant non-const value."));
133 cl::desc(
"Enable chain commoning in PPC loop prepare pass."));
140 cl::desc(
"Potential PHI threshold per loop for PPC loop prep of update "
145 cl::desc(
"Potential PHI threshold per loop for PPC loop prep of DS form"));
149 cl::desc(
"Potential PHI threshold per loop for PPC loop prep of DQ form"));
160 cl::desc(
"Bucket number per loop for PPC loop chain common"));
168 cl::desc(
"Minimal common base load/store instructions triggering DS/DQ form "
173 cl::desc(
"Minimal common base load/store instructions triggering chain "
174 "commoning preparation. Must be not smaller than 4"));
176STATISTIC(PHINodeAlreadyExistsUpdate,
"PHI node already in pre-increment form");
177STATISTIC(PHINodeAlreadyExistsDS,
"PHI node already in DS form");
178STATISTIC(PHINodeAlreadyExistsDQ,
"PHI node already in DQ form");
179STATISTIC(DSFormChainRewritten,
"Num of DS form chain rewritten");
180STATISTIC(DQFormChainRewritten,
"Num of DQ form chain rewritten");
181STATISTIC(UpdFormChainRewritten,
"Num of update form chain rewritten");
182STATISTIC(ChainCommoningRewritten,
"Num of commoning chains");
185 struct BucketElement {
195 : BaseSCEV(
B),
Elements(1, BucketElement(
I)) {
200 const SCEV *BaseSCEV;
218 enum PrepForm { UpdateForm = 1, DSForm = 4, DQForm = 16, ChainCommoning };
248 bool HasCandidateForPrepare;
254 unsigned SuccPrepCount;
256 bool runOnLoop(
Loop *L);
260 const SCEV *BasePtrStartSCEV,
261 const SCEV *BasePtrIncSCEV, PrepForm Form);
265 const SCEV *BasePtrIncSCEV);
271 bool prepareBasesForCommoningChains(Bucket &BucketChain);
275 rewriteLoadStoresForCommoningChains(
Loop *L, Bucket &Bucket,
284 std::function<
bool(
const SCEV *)> isValidDiff,
285 unsigned MaxCandidateNum);
291 std::function<
bool(
const SCEV *)> isValidDiff,
292 unsigned MaxCandidateNum);
307 bool prepareBaseForDispFormChain(Bucket &BucketChain, PrepForm Form);
314 bool prepareBaseForUpdateFormChain(Bucket &BucketChain);
318 bool rewriteLoadStores(
Loop *L, Bucket &BucketChain,
323 std::pair<Instruction *, Instruction *>
325 Instruction *BaseMemI,
bool CanPreInc, PrepForm Form,
331 rewriteForBucketElement(std::pair<Instruction *, Instruction *>
Base,
332 const BucketElement &Element,
Value *OffToBase,
338char PPCLoopInstrFormPrep::ID = 0;
339static const char *
name =
"Prepare loop for ppc preferred instruction forms";
351 return new PPCLoopInstrFormPrep(TM);
355 Value *StrippedBasePtr = BasePtr;
356 while (
BitCastInst *BC = dyn_cast<BitCastInst>(StrippedBasePtr))
357 StrippedBasePtr = BC->getOperand(0);
359 return GEP->isInBounds();
365 assert(
I &&
"Invalid paramater!");
367 return (
I->getName() + Suffix).str();
373 Type **PtrElementType =
nullptr) {
375 Value *PtrValue =
nullptr;
376 Type *PointerElementType =
nullptr;
378 if (
LoadInst *LMemI = dyn_cast<LoadInst>(MemI)) {
379 PtrValue = LMemI->getPointerOperand();
380 PointerElementType = LMemI->getType();
381 }
else if (
StoreInst *SMemI = dyn_cast<StoreInst>(MemI)) {
382 PtrValue = SMemI->getPointerOperand();
383 PointerElementType = SMemI->getValueOperand()->getType();
384 }
else if (
IntrinsicInst *IMemI = dyn_cast<IntrinsicInst>(MemI)) {
386 if (IMemI->getIntrinsicID() == Intrinsic::prefetch ||
387 IMemI->getIntrinsicID() == Intrinsic::ppc_vsx_lxvp) {
388 PtrValue = IMemI->getArgOperand(0);
389 }
else if (IMemI->getIntrinsicID() == Intrinsic::ppc_vsx_stxvp) {
390 PtrValue = IMemI->getArgOperand(1);
395 *PtrElementType = PointerElementType;
400bool PPCLoopInstrFormPrep::runOnFunction(
Function &
F) {
404 LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
405 SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
406 auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>();
407 DT = DTWP ? &DTWP->getDomTree() :
nullptr;
408 PreserveLCSSA = mustPreserveAnalysisID(
LCSSAID);
409 ST =
TM ?
TM->getSubtargetImpl(
F) :
nullptr;
412 bool MadeChange =
false;
416 MadeChange |= runOnLoop(L);
427bool PPCLoopInstrFormPrep::prepareBasesForCommoningChains(Bucket &CBucket) {
444 "Thredhold can not be smaller than 4!\n");
450 const SCEV *FirstOffset = CBucket.Elements[1].Offset;
455 unsigned FirstOffsetReusedCount = 1;
459 unsigned FirstOffsetReusedCountInFirstChain = 1;
461 unsigned EleNum = CBucket.Elements.size();
462 bool SawChainSeparater =
false;
463 for (
unsigned j = 2;
j != EleNum; ++
j) {
465 CBucket.Elements[j - 1].Offset) == FirstOffset) {
466 if (!SawChainSeparater)
467 FirstOffsetReusedCountInFirstChain++;
468 FirstOffsetReusedCount++;
486 SawChainSeparater =
true;
490 if (FirstOffsetReusedCount == 1)
494 FirstOffsetReusedCount / FirstOffsetReusedCountInFirstChain;
498 if (!SawChainSeparater)
499 ChainNum = (
unsigned)sqrt((
double)EleNum);
501 CBucket.ChainSize = (
unsigned)(EleNum / ChainNum);
505 if (CBucket.ChainSize * ChainNum != EleNum)
508 if (SawChainSeparater) {
510 for (
unsigned i = 1; i < CBucket.ChainSize; i++)
511 for (
unsigned j = 1;
j < ChainNum;
j++)
512 if (CBucket.Elements[i].Offset !=
513 SE->
getMinusSCEV(CBucket.Elements[i + j * CBucket.ChainSize].Offset,
514 CBucket.Elements[j * CBucket.ChainSize].Offset))
518 for (
unsigned i = 0; i < ChainNum; i++)
519 CBucket.ChainBases.push_back(CBucket.Elements[i * CBucket.ChainSize]);
526bool PPCLoopInstrFormPrep::chainCommoning(
Loop *L,
528 bool MadeChange =
false;
535 for (
auto &Bucket : Buckets) {
536 if (prepareBasesForCommoningChains(Bucket))
537 MadeChange |= rewriteLoadStoresForCommoningChains(L, Bucket, BBChanged);
541 for (
auto *BB : BBChanged)
546bool PPCLoopInstrFormPrep::rewriteLoadStoresForCommoningChains(
548 bool MadeChange =
false;
550 assert(Bucket.Elements.size() ==
551 Bucket.ChainBases.size() * Bucket.ChainSize &&
552 "invalid bucket for chain commoning!\n");
556 BasicBlock *LoopPredecessor =
L->getLoopPredecessor();
559 "loopprepare-chaincommon");
561 for (
unsigned ChainIdx = 0; ChainIdx < Bucket.ChainBases.size(); ++ChainIdx) {
562 unsigned BaseElemIdx = Bucket.ChainSize * ChainIdx;
563 const SCEV *BaseSCEV =
565 Bucket.Elements[BaseElemIdx].Offset)
567 const SCEVAddRecExpr *BasePtrSCEV = cast<SCEVAddRecExpr>(BaseSCEV);
570 if (!SCEVE.isSafeToExpand(BasePtrSCEV->
getStart()))
574 "Invalid SCEV type for the base ptr for a candidate chain!\n");
576 std::pair<Instruction *, Instruction *>
Base = rewriteForBase(
577 L, BasePtrSCEV, Bucket.Elements[BaseElemIdx].Instr,
578 false , ChainCommoning, SCEVE, DeletedPtrs);
588 for (
unsigned Idx = BaseElemIdx + 1;
Idx < BaseElemIdx + Bucket.ChainSize;
590 BucketElement &
I = Bucket.Elements[
Idx];
596 const SCEV *OffsetSCEV =
598 Bucket.Elements[BaseElemIdx].Offset)
599 : Bucket.Elements[
Idx].Offset;
604 if (!SCEVE.isSafeToExpand(OffsetSCEV))
607 Value *OffsetValue = SCEVE.expandCodeFor(
611 OffsetValue, DeletedPtrs);
613 assert(NewPtr &&
"Wrong rewrite!\n");
617 ++ChainCommoningRewritten;
624 for (
auto *
Ptr : DeletedPtrs) {
626 BBChanged.
insert(IDel->getParent());
646std::pair<Instruction *, Instruction *>
652 LLVM_DEBUG(
dbgs() <<
"PIP: Transforming: " << *BasePtrSCEV <<
"\n");
654 assert(BasePtrSCEV->
getLoop() == L &&
"AddRec for the wrong loop?");
657 assert(BasePtr &&
"No pointer operand");
661 PointerType::get(BaseMemI->
getParent()->getContext(),
662 BasePtr->getType()->getPointerAddressSpace());
664 bool IsConstantInc =
false;
666 Value *IncNode = getNodeForInc(L, BaseMemI, BasePtrIncSCEV);
669 dyn_cast<SCEVConstant>(BasePtrIncSCEV);
670 if (BasePtrIncConstantSCEV)
671 IsConstantInc =
true;
675 LLVM_DEBUG(
dbgs() <<
"Loop Increasement can not be represented!\n");
676 return std::make_pair(
nullptr,
nullptr);
682 <<
"Update form prepare for non-const increment is not enabled!\n");
683 return std::make_pair(
nullptr,
nullptr);
686 const SCEV *BasePtrStartSCEV =
nullptr;
689 "Increment is not loop invariant!\n");
691 IsConstantInc ? BasePtrIncConstantSCEV
694 BasePtrStartSCEV = BasePtrSCEV->
getStart();
696 if (alreadyPrepared(L, BaseMemI, BasePtrStartSCEV, BasePtrIncSCEV, Form)) {
698 return std::make_pair(
nullptr,
nullptr);
701 LLVM_DEBUG(
dbgs() <<
"PIP: New start is: " << *BasePtrStartSCEV <<
"\n");
704 unsigned HeaderLoopPredCount =
pred_size(Header);
705 BasicBlock *LoopPredecessor =
L->getLoopPredecessor();
717 if (PI != LoopPredecessor)
720 NewPHI->
addIncoming(BasePtrStart, LoopPredecessor);
730 cast<GetElementPtrInst>(PtrInc)->setIsInBounds(
IsPtrInBounds(BasePtr));
732 if (PI == LoopPredecessor)
747 if (PI == LoopPredecessor)
757 cast<GetElementPtrInst>(PtrInc)->setIsInBounds(
IsPtrInBounds(BasePtr));
765 Header->getFirstInsertionPt());
770 BasePtr->replaceAllUsesWith(NewBasePtr);
772 DeletedPtrs.
insert(BasePtr);
774 return std::make_pair(NewBasePtr, PtrInc);
777Instruction *PPCLoopInstrFormPrep::rewriteForBucketElement(
778 std::pair<Instruction *, Instruction *>
Base,
const BucketElement &Element,
782 assert((NewBasePtr && PtrInc) &&
"base does not exist!\n");
790 if (!Element.Offset ||
791 (isa<SCEVConstant>(Element.Offset) &&
792 cast<SCEVConstant>(Element.Offset)->getValue()->isZero())) {
793 RealNewPtr = NewBasePtr;
795 std::optional<BasicBlock::iterator> PtrIP = std::nullopt;
797 PtrIP =
I->getIterator();
799 if (PtrIP && isa<Instruction>(NewBasePtr) &&
801 PtrIP = std::nullopt;
802 else if (PtrIP && isa<PHINode>(*PtrIP))
803 PtrIP = (*PtrIP)->getParent()->getFirstInsertionPt();
805 PtrIP = Element.Instr->getIterator();
807 assert(OffToBase &&
"There should be an offset for non base element!\n");
809 I8Ty, PtrInc, OffToBase,
820 if (
Ptr->getType() != RealNewPtr->
getType()) {
825 ReplNewPtr = RealNewPtr;
827 Ptr->replaceAllUsesWith(ReplNewPtr);
833void PPCLoopInstrFormPrep::addOneCandidate(
835 std::function<
bool(
const SCEV *)> isValidDiff,
unsigned MaxCandidateNum) {
837 "Candidate should be a memory instruction.");
838 assert(LSCEV &&
"Invalid SCEV for Ptr value.");
840 bool FoundBucket =
false;
841 for (
auto &
B : Buckets) {
842 if (cast<SCEVAddRecExpr>(
B.BaseSCEV)->getStepRecurrence(*SE) !=
843 cast<SCEVAddRecExpr>(LSCEV)->getStepRecurrence(*SE))
846 if (isValidDiff(Diff)) {
847 B.Elements.push_back(BucketElement(Diff, MemI));
854 if (Buckets.size() == MaxCandidateNum) {
855 LLVM_DEBUG(
dbgs() <<
"Can not prepare more chains, reach maximum limit "
856 << MaxCandidateNum <<
"\n");
859 Buckets.push_back(Bucket(LSCEV, MemI));
867 std::function<
bool(
const SCEV *)> isValidDiff,
unsigned MaxCandidateNum) {
870 for (
const auto &BB :
L->blocks())
871 for (
auto &J : *BB) {
872 Value *PtrValue =
nullptr;
873 Type *PointerElementType =
nullptr;
882 if (
L->isLoopInvariant(PtrValue))
887 if (!LARSCEV || LARSCEV->
getLoop() != L)
891 HasCandidateForPrepare =
true;
893 if (isValidCandidate(&J, PtrValue, PointerElementType))
894 addOneCandidate(&J, LSCEV, Buckets, isValidDiff, MaxCandidateNum);
899bool PPCLoopInstrFormPrep::prepareBaseForDispFormChain(Bucket &BucketChain,
909 for (
unsigned j = 0, je = BucketChain.Elements.size(); j != je; ++j) {
910 if (!BucketChain.Elements[j].Offset)
911 RemainderOffsetInfo[0] = std::make_pair(0, 1);
913 unsigned Remainder = cast<SCEVConstant>(BucketChain.Elements[j].Offset)
916 if (!RemainderOffsetInfo.
contains(Remainder))
917 RemainderOffsetInfo[Remainder] = std::make_pair(j, 1);
919 RemainderOffsetInfo[Remainder].second++;
937 unsigned MaxCountRemainder = 0;
939 if ((RemainderOffsetInfo.
contains(j)) &&
940 RemainderOffsetInfo[
j].second >
941 RemainderOffsetInfo[MaxCountRemainder].second)
942 MaxCountRemainder = j;
950 if (MaxCountRemainder == 0)
955 BucketChain.Elements[RemainderOffsetInfo[MaxCountRemainder].first].Offset;
957 for (
auto &E : BucketChain.Elements) {
964 std::swap(BucketChain.Elements[RemainderOffsetInfo[MaxCountRemainder].first],
965 BucketChain.Elements[0]);
975bool PPCLoopInstrFormPrep::prepareBaseForUpdateFormChain(Bucket &BucketChain) {
985 for (
int j = 0, je = BucketChain.Elements.size(); j != je; ++j) {
986 if (
auto *
II = dyn_cast<IntrinsicInst>(BucketChain.Elements[j].Instr))
987 if (
II->getIntrinsicID() == Intrinsic::prefetch)
996 if (!BucketChain.Elements[j].Offset ||
997 cast<SCEVConstant>(BucketChain.Elements[j].Offset)->isZero())
1000 const SCEV *
Offset = BucketChain.Elements[
j].Offset;
1002 for (
auto &E : BucketChain.Elements) {
1009 std::swap(BucketChain.Elements[j], BucketChain.Elements[0]);
1015bool PPCLoopInstrFormPrep::rewriteLoadStores(
1018 bool MadeChange =
false;
1021 cast<SCEVAddRecExpr>(BucketChain.BaseSCEV);
1027 "loopprepare-formrewrite");
1036 bool CanPreInc = (
Form == UpdateForm ||
1037 ((
Form == DSForm) &&
1044 std::pair<Instruction *, Instruction *>
Base =
1045 rewriteForBase(L, BasePtrSCEV, BucketChain.Elements.begin()->Instr,
1046 CanPreInc, Form, SCEVE, DeletedPtrs);
1064 BE.Offset ? cast<SCEVConstant>(BE.Offset)->getValue() :
nullptr,
1066 assert(NewPtr &&
"wrong rewrite!\n");
1074 for (
auto *
Ptr : DeletedPtrs) {
1076 BBChanged.
insert(IDel->getParent());
1084 if (Form == DSForm && !CanPreInc)
1085 DSFormChainRewritten++;
1086 else if (Form == DQForm)
1087 DQFormChainRewritten++;
1088 else if (Form == UpdateForm || (Form == DSForm && CanPreInc))
1089 UpdFormChainRewritten++;
1094bool PPCLoopInstrFormPrep::updateFormPrep(
Loop *L,
1096 bool MadeChange =
false;
1097 if (Buckets.
empty())
1100 for (
auto &Bucket : Buckets)
1103 if (prepareBaseForUpdateFormChain(Bucket))
1104 MadeChange |= rewriteLoadStores(L, Bucket, BBChanged, UpdateForm);
1107 for (
auto *BB : BBChanged)
1112bool PPCLoopInstrFormPrep::dispFormPrep(
Loop *L,
1115 bool MadeChange =
false;
1117 if (Buckets.
empty())
1121 for (
auto &Bucket : Buckets) {
1124 if (prepareBaseForDispFormChain(Bucket, Form))
1125 MadeChange |= rewriteLoadStores(L, Bucket, BBChanged, Form);
1129 for (
auto *BB : BBChanged)
1143 const SCEV *BasePtrIncSCEV) {
1146 if (isa<SCEVConstant>(BasePtrIncSCEV))
1147 return cast<SCEVConstant>(BasePtrIncSCEV)->getValue();
1164 for (
auto &CurrentPHI : PHIIter) {
1165 PHINode *CurrentPHINode = dyn_cast<PHINode>(&CurrentPHI);
1166 if (!CurrentPHINode)
1174 const SCEVAddRecExpr *PHIBasePtrSCEV = dyn_cast<SCEVAddRecExpr>(PHISCEV);
1175 if (!PHIBasePtrSCEV)
1180 if (!PHIBasePtrIncSCEV || (PHIBasePtrIncSCEV != BasePtrIncSCEV))
1189 Value *StrippedBaseI =
I;
1190 while (
BitCastInst *BC = dyn_cast<BitCastInst>(StrippedBaseI))
1191 StrippedBaseI = BC->getOperand(0);
1193 Instruction *StrippedI = dyn_cast<Instruction>(StrippedBaseI);
1199 if (StrippedI->
getOpcode() == Instruction::Add ||
1200 (StrippedI->
getOpcode() == Instruction::GetElementPtr &&
1217 const SCEV *BasePtrStartSCEV,
1218 const SCEV *BasePtrIncSCEV,
1227 if (!PredBB || !LatchBB)
1232 for (
auto & CurrentPHI : PHIIter) {
1233 PHINode *CurrentPHINode = dyn_cast<PHINode>(&CurrentPHI);
1234 if (!CurrentPHINode)
1242 const SCEVAddRecExpr *PHIBasePtrSCEV = dyn_cast<SCEVAddRecExpr>(PHISCEV);
1243 if (!PHIBasePtrSCEV)
1248 if (!PHIBasePtrIncSCEV)
1256 if (PHIBasePtrIncSCEV == BasePtrIncSCEV) {
1259 if ((Form == UpdateForm || Form == ChainCommoning ) &&
1260 PHIBasePtrSCEV->
getStart() == BasePtrStartSCEV) {
1261 ++PHINodeAlreadyExistsUpdate;
1264 if (Form == DSForm || Form == DQForm) {
1269 ++PHINodeAlreadyExistsDS;
1271 ++PHINodeAlreadyExistsDQ;
1282bool PPCLoopInstrFormPrep::runOnLoop(
Loop *L) {
1283 bool MadeChange =
false;
1286 if (!
L->isInnermost())
1295 BasicBlock *LoopPredecessor =
L->getLoopPredecessor();
1299 if (!LoopPredecessor ||
1302 if (LoopPredecessor)
1305 if (!LoopPredecessor) {
1306 LLVM_DEBUG(
dbgs() <<
"PIP fails since no predecessor for current loop.\n");
1312 const Type *PointerElementType) {
1313 assert((PtrValue &&
I) &&
"Invalid parameter!");
1315 if (ST &&
ST->hasAltivec() && PointerElementType->
isVectorTy())
1318 auto *
II = dyn_cast<IntrinsicInst>(
I);
1319 if (
II && ((
II->getIntrinsicID() == Intrinsic::ppc_vsx_lxvp) ||
1320 II->getIntrinsicID() == Intrinsic::ppc_vsx_stxvp))
1330 if (!LARSCEV || LARSCEV->
getLoop() != L)
1334 const APInt &ConstInt = StepConst->getValue()->getValue();
1344 const Type *PointerElementType) {
1345 assert((PtrValue &&
I) &&
"Invalid parameter!");
1346 if (isa<IntrinsicInst>(
I))
1353 [](
const User *U) { return isa<SExtInst>(U); }));
1358 const Type *PointerElementType) {
1359 assert((PtrValue &&
I) &&
"Invalid parameter!");
1361 auto *
II = dyn_cast<IntrinsicInst>(
I);
1363 return II->getIntrinsicID() == Intrinsic::ppc_vsx_lxvp ||
1364 II->getIntrinsicID() == Intrinsic::ppc_vsx_stxvp;
1366 return ST &&
ST->hasP9Vector() && (PointerElementType->
isVectorTy());
1373 const Type *PointerElementType) {
1385 if (isa<SCEVUnknown>(Start) && Start->getType()->isPointerTy())
1388 const SCEVAddExpr *ASCEV = dyn_cast<SCEVAddExpr>(Start);
1396 bool SawPointer =
false;
1398 if (
Op->getType()->isPointerTy()) {
1402 }
else if (!
Op->getType()->isIntegerTy())
1411 auto isValidConstantDiff = [](
const SCEV *Diff) {
1412 return dyn_cast<SCEVConstant>(Diff) !=
nullptr;
1417 auto isValidChainCommoningDiff = [](
const SCEV *Diff) {
1418 assert(Diff &&
"Invalid Diff!\n");
1421 if (isa<SCEVConstant>(Diff))
1428 const SCEVNAryExpr *ADiff = dyn_cast<SCEVNAryExpr>(Diff);
1433 if (!
Op->getType()->isIntegerTy())
1439 HasCandidateForPrepare =
false;
1448 if (!UpdateFormBuckets.
empty())
1449 MadeChange |= updateFormPrep(L, UpdateFormBuckets);
1450 else if (!HasCandidateForPrepare) {
1453 <<
"No prepare candidates found, stop praparation for current loop!\n");
1465 if (!DSFormBuckets.
empty())
1466 MadeChange |= dispFormPrep(L, DSFormBuckets, DSForm);
1475 if (!DQFormBuckets.
empty())
1476 MadeChange |= dispFormPrep(L, DQFormBuckets, DQForm);
1488 collectCandidates(L, isChainCommoningCandidate, isValidChainCommoningDiff,
1492 if (!Buckets.
empty())
1493 MadeChange |= chainCommoning(L, Buckets);
static const Function * getParent(const Value *V)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
uint64_t IntrinsicInst * II
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallPtrSet class.
This file defines the SmallSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Class for arbitrary precision integers.
APInt urem(const APInt &RHS) const
Unsigned remainder operation.
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
APInt srem(const APInt &RHS) const
Function for signed remainder operation.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM Basic Block Representation.
iterator_range< const_phi_iterator > phis() const
Returns a range that iterates over the phis in the basic block.
InstListType::iterator iterator
Instruction iterators...
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...
This class represents a no-op cast from one type to another.
This class represents an Operation in the Expression.
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
Legacy analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
FunctionPass class - This class is used to implement most global optimizations.
virtual bool runOnFunction(Function &F)=0
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
static GetElementPtrInst * Create(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
void setIsInBounds(bool b=true)
Set or clear the inbounds flag on this GEP instruction.
Module * getParent()
Get the module that this global value is contained inside of...
void insertBefore(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified instruction.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
void insertAfter(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately after the specified instruction.
A wrapper class for inspecting calls to intrinsic functions.
An instruction for reading from memory.
The legacy pass manager's analysis pass to compute loop information.
Represents a single loop in the control flow graph.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
Value * getIncomingValueForBlock(const BasicBlock *BB) const
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
int getBasicBlockIndex(const BasicBlock *BB) const
Return the first index of the specified basic block in the value list for this PHI.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
Common code between 32-bit and 64-bit PowerPC targets.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
This node represents an addition of some number of SCEVs.
This node represents a polynomial recurrence on the trip count of the specified loop.
const SCEV * getStart() const
const SCEV * getStepRecurrence(ScalarEvolution &SE) const
Constructs and returns the recurrence indicating how much this expression steps by.
bool isAffine() const
Return true if this represents an expression A + B*x where A and B are loop invariant values.
const Loop * getLoop() const
This class represents a constant integer value.
const APInt & getAPInt() const
This class uses information about analyze scalars to rewrite expressions in canonical form.
bool isSafeToExpand(const SCEV *S) const
Return true if the given expression is safe to expand in the sense that all materialized values are s...
void clear()
Erase the contents of the InsertedExpressions map so that users trying to expand the same expression ...
Value * expandCodeFor(const SCEV *SH, Type *Ty, BasicBlock::iterator I)
Insert code to directly compute the specified SCEV expression into the program.
This node is a base class providing common functionality for n'ary operators.
ArrayRef< const SCEV * > operands() const
This class represents an analyzed expression in the program.
Type * getType() const
Return the LLVM type of this SCEV expression.
The main scalar evolution driver.
const SCEV * getNegativeSCEV(const SCEV *V, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap)
Return the SCEV object corresponding to -V.
const SCEV * getSCEVAtScope(const SCEV *S, const Loop *L)
Return a SCEV expression for the specified value at the specified scope in the program.
bool isLoopInvariant(const SCEV *S, const Loop *L)
Return true if the value of the given SCEV is unchanging in the specified loop.
bool isSCEVable(Type *Ty) const
Test if values of the given type are analyzable within the SCEV framework.
const SCEV * getMinusSCEV(const SCEV *LHS, const SCEV *RHS, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Return LHS-RHS.
const SCEV * getAddExpr(SmallVectorImpl< const SCEV * > &Ops, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Get a canonical add expression, or something simpler if possible.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
StringRef - Represent a constant reference to a string, i.e.
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.
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
static IntegerType * getInt8Ty(LLVMContext &C)
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
bool isVoidTy() const
Return true if this is 'void'.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVMContext & getContext() const
All values hold a context through their type.
const ParentTy * getParent() const
self_iterator getIterator()
A range adaptor for a pair of iterators.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
initializer< Ty > init(const Ty &Val)
NodeAddr< InstrNode * > Instr
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
BasicBlock * InsertPreheaderForLoop(Loop *L, DominatorTree *DT, LoopInfo *LI, MemorySSAUpdater *MSSAU, bool PreserveLCSSA)
InsertPreheaderForLoop - Once we discover that a loop doesn't have a preheader, this method is called...
bool RecursivelyDeleteTriviallyDeadInstructions(Value *V, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr, std::function< void(Value *)> AboutToDeleteCallback=std::function< void(Value *)>())
If the specified value is a trivially dead instruction, delete it.
FunctionPass * createPPCLoopInstrFormPrepPass(PPCTargetMachine &TM)
auto pred_size(const MachineBasicBlock *BB)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
bool DeleteDeadPHIs(BasicBlock *BB, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Examine each PHI in the given block and delete it if it is dead.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto predecessors(const MachineBasicBlock *BB)
iterator_range< df_iterator< T > > depth_first(const T &G)
void initializePPCLoopInstrFormPrepPass(PassRegistry &)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.