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 {
129 PostDominatorTree *PDT;
132 MemorySSAUpdater *MSSAU;
137 std::function<bool(BasicBlock*)> BlockFilter;
141 SmallVector<Instruction *, 16> EliminatedGuardsAndBranches;
145 DenseSet<Instruction *> WidenedGuards;
151 bool eliminateInstrViaWidening(
152 Instruction *Instr,
const df_iterator<DomTreeNode *> &DFSI,
153 const DenseMap<BasicBlock *, SmallVector<Instruction *, 8>>
159 WS_IllegalOrNegative,
174 static StringRef scoreTypeToString(WideningScore WS);
178 WideningScore computeWideningScore(Instruction *DominatedInstr,
179 Instruction *ToWiden,
181 SmallVectorImpl<Value *> &ChecksToHoist,
182 SmallVectorImpl<Value *> &ChecksToWiden);
186 SmallPtrSet<const Instruction *, 8> Visited;
187 return canBeHoistedTo(V, InsertPos, Visited);
191 SmallPtrSetImpl<const Instruction *> &Visited)
const;
193 bool canBeHoistedTo(
const SmallVectorImpl<Value *> &Checks,
196 [&](
const Value *V) {
return canBeHoistedTo(V, InsertPos); });
202 void makeAvailableAt(
const SmallVectorImpl<Value *> &Checks,
204 for (
Value *V : Checks)
205 makeAvailableAt(V, InsertPos);
215 std::optional<Value *>
216 mergeChecks(SmallVectorImpl<Value *> &ChecksToHoist,
217 SmallVectorImpl<Value *> &ChecksToWiden,
218 std::optional<BasicBlock::iterator> InsertPt);
222 Value *hoistChecks(SmallVectorImpl<Value *> &ChecksToHoist,
235 const ConstantInt *Offset;
240 explicit RangeCheck(
const Value *Base,
const ConstantInt *Offset,
241 const Value *Length, ICmpInst *CheckInst)
242 : Base(Base), Offset(Offset), Length(Length), CheckInst(CheckInst) {}
244 void setBase(
const Value *NewBase) { Base = NewBase; }
245 void setOffset(
const ConstantInt *NewOffset) { Offset = NewOffset; }
247 const Value *getBase()
const {
return Base; }
248 const ConstantInt *
getOffset()
const {
return Offset; }
249 const APInt &getOffsetValue()
const {
return getOffset()->getValue(); }
250 const Value *getLength()
const {
return Length; };
251 ICmpInst *getCheckInst()
const {
return CheckInst; }
253 void print(raw_ostream &OS,
bool PrintTypes =
false) {
255 Base->printAsOperand(OS, PrintTypes);
257 Offset->printAsOperand(OS, PrintTypes);
259 Length->printAsOperand(OS, PrintTypes);
271 bool parseRangeChecks(SmallVectorImpl<Value *> &ToParse,
272 SmallVectorImpl<RangeCheck> &Checks) {
273 for (
auto CheckCond : ToParse) {
274 if (!parseRangeChecks(CheckCond, Checks))
280 bool parseRangeChecks(
Value *CheckCond, SmallVectorImpl<RangeCheck> &Checks);
286 bool combineRangeChecks(SmallVectorImpl<RangeCheck> &Checks,
287 SmallVectorImpl<RangeCheck> &CombinedChecks)
const;
291 bool isWideningCondProfitable(SmallVectorImpl<Value *> &ChecksToHoist,
292 SmallVectorImpl<Value *> &ChecksToWiden) {
293 return mergeChecks(ChecksToHoist, ChecksToWiden, std::nullopt)
298 void widenGuard(SmallVectorImpl<Value *> &ChecksToHoist,
299 SmallVectorImpl<Value *> &ChecksToWiden,
300 Instruction *ToWiden) {
302 auto MergedCheck = mergeChecks(ChecksToHoist, ChecksToWiden, InsertPt);
304 : hoistChecks(ChecksToHoist,
315 explicit GuardWideningImpl(DominatorTree &DT, PostDominatorTree *PDT,
316 LoopInfo &LI, AssumptionCache &AC,
318 std::function<
bool(BasicBlock *)> BlockFilter)
319 : DT(DT), PDT(PDT), LI(LI), AC(AC), MSSAU(MSSAU), Root(Root),
320 BlockFilter(BlockFilter) {}
330 if (ScalarOptions::Global.guard_widening_widen_branch_guards &&
336bool GuardWideningImpl::run() {
337 DenseMap<BasicBlock *, SmallVector<Instruction *, 8>> GuardsInBlock;
341 auto *BB = (*DFI)->getBlock();
342 if (!BlockFilter(BB))
345 auto &CurrentList = GuardsInBlock[BB];
351 for (
auto *
II : CurrentList)
352 Changed |= eliminateInstrViaWidening(
II, DFI, GuardsInBlock);
356 for (
auto *
I : EliminatedGuardsAndBranches)
357 if (!WidenedGuards.
count(
I)) {
363 "Eliminated something other than guard or branch?");
364 ++CondBranchEliminated;
371bool GuardWideningImpl::eliminateInstrViaWidening(
372 Instruction *Instr,
const df_iterator<DomTreeNode *> &DFSI,
373 const DenseMap<BasicBlock *, SmallVector<Instruction *, 8>>
380 if (ChecksToHoist.
empty() ||
385 auto BestScoreSoFar = WS_IllegalOrNegative;
389 for (
unsigned i = 0, e = DFSI.
getPathLength(); i != e; ++i) {
390 auto *CurBB = DFSI.
getPath(i)->getBlock();
391 if (!BlockFilter(CurBB))
393 assert(GuardsInBlock.
count(CurBB) &&
"Must have been populated by now!");
394 const auto &GuardsInCurBB = GuardsInBlock.
find(CurBB)->second;
396 auto I = GuardsInCurBB.begin();
397 auto E =
Instr->getParent() == CurBB ?
find(GuardsInCurBB, Instr)
398 : GuardsInCurBB.
end();
403 for (
auto &
I : *CurBB) {
404 if (Index == GuardsInCurBB.size())
406 if (GuardsInCurBB[Index] == &
I)
409 assert(Index == GuardsInCurBB.size() &&
410 "Guards expected to be in order!");
414 assert((i == (e - 1)) == (
Instr->getParent() == CurBB) &&
"Bad DFS?");
422 auto Score = computeWideningScore(Instr, Candidate, *WideningPoint,
423 ChecksToHoist, CandidateChecks);
424 LLVM_DEBUG(
dbgs() <<
"Score between " << *Instr <<
" and " << *Candidate
425 <<
" is " << scoreTypeToString(Score) <<
"\n");
426 if (Score > BestScoreSoFar) {
427 BestScoreSoFar = Score;
428 BestSoFar = Candidate;
433 if (BestScoreSoFar == WS_IllegalOrNegative) {
434 LLVM_DEBUG(
dbgs() <<
"Did not eliminate guard " << *Instr <<
"\n");
438 assert(BestSoFar != Instr &&
"Should have never visited same guard!");
441 LLVM_DEBUG(
dbgs() <<
"Widening " << *Instr <<
" into " << *BestSoFar
442 <<
" with score " << scoreTypeToString(BestScoreSoFar)
446 widenGuard(ChecksToHoist, ChecksToWiden, BestSoFar);
449 EliminatedGuardsAndBranches.push_back(Instr);
450 WidenedGuards.
insert(BestSoFar);
454GuardWideningImpl::WideningScore GuardWideningImpl::computeWideningScore(
455 Instruction *DominatedInstr, Instruction *ToWiden,
457 SmallVectorImpl<Value *> &ChecksToWiden) {
459 Loop *DominatingGuardLoop = LI.
getLoopFor(WideningPoint->getParent());
460 bool HoistingOutOfLoop =
false;
462 if (DominatingGuardLoop != DominatedInstrLoop) {
465 if (DominatingGuardLoop &&
466 !DominatingGuardLoop->
contains(DominatedInstrLoop))
467 return WS_IllegalOrNegative;
469 HoistingOutOfLoop =
true;
472 if (!canBeHoistedTo(ChecksToHoist, WideningPoint))
473 return WS_IllegalOrNegative;
477 if (!canBeHoistedTo(
getCondition(ToWiden), WideningPoint))
478 return WS_IllegalOrNegative;
488 if (isWideningCondProfitable(ChecksToHoist, ChecksToWiden))
489 return HoistingOutOfLoop ? WS_VeryPositive : WS_Positive;
491 if (HoistingOutOfLoop)
496 auto GetLikelySuccessor = [](
const BasicBlock * BB)->
const BasicBlock * {
497 if (
auto *UniqueSucc = BB->getUniqueSuccessor())
499 auto *
Term = BB->getTerminator();
501 const BasicBlock *IfTrue =
nullptr, *IfFalse =
nullptr;
502 using namespace PatternMatch;
508 return ConstCond->isAllOnesValue() ? IfTrue : IfFalse;
510 if (IfFalse->getPostdominatingDeoptimizeCall())
523 auto MaybeHoistingToHotterBlock = [&]() {
524 const auto *DominatingBlock = WideningPoint->getParent();
525 const auto *DominatedBlock = DominatedInstr->
getParent();
530 assert(DT.
dominates(DominatingBlock, DominatedBlock) &&
"No dominance");
531 while (DominatedBlock != DominatingBlock) {
532 auto *LikelySucc = GetLikelySuccessor(DominatingBlock);
539 DominatingBlock = LikelySucc;
543 if (DominatedBlock == DominatingBlock)
547 if (!DT.
dominates(DominatingBlock, DominatedBlock))
552 return !PDT->
dominates(DominatedBlock, DominatingBlock);
555 return MaybeHoistingToHotterBlock() ? WS_IllegalOrNegative : WS_Neutral;
558bool GuardWideningImpl::canBeHoistedTo(
560 SmallPtrSetImpl<const Instruction *> &Visited)
const {
566 Inst->mayReadFromMemory())
573 "PHIs should return false for isSafeToSpeculativelyExecute");
575 "We did a DFS from the block entry!");
576 return all_of(Inst->operands(),
577 [&](
Value *
Op) { return canBeHoistedTo(Op, Loc, Visited); });
580void GuardWideningImpl::makeAvailableAt(
Value *V,
587 !Inst->mayReadFromMemory() &&
588 "Should've checked with canBeHoistedTo!");
590 for (
Value *
Op : Inst->operands())
591 makeAvailableAt(
Op, Loc);
593 Inst->moveBefore(*Loc->getParent(), Loc);
598static std::optional<BasicBlock::iterator>
604 std::optional<BasicBlock::iterator> Res =
I->getInsertionPointAfterDef();
614 Instruction *User = cast<Instruction>(U);
615 return ResInst != User && DT.dominates(I, User) &&
616 !DT.dominates(ResInst, User);
622Value *GuardWideningImpl::freezeAndPush(
Value *Orig,
626 std::optional<BasicBlock::iterator> InsertPtAtDef =
628 if (!InsertPtAtDef) {
629 FreezeInst *FI =
new FreezeInst(Orig,
"gw.freeze");
635 FreezeInst *FI =
new FreezeInst(Orig,
"gw.freeze");
640 SmallPtrSet<Value *, 16> Visited;
641 SmallVector<Value *, 16> Worklist;
642 SmallPtrSet<Instruction *, 16> DropPoisonFlags;
643 SmallVector<Value *, 16> NeedFreeze;
644 DenseMap<Value *, FreezeInst *> CacheOfFreezes;
649 auto handleConstantOrGlobal = [&](
Use &
U) {
654 if (Visited.
insert(Def).second) {
658 FreezeInst *FI =
new FreezeInst(Def,
Def->getName() +
".gw.fr");
660 CacheOfFreezes[
Def] = FI;
663 if (
auto It = CacheOfFreezes.
find(Def); It != CacheOfFreezes.
end())
669 while (!Worklist.
empty()) {
671 if (!Visited.
insert(V).second)
686 return isa<Instruction>(Op) && !getFreezeInsertPt(Op, DT);
692 for (Use &U :
I->operands())
693 if (!handleConstantOrGlobal(U))
696 for (Instruction *
I : DropPoisonFlags)
697 I->dropPoisonGeneratingAnnotations();
700 for (
Value *V : NeedFreeze) {
702 FreezeInst *FI =
new FreezeInst(V,
V->getName() +
".gw.fr");
703 FI->
insertBefore(*FreezeInsertPt->getParent(), FreezeInsertPt);
707 V->replaceUsesWithIf(
708 FI, [&](
const Use & U)->
bool {
return U.getUser() != FI; });
714std::optional<Value *>
715GuardWideningImpl::mergeChecks(SmallVectorImpl<Value *> &ChecksToHoist,
716 SmallVectorImpl<Value *> &ChecksToWiden,
717 std::optional<BasicBlock::iterator> InsertPt) {
718 using namespace llvm::PatternMatch;
723 ConstantInt *RHS0, *RHS1;
725 CmpPredicate Pred0, Pred1;
728 if (ChecksToWiden.
size() == 1 && ChecksToHoist.
size() == 1 &&
742 if (std::optional<ConstantRange> Intersect =
746 if (Intersect->getEquivalentICmp(Pred, NewRHSAP)) {
748 ConstantInt *NewRHS =
749 ConstantInt::get((*InsertPt)->getContext(), NewRHSAP);
750 assert(canBeHoistedTo(
LHS, *InsertPt) &&
"must be");
751 makeAvailableAt(
LHS, *InsertPt);
752 Result =
new ICmpInst(*InsertPt, Pred,
LHS, NewRHS,
"wide.chk");
762 if (parseRangeChecks(ChecksToWiden, Checks) &&
763 parseRangeChecks(ChecksToHoist, Checks) &&
764 combineRangeChecks(Checks, CombinedChecks)) {
766 for (
auto &RC : CombinedChecks) {
767 makeAvailableAt(RC.getCheckInst(), *InsertPt);
769 Result = BinaryOperator::CreateAnd(RC.getCheckInst(), Result,
"",
772 Result = RC.getCheckInst();
774 assert(Result &&
"Failed to find result value");
775 Result->setName(
"wide.chk");
776 Result = freezeAndPush(Result, *InsertPt);
786Value *GuardWideningImpl::hoistChecks(SmallVectorImpl<Value *> &ChecksToHoist,
791 makeAvailableAt(ChecksToHoist, InsertPt);
792 makeAvailableAt(OldCondition, InsertPt);
794 Result = freezeAndPush(Result, InsertPt);
795 Result = Builder.CreateAnd(OldCondition, Result);
796 Result->setName(
"wide.chk");
800bool GuardWideningImpl::parseRangeChecks(
801 Value *CheckCond, SmallVectorImpl<GuardWideningImpl::RangeCheck> &Checks) {
802 using namespace llvm::PatternMatch;
805 if (!IC || !IC->getOperand(0)->getType()->isIntegerTy() ||
806 (IC->getPredicate() != ICmpInst::ICMP_ULT &&
807 IC->getPredicate() != ICmpInst::ICMP_UGT))
810 const Value *CmpLHS = IC->getOperand(0), *CmpRHS = IC->getOperand(1);
811 if (IC->getPredicate() == ICmpInst::ICMP_UGT)
814 auto &
DL = IC->getDataLayout();
816 GuardWideningImpl::RangeCheck
Check(
837 "Unreachable instruction?");
841 Check.setBase(OpLHS);
842 APInt NewOffset =
Check.getOffsetValue() + OpRHS->
getValue();
843 Check.setOffset(ConstantInt::get(Ctx, NewOffset));
849 Check.setBase(OpLHS);
850 APInt NewOffset =
Check.getOffsetValue() + OpRHS->
getValue();
851 Check.setOffset(ConstantInt::get(Ctx, NewOffset));
861bool GuardWideningImpl::combineRangeChecks(
862 SmallVectorImpl<GuardWideningImpl::RangeCheck> &Checks,
863 SmallVectorImpl<GuardWideningImpl::RangeCheck> &RangeChecksOut)
const {
864 unsigned OldCount = Checks.
size();
865 while (!Checks.
empty()) {
868 const Value *CurrentBase = Checks.
front().getBase();
869 const Value *CurrentLength = Checks.
front().getLength();
873 auto IsCurrentCheck = [&](GuardWideningImpl::RangeCheck &RC) {
874 return RC.getBase() == CurrentBase && RC.getLength() == CurrentLength;
877 copy_if(Checks, std::back_inserter(CurrentChecks), IsCurrentCheck);
880 assert(CurrentChecks.
size() != 0 &&
"We know we have at least one!");
882 if (CurrentChecks.
size() < 3) {
890 llvm::sort(CurrentChecks, [&](
const GuardWideningImpl::RangeCheck &
LHS,
891 const GuardWideningImpl::RangeCheck &
RHS) {
892 return LHS.getOffsetValue().slt(
RHS.getOffsetValue());
897 const ConstantInt *MinOffset = CurrentChecks.
front().getOffset();
898 const ConstantInt *MaxOffset = CurrentChecks.
back().getOffset();
901 if ((MaxOffset->
getValue() - MinOffset->getValue())
905 APInt MaxDiff = MaxOffset->
getValue() - MinOffset->getValue();
906 const APInt &HighOffset = MaxOffset->
getValue();
907 auto OffsetOK = [&](
const GuardWideningImpl::RangeCheck &RC) {
908 return (HighOffset - RC.getOffsetValue()).ult(MaxDiff);
953 assert(RangeChecksOut.
size() <= OldCount &&
"We pessimized!");
954 return RangeChecksOut.
size() != OldCount;
958StringRef GuardWideningImpl::scoreTypeToString(WideningScore WS) {
960 case WS_IllegalOrNegative:
961 return "IllegalOrNegative";
966 case WS_VeryPositive:
967 return "VeryPositive";
978 F.getParent(), Intrinsic::experimental_guard);
979 bool HasIntrinsicGuards = GuardDecl && !GuardDecl->use_empty();
981 F.getParent(), Intrinsic::experimental_widenable_condition);
982 bool HasWidenableConditions = WCDecl && !WCDecl->use_empty();
983 if (!HasIntrinsicGuards && !HasWidenableConditions)
990 std::unique_ptr<MemorySSAUpdater> MSSAU;
992 MSSAU = std::make_unique<MemorySSAUpdater>(&MSSAA->getMSSA());
993 if (!GuardWideningImpl(DT, &PDT, LI, AC, MSSAU ? MSSAU.get() :
nullptr,
1009 RootBB = L.getHeader();
1011 return BB == RootBB || L.contains(BB);
1013 std::unique_ptr<MemorySSAUpdater> MSSAU;
1015 MSSAU = std::make_unique<MemorySSAUpdater>(AR.
MSSA);
1016 if (!GuardWideningImpl(AR.
DT,
nullptr, AR.
LI, AR.
AC,
1017 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 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 getFirstNonPHIOrDbgOrAlloca() const
Returns an iterator to the first instruction in this block that is not a PHINode, a debug intrinsic,...
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...