66#define DEBUG_TYPE "guard-widening"
68STATISTIC(GuardsEliminated,
"Number of eliminated guards");
69STATISTIC(CondBranchEliminated,
"Number of eliminated conditional branches");
70STATISTIC(FreezeAdded,
"Number of freeze instruction introduced");
75 assert(GI->getIntrinsicID() == Intrinsic::experimental_guard &&
76 "Bad guard intrinsic?");
77 return GI->getArgOperand(0);
91 assert(GI->getIntrinsicID() == Intrinsic::experimental_guard &&
92 "Bad guard intrinsic?");
93 GI->setArgOperand(0, NewCond);
116static std::optional<BasicBlock::iterator>
127class GuardWideningImpl {
128 const ScalarOptions &Opts;
130 PostDominatorTree *PDT;
133 MemorySSAUpdater *MSSAU;
138 std::function<bool(BasicBlock*)> BlockFilter;
142 SmallVector<Instruction *, 16> EliminatedGuardsAndBranches;
146 DenseSet<Instruction *> WidenedGuards;
152 bool eliminateInstrViaWidening(
153 Instruction *Instr,
const df_iterator<DomTreeNode *> &DFSI,
154 const DenseMap<BasicBlock *, SmallVector<Instruction *, 8>>
160 WS_IllegalOrNegative,
175 static StringRef scoreTypeToString(WideningScore WS);
179 WideningScore computeWideningScore(Instruction *DominatedInstr,
180 Instruction *ToWiden,
182 SmallVectorImpl<Value *> &ChecksToHoist,
183 SmallVectorImpl<Value *> &ChecksToWiden);
187 SmallPtrSet<const Instruction *, 8> Visited;
188 return canBeHoistedTo(V, InsertPos, Visited);
192 SmallPtrSetImpl<const Instruction *> &Visited)
const;
194 bool canBeHoistedTo(
const SmallVectorImpl<Value *> &Checks,
197 [&](
const Value *V) {
return canBeHoistedTo(V, InsertPos); });
203 void makeAvailableAt(
const SmallVectorImpl<Value *> &Checks,
205 for (
Value *V : Checks)
206 makeAvailableAt(V, InsertPos);
216 std::optional<Value *>
217 mergeChecks(SmallVectorImpl<Value *> &ChecksToHoist,
218 SmallVectorImpl<Value *> &ChecksToWiden,
219 std::optional<BasicBlock::iterator> InsertPt);
223 Value *hoistChecks(SmallVectorImpl<Value *> &ChecksToHoist,
236 const ConstantInt *Offset;
241 explicit RangeCheck(
const Value *Base,
const ConstantInt *Offset,
242 const Value *Length, ICmpInst *CheckInst)
243 : Base(Base), Offset(Offset), Length(Length), CheckInst(CheckInst) {}
245 void setBase(
const Value *NewBase) { Base = NewBase; }
246 void setOffset(
const ConstantInt *NewOffset) { Offset = NewOffset; }
248 const Value *getBase()
const {
return Base; }
249 const ConstantInt *
getOffset()
const {
return Offset; }
250 const APInt &getOffsetValue()
const {
return getOffset()->getValue(); }
251 const Value *getLength()
const {
return Length; };
252 ICmpInst *getCheckInst()
const {
return CheckInst; }
254 void print(raw_ostream &OS,
bool PrintTypes =
false) {
256 Base->printAsOperand(OS, PrintTypes);
258 Offset->printAsOperand(OS, PrintTypes);
260 Length->printAsOperand(OS, PrintTypes);
272 bool parseRangeChecks(SmallVectorImpl<Value *> &ToParse,
273 SmallVectorImpl<RangeCheck> &Checks) {
274 for (
auto CheckCond : ToParse) {
275 if (!parseRangeChecks(CheckCond, Checks))
281 bool parseRangeChecks(
Value *CheckCond, SmallVectorImpl<RangeCheck> &Checks);
287 bool combineRangeChecks(SmallVectorImpl<RangeCheck> &Checks,
288 SmallVectorImpl<RangeCheck> &CombinedChecks)
const;
292 bool isWideningCondProfitable(SmallVectorImpl<Value *> &ChecksToHoist,
293 SmallVectorImpl<Value *> &ChecksToWiden) {
294 return mergeChecks(ChecksToHoist, ChecksToWiden, std::nullopt)
299 void widenGuard(SmallVectorImpl<Value *> &ChecksToHoist,
300 SmallVectorImpl<Value *> &ChecksToWiden,
301 Instruction *ToWiden) {
303 auto MergedCheck = mergeChecks(ChecksToHoist, ChecksToWiden, InsertPt);
305 : hoistChecks(ChecksToHoist,
316 explicit GuardWideningImpl(
const ScalarOptions &Opts, DominatorTree &DT,
317 PostDominatorTree *PDT, LoopInfo &LI,
318 AssumptionCache &AC, MemorySSAUpdater *MSSAU,
320 std::function<
bool(BasicBlock *)> BlockFilter)
321 : Opts(Opts), DT(DT), PDT(PDT), LI(LI), AC(AC), MSSAU(MSSAU), Root(Root),
322 BlockFilter(BlockFilter) {}
338bool GuardWideningImpl::run() {
339 DenseMap<BasicBlock *, SmallVector<Instruction *, 8>> GuardsInBlock;
343 auto *BB = (*DFI)->getBlock();
344 if (!BlockFilter(BB))
347 auto &CurrentList = GuardsInBlock[BB];
353 for (
auto *
II : CurrentList)
354 Changed |= eliminateInstrViaWidening(
II, DFI, GuardsInBlock);
358 for (
auto *
I : EliminatedGuardsAndBranches)
359 if (!WidenedGuards.
count(
I)) {
365 "Eliminated something other than guard or branch?");
366 ++CondBranchEliminated;
373bool GuardWideningImpl::eliminateInstrViaWidening(
374 Instruction *Instr,
const df_iterator<DomTreeNode *> &DFSI,
375 const DenseMap<BasicBlock *, SmallVector<Instruction *, 8>>
382 if (ChecksToHoist.
empty() ||
387 auto BestScoreSoFar = WS_IllegalOrNegative;
391 for (
unsigned i = 0, e = DFSI.
getPathLength(); i != e; ++i) {
392 auto *CurBB = DFSI.
getPath(i)->getBlock();
393 if (!BlockFilter(CurBB))
395 assert(GuardsInBlock.
count(CurBB) &&
"Must have been populated by now!");
396 const auto &GuardsInCurBB = GuardsInBlock.
find(CurBB)->second;
398 auto I = GuardsInCurBB.begin();
399 auto E =
Instr->getParent() == CurBB ?
find(GuardsInCurBB, Instr)
400 : GuardsInCurBB.
end();
405 for (
auto &
I : *CurBB) {
406 if (Index == GuardsInCurBB.size())
408 if (GuardsInCurBB[Index] == &
I)
411 assert(Index == GuardsInCurBB.size() &&
412 "Guards expected to be in order!");
416 assert((i == (e - 1)) == (
Instr->getParent() == CurBB) &&
"Bad DFS?");
424 auto Score = computeWideningScore(Instr, Candidate, *WideningPoint,
425 ChecksToHoist, CandidateChecks);
426 LLVM_DEBUG(
dbgs() <<
"Score between " << *Instr <<
" and " << *Candidate
427 <<
" is " << scoreTypeToString(Score) <<
"\n");
428 if (Score > BestScoreSoFar) {
429 BestScoreSoFar = Score;
430 BestSoFar = Candidate;
435 if (BestScoreSoFar == WS_IllegalOrNegative) {
436 LLVM_DEBUG(
dbgs() <<
"Did not eliminate guard " << *Instr <<
"\n");
440 assert(BestSoFar != Instr &&
"Should have never visited same guard!");
443 LLVM_DEBUG(
dbgs() <<
"Widening " << *Instr <<
" into " << *BestSoFar
444 <<
" with score " << scoreTypeToString(BestScoreSoFar)
448 widenGuard(ChecksToHoist, ChecksToWiden, BestSoFar);
451 EliminatedGuardsAndBranches.push_back(Instr);
452 WidenedGuards.
insert(BestSoFar);
456GuardWideningImpl::WideningScore GuardWideningImpl::computeWideningScore(
457 Instruction *DominatedInstr, Instruction *ToWiden,
459 SmallVectorImpl<Value *> &ChecksToWiden) {
461 Loop *DominatingGuardLoop = LI.
getLoopFor(WideningPoint->getParent());
462 bool HoistingOutOfLoop =
false;
464 if (DominatingGuardLoop != DominatedInstrLoop) {
467 if (DominatingGuardLoop &&
468 !DominatingGuardLoop->
contains(DominatedInstrLoop))
469 return WS_IllegalOrNegative;
471 HoistingOutOfLoop =
true;
474 if (!canBeHoistedTo(ChecksToHoist, WideningPoint))
475 return WS_IllegalOrNegative;
479 if (!canBeHoistedTo(
getCondition(ToWiden), WideningPoint))
480 return WS_IllegalOrNegative;
490 if (isWideningCondProfitable(ChecksToHoist, ChecksToWiden))
491 return HoistingOutOfLoop ? WS_VeryPositive : WS_Positive;
493 if (HoistingOutOfLoop)
498 auto GetLikelySuccessor = [](
const BasicBlock * BB)->
const BasicBlock * {
499 if (
auto *UniqueSucc = BB->getUniqueSuccessor())
501 auto *
Term = BB->getTerminator();
503 const BasicBlock *IfTrue =
nullptr, *IfFalse =
nullptr;
504 using namespace PatternMatch;
510 return ConstCond->isAllOnesValue() ? IfTrue : IfFalse;
512 if (IfFalse->getPostdominatingDeoptimizeCall())
525 auto MaybeHoistingToHotterBlock = [&]() {
526 const auto *DominatingBlock = WideningPoint->getParent();
527 const auto *DominatedBlock = DominatedInstr->
getParent();
532 assert(DT.
dominates(DominatingBlock, DominatedBlock) &&
"No dominance");
533 while (DominatedBlock != DominatingBlock) {
534 auto *LikelySucc = GetLikelySuccessor(DominatingBlock);
541 DominatingBlock = LikelySucc;
545 if (DominatedBlock == DominatingBlock)
549 if (!DT.
dominates(DominatingBlock, DominatedBlock))
554 return !PDT->
dominates(DominatedBlock, DominatingBlock);
557 return MaybeHoistingToHotterBlock() ? WS_IllegalOrNegative : WS_Neutral;
560bool GuardWideningImpl::canBeHoistedTo(
562 SmallPtrSetImpl<const Instruction *> &Visited)
const {
568 Inst->mayReadFromMemory())
575 "PHIs should return false for isSafeToSpeculativelyExecute");
577 "We did a DFS from the block entry!");
578 return all_of(Inst->operands(),
579 [&](
Value *
Op) { return canBeHoistedTo(Op, Loc, Visited); });
582void GuardWideningImpl::makeAvailableAt(
Value *V,
589 !Inst->mayReadFromMemory() &&
590 "Should've checked with canBeHoistedTo!");
592 for (
Value *
Op : Inst->operands())
593 makeAvailableAt(
Op, Loc);
595 Inst->moveBefore(*Loc->getParent(), Loc);
600static std::optional<BasicBlock::iterator>
606 std::optional<BasicBlock::iterator> Res =
I->getInsertionPointAfterDef();
616 Instruction *User = cast<Instruction>(U);
617 return ResInst != User && DT.dominates(I, User) &&
618 !DT.dominates(ResInst, User);
624Value *GuardWideningImpl::freezeAndPush(
Value *Orig,
628 std::optional<BasicBlock::iterator> InsertPtAtDef =
630 if (!InsertPtAtDef) {
631 FreezeInst *FI =
new FreezeInst(Orig,
"gw.freeze");
637 FreezeInst *FI =
new FreezeInst(Orig,
"gw.freeze");
642 SmallPtrSet<Value *, 16> Visited;
643 SmallVector<Value *, 16> Worklist;
644 SmallPtrSet<Instruction *, 16> DropPoisonFlags;
645 SmallVector<Value *, 16> NeedFreeze;
646 DenseMap<Value *, FreezeInst *> CacheOfFreezes;
651 auto handleConstantOrGlobal = [&](
Use &
U) {
656 if (Visited.
insert(Def).second) {
660 FreezeInst *FI =
new FreezeInst(Def,
Def->getName() +
".gw.fr");
662 CacheOfFreezes[
Def] = FI;
665 if (
auto It = CacheOfFreezes.
find(Def); It != CacheOfFreezes.
end())
671 while (!Worklist.
empty()) {
673 if (!Visited.
insert(V).second)
688 return isa<Instruction>(Op) && !getFreezeInsertPt(Op, DT);
694 for (Use &U :
I->operands())
695 if (!handleConstantOrGlobal(U))
698 for (Instruction *
I : DropPoisonFlags)
699 I->dropPoisonGeneratingAnnotations();
702 for (
Value *V : NeedFreeze) {
704 FreezeInst *FI =
new FreezeInst(V,
V->getName() +
".gw.fr");
705 FI->
insertBefore(*FreezeInsertPt->getParent(), FreezeInsertPt);
709 V->replaceUsesWithIf(
710 FI, [&](
const Use & U)->
bool {
return U.getUser() != FI; });
716std::optional<Value *>
717GuardWideningImpl::mergeChecks(SmallVectorImpl<Value *> &ChecksToHoist,
718 SmallVectorImpl<Value *> &ChecksToWiden,
719 std::optional<BasicBlock::iterator> InsertPt) {
720 using namespace llvm::PatternMatch;
725 ConstantInt *RHS0, *RHS1;
727 CmpPredicate Pred0, Pred1;
730 if (ChecksToWiden.
size() == 1 && ChecksToHoist.
size() == 1 &&
744 if (std::optional<ConstantRange> Intersect =
748 if (Intersect->getEquivalentICmp(Pred, NewRHSAP)) {
750 ConstantInt *NewRHS =
751 ConstantInt::get((*InsertPt)->getContext(), NewRHSAP);
752 assert(canBeHoistedTo(
LHS, *InsertPt) &&
"must be");
753 makeAvailableAt(
LHS, *InsertPt);
754 Result =
new ICmpInst(*InsertPt, Pred,
LHS, NewRHS,
"wide.chk");
764 if (parseRangeChecks(ChecksToWiden, Checks) &&
765 parseRangeChecks(ChecksToHoist, Checks) &&
766 combineRangeChecks(Checks, CombinedChecks)) {
768 for (
auto &RC : CombinedChecks) {
769 makeAvailableAt(RC.getCheckInst(), *InsertPt);
771 Result = BinaryOperator::CreateAnd(RC.getCheckInst(), Result,
"",
774 Result = RC.getCheckInst();
776 assert(Result &&
"Failed to find result value");
777 Result->setName(
"wide.chk");
778 Result = freezeAndPush(Result, *InsertPt);
788Value *GuardWideningImpl::hoistChecks(SmallVectorImpl<Value *> &ChecksToHoist,
793 makeAvailableAt(ChecksToHoist, InsertPt);
794 makeAvailableAt(OldCondition, InsertPt);
796 Result = freezeAndPush(Result, InsertPt);
797 Result = Builder.CreateAnd(OldCondition, Result);
798 Result->setName(
"wide.chk");
802bool GuardWideningImpl::parseRangeChecks(
803 Value *CheckCond, SmallVectorImpl<GuardWideningImpl::RangeCheck> &Checks) {
804 using namespace llvm::PatternMatch;
807 if (!IC || !IC->getOperand(0)->getType()->isIntegerTy() ||
808 (IC->getPredicate() != ICmpInst::ICMP_ULT &&
809 IC->getPredicate() != ICmpInst::ICMP_UGT))
812 const Value *CmpLHS = IC->getOperand(0), *CmpRHS = IC->getOperand(1);
813 if (IC->getPredicate() == ICmpInst::ICMP_UGT)
816 auto &
DL = IC->getDataLayout();
818 GuardWideningImpl::RangeCheck
Check(
839 "Unreachable instruction?");
843 Check.setBase(OpLHS);
844 APInt NewOffset =
Check.getOffsetValue() + OpRHS->
getValue();
845 Check.setOffset(ConstantInt::get(Ctx, NewOffset));
851 Check.setBase(OpLHS);
852 APInt NewOffset =
Check.getOffsetValue() + OpRHS->
getValue();
853 Check.setOffset(ConstantInt::get(Ctx, NewOffset));
863bool GuardWideningImpl::combineRangeChecks(
864 SmallVectorImpl<GuardWideningImpl::RangeCheck> &Checks,
865 SmallVectorImpl<GuardWideningImpl::RangeCheck> &RangeChecksOut)
const {
866 unsigned OldCount = Checks.
size();
867 while (!Checks.
empty()) {
870 const Value *CurrentBase = Checks.
front().getBase();
871 const Value *CurrentLength = Checks.
front().getLength();
875 auto IsCurrentCheck = [&](GuardWideningImpl::RangeCheck &RC) {
876 return RC.getBase() == CurrentBase && RC.getLength() == CurrentLength;
879 copy_if(Checks, std::back_inserter(CurrentChecks), IsCurrentCheck);
882 assert(CurrentChecks.
size() != 0 &&
"We know we have at least one!");
884 if (CurrentChecks.
size() < 3) {
892 llvm::sort(CurrentChecks, [&](
const GuardWideningImpl::RangeCheck &
LHS,
893 const GuardWideningImpl::RangeCheck &
RHS) {
894 return LHS.getOffsetValue().slt(
RHS.getOffsetValue());
899 const ConstantInt *MinOffset = CurrentChecks.
front().getOffset();
900 const ConstantInt *MaxOffset = CurrentChecks.
back().getOffset();
903 if ((MaxOffset->
getValue() - MinOffset->getValue())
907 APInt MaxDiff = MaxOffset->
getValue() - MinOffset->getValue();
908 const APInt &HighOffset = MaxOffset->
getValue();
909 auto OffsetOK = [&](
const GuardWideningImpl::RangeCheck &RC) {
910 return (HighOffset - RC.getOffsetValue()).ult(MaxDiff);
955 assert(RangeChecksOut.
size() <= OldCount &&
"We pessimized!");
956 return RangeChecksOut.
size() != OldCount;
960StringRef GuardWideningImpl::scoreTypeToString(WideningScore WS) {
962 case WS_IllegalOrNegative:
963 return "IllegalOrNegative";
968 case WS_VeryPositive:
969 return "VeryPositive";
980 F.getParent(), Intrinsic::experimental_guard);
981 bool HasIntrinsicGuards = GuardDecl && !GuardDecl->use_empty();
983 F.getParent(), Intrinsic::experimental_widenable_condition);
984 bool HasWidenableConditions = WCDecl && !WCDecl->use_empty();
985 if (!HasIntrinsicGuards && !HasWidenableConditions)
992 std::unique_ptr<MemorySSAUpdater> MSSAU;
994 MSSAU = std::make_unique<MemorySSAUpdater>(&MSSAA->getMSSA());
995 const ScalarOptions &Opts =
996 F.getContext().getLibraryOptions().get<ScalarOptions>();
997 if (!GuardWideningImpl(Opts, DT, &PDT, LI, AC, MSSAU ? MSSAU.get() :
nullptr,
1013 RootBB = L.getHeader();
1015 return BB == RootBB || L.contains(BB);
1017 std::unique_ptr<MemorySSAUpdater> MSSAU;
1019 MSSAU = std::make_unique<MemorySSAUpdater>(AR.
MSSA);
1020 const ScalarOptions &Opts =
1021 L.getHeader()->getContext().getLibraryOptions().get<ScalarOptions>();
1022 if (!GuardWideningImpl(Opts, AR.
DT,
nullptr, AR.
LI, AR.
AC,
1023 MSSAU ? MSSAU.get() :
nullptr, AR.
DT.
getNode(RootBB),
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
This file defines the DenseMap class.
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
static bool isSupportedGuardInstruction(const ScalarOptions &Opts, const Instruction *Insn)
static void eliminateGuard(Instruction *GuardInst, MemorySSAUpdater *MSSAU)
static std::optional< BasicBlock::iterator > findInsertionPointForWideCondition(Instruction *WCOrGuard)
Find a point at which the widened condition of Guard should be inserted.
static Value * getCondition(Instruction *I)
static void setCondition(Instruction *I, Value *NewCond)
static std::optional< BasicBlock::iterator > getFreezeInsertPt(Value *V, const DominatorTree &DT)
uint64_t IntrinsicInst * II
const SmallVectorImpl< MachineOperand > & Cond
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
unsigned getBitWidth() const
Return the number of bits in the APInt.
bool isMinValue() const
Determine if this is the smallest unsigned value.
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
A function analysis which provides an AssumptionCache.
LLVM Basic Block Representation.
InstListType::iterator iterator
Instruction iterators...
LLVM_ABI const_iterator getFirstNonPHIOrAlloca() const
Returns an iterator to the first instruction in this block that is not a PHINode, a static alloca,...
LLVM_ABI const CallInst * getPostdominatingDeoptimizeCall() const
Returns the call instruction calling @llvm.experimental.deoptimize that is present either in current ...
Represents analyses that only rely on functions' control flow.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
const APInt & getValue() const
Return the constant as an APInt value reference.
static LLVM_ABI ConstantRange makeExactICmpRegion(CmpInst::Predicate Pred, const APInt &Other)
Produce the exact range such that all values in the returned range satisfy the given predicate with a...
LLVM_ABI std::optional< ConstantRange > exactIntersectWith(const ConstantRange &CR) const
Intersect the two ranges and return the result if it can be represented exactly, otherwise return std...
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
iterator find(const_arg_type_t< KeyT > Val)
Analysis pass which computes a DominatorTree.
DomTreeNodeBase< NodeT > * getRootNode()
getRootNode - This returns the entry node for the CFG of the function.
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
bool properlyDominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
properlyDominates - Returns true iff A dominates B and A != B.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
LLVM_ABI bool isReachableFromEntry(const Use &U) const
Provide an overload for a Use.
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
LLVM_ABI void insertBefore(InstListType::iterator InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified position.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
A wrapper class for inspecting calls to intrinsic functions.
This class provides an interface for updating the loop pass manager based on mutations to the loop ne...
Analysis pass that exposes the LoopInfo for a function.
bool contains(const LoopT *L) const
Return true if the specified loop is contained within this loop.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
Represents a single loop in the control flow graph.
An analysis that produces MemorySSA for a function.
LLVM_ABI void removeMemoryAccess(MemoryAccess *, bool OptimizePhis=false)
Remove a MemoryAccess from MemorySSA, including updating all definitions and uses.
Analysis pass which computes a PostDominatorTree.
LLVM_ABI bool dominates(const Instruction *I1, const Instruction *I2) const
Return true if I1 dominates I2.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
PreservedAnalyses & preserve()
Mark an analysis as preserved.
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.
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
LLVM Value Representation.
LLVMContext & getContext() const
All values hold a context through their type.
std::pair< iterator, bool > insert(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
unsigned getPathLength() const
Return the length of the path from the entry node to the current node, counting both nodes.
NodeRef getPath(unsigned n) const
Return the n'th node in the path from the entry node to the current node.
const ParentTy * getParent() const
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ BasicBlock
Various leaf nodes.
LLVM_ABI Function * getDeclarationIfExists(const Module *M, ID id)
Look up the Function declaration of the intrinsic id in the Module M and return it if it exists.
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
bool match(Val *V, const Pattern &P)
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
auto m_BasicBlock()
Match an arbitrary basic block value and ignore it.
auto m_Value()
Match an arbitrary value and ignore it.
CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
brc_match< Cond_t, match_bind< BasicBlock >, match_bind< BasicBlock > > m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F)
BinaryOp_match< LHS, RHS, Instruction::Or > m_Or(const LHS &L, const RHS &R)
auto m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
NodeAddr< DefNode * > Def
NodeAddr< InstrNode * > Instr
NodeAddr< UseNode * > Use
friend class Instruction
Iterator for Instructions in a `BasicBlock.
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.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
@ Known
Known to have no common set bits.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
df_iterator< T > df_begin(const T &G)
LLVM_ABI Value * extractWidenableCondition(const User *U)
LLVM_ABI void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
LLVM_ABI void parseWidenableGuard(const User *U, llvm::SmallVectorImpl< Value * > &Checks)
LLVM_ABI bool isSafeToSpeculativelyExecute(const Instruction *I, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr, bool UseVariableInfo=true, bool IgnoreUBImplyingAttrs=true)
Return true if the instruction does not have any effects besides calculating the result and does not ...
OutputIt copy_if(R &&Range, OutputIt Out, UnaryPredicate P)
Provide wrappers to std::copy_if which take ranges instead of having to pass begin/end explicitly.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
DomTreeNodeBase< BasicBlock > DomTreeNode
AnalysisManager< Loop, LoopStandardAnalysisResults & > LoopAnalysisManager
The loop analysis manager.
static Error getOffset(const SymbolRef &Sym, SectionRef Sec, uint64_t &Result)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI bool isGuard(const User *U)
Returns true iff U has semantics of a guard expressed in a form of call of llvm.experimental....
LLVM_ABI bool parseWidenableBranch(const User *U, Value *&Condition, Value *&WidenableCondition, BasicBlock *&IfTrueBB, BasicBlock *&IfFalseBB)
If U is widenable branch looking like: cond = ... wc = call i1 @llvm.experimental....
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
LLVM_ABI bool canCreateUndefOrPoison(const Operator *Op, bool ConsiderFlagsAndMetadata=true)
canCreateUndefOrPoison returns true if Op can create undef or poison from non-undef & non-poison oper...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI bool isGuardAsWidenableBranch(const User *U)
Returns true iff U has semantics of a guard expressed in a form of a widenable conditional branch to ...
LLVM_ABI void setWidenableBranchCond(CondBrInst *WidenableBR, Value *Cond)
Given a branch we know is widenable (defined per Analysis/GuardUtils.h), set it's condition such that...
DWARFExpression::Operation Op
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI PreservedAnalyses getLoopPassPreservedAnalyses()
Returns the minimum set of Analyses that all loop passes must preserve.
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
df_iterator< T > df_end(const T &G)
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI bool isGuaranteedNotToBePoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Returns true if V cannot be poison, but may be undef.
LLVM_ABI bool isKnownNonNegative(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Returns true if the give value is known to be non-negative.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
The adaptor from a function pass to a loop pass computes these analyses and makes them available to t...