68#define DEBUG_TYPE "mergeicmps"
80 BCEAtom(GetElementPtrInst *GEP, LoadInst *LoadI,
int BaseId, APInt Offset)
81 : GEP(GEP), LoadI(LoadI), BaseId(BaseId), Offset(std::
move(Offset)) {}
83 BCEAtom(
const BCEAtom &) =
delete;
84 BCEAtom &operator=(
const BCEAtom &) =
delete;
86 BCEAtom(BCEAtom &&that) =
default;
87 BCEAtom &operator=(BCEAtom &&that) {
93 Offset = std::move(that.Offset);
108 return BaseId !=
O.BaseId ? BaseId <
O.BaseId : Offset.slt(
O.Offset);
111 GetElementPtrInst *GEP =
nullptr;
112 LoadInst *LoadI =
nullptr;
119class BaseIdentifier {
125 const auto Insertion = BaseToIndex.try_emplace(
Base, Order);
126 if (Insertion.second)
128 return Insertion.first->second;
133 DenseMap<const Value*, int> BaseToIndex;
145 if (LoadI->isUsedOutsideOfBlock(LoadI->getParent())) {
150 if (!LoadI->isSimple()) {
154 Value *Addr = LoadI->getOperand(0);
159 const auto &
DL = LoadI->getDataLayout();
172 if (
GEP->isUsedOutsideOfBlock(LoadI->getParent())) {
178 Base =
GEP->getPointerOperand();
194 const ICmpInst *CmpI;
196 BCECmp(BCEAtom L, BCEAtom R,
int SizeBits,
const ICmpInst *CmpI)
197 : Lhs(std::
move(
L)), Rhs(std::
move(
R)), SizeBits(SizeBits), CmpI(CmpI) {
209 typedef SmallDenseSet<const Instruction *, 8> InstructionSet;
211 BCECmpBlock(BCECmp Cmp, BasicBlock *BB, InstructionSet BlockInsts)
212 : BB(BB), BlockInsts(std::
move(BlockInsts)), Cmp(std::
move(Cmp)) {}
214 const BCEAtom &Lhs()
const {
return Cmp.Lhs; }
215 const BCEAtom &Rhs()
const {
return Cmp.Rhs; }
216 int SizeBits()
const {
return Cmp.SizeBits; }
219 bool doesOtherWork()
const;
229 bool canSinkBCECmpInst(
const Instruction *,
AliasAnalysis &AA)
const;
239 InstructionSet BlockInsts;
241 bool RequireSplit =
false;
243 unsigned OrigOrder = 0;
250bool BCECmpBlock::canSinkBCECmpInst(
const Instruction *Inst,
255 auto MayClobber = [&](LoadInst *LI) {
261 if (MayClobber(Cmp.Lhs.LoadI) || MayClobber(Cmp.Rhs.LoadI))
267 const Instruction *OpI = dyn_cast<Instruction>(Op);
268 return OpI && BlockInsts.contains(OpI);
272void BCECmpBlock::split(BasicBlock *NewParent,
AliasAnalysis &AA)
const {
273 llvm::SmallVector<Instruction *, 4> OtherInsts;
274 for (Instruction &Inst : *BB) {
275 if (BlockInsts.
count(&Inst))
277 assert(canSinkBCECmpInst(&Inst, AA) &&
"Split unsplittable block");
284 for (Instruction *Inst :
reverse(OtherInsts))
289 for (Instruction &Inst : *BB) {
290 if (!BlockInsts.
count(&Inst)) {
291 if (!canSinkBCECmpInst(&Inst, AA))
298bool BCECmpBlock::doesOtherWork()
const {
303 for (
const Instruction &Inst : *BB) {
304 if (!BlockInsts.
count(&Inst))
312static std::optional<BCECmp>
336 return BCECmp(std::move(Lhs), std::move(Rhs),
342static std::optional<BCECmpBlock>
344 const BasicBlock *
const PhiBlock, BaseIdentifier &BaseId) {
347 auto *Term =
Block->getTerminator();
362 if (!Const->isZero())
365 assert(BranchI->getNumSuccessors() == 2 &&
"expecting a cond branch");
366 BasicBlock *
const FalseBlock = BranchI->getSuccessor(1);
367 Cond = BranchI->getCondition();
378 std::optional<BCECmp> Result =
visitICmp(CmpI, ExpectedPredicate, BaseId);
382 BCECmpBlock::InstructionSet BlockInsts(
383 {Result->Lhs.LoadI, Result->Rhs.LoadI, Result->CmpI, Term});
385 BlockInsts.insert(Result->Lhs.GEP);
387 BlockInsts.insert(Result->Rhs.GEP);
388 return BCECmpBlock(std::move(*Result),
Block, BlockInsts);
392 BCECmpBlock &&Comparison) {
394 <<
"': Found cmp of " << Comparison.SizeBits()
395 <<
" bits between " << Comparison.Lhs().BaseId <<
" + "
396 << Comparison.Lhs().Offset <<
" and "
397 << Comparison.Rhs().BaseId <<
" + "
398 << Comparison.Rhs().Offset <<
"\n");
400 Comparison.OrigOrder = Comparisons.size();
401 Comparisons.push_back(std::move(Comparison));
408 using ContiguousBlocks = std::vector<BCECmpBlock>;
410 BCECmpChain(
const std::vector<BasicBlock *> &Blocks, PHINode &Phi,
414 DomTreeUpdater &DTU);
416 bool atLeastOneMerged()
const {
417 return any_of(MergedBlocks_,
418 [](
const auto &Blocks) {
return Blocks.size() > 1; });
424 std::vector<ContiguousBlocks> MergedBlocks_;
431 return First.Lhs().BaseId == Second.Lhs().BaseId &&
432 First.Rhs().BaseId == Second.Rhs().BaseId &&
433 First.Lhs().Offset +
First.SizeBits() / 8 == Second.Lhs().Offset &&
434 First.Rhs().Offset +
First.SizeBits() / 8 == Second.Rhs().Offset;
438 unsigned MinOrigOrder = std::numeric_limits<unsigned>::max();
439 for (
const BCECmpBlock &
Block : Blocks)
440 MinOrigOrder = std::min(MinOrigOrder,
Block.OrigOrder);
446static std::vector<BCECmpChain::ContiguousBlocks>
448 std::vector<BCECmpChain::ContiguousBlocks> MergedBlocks;
452 [](
const BCECmpBlock &LhsBlock,
const BCECmpBlock &RhsBlock) {
453 return std::tie(LhsBlock.Lhs(), LhsBlock.Rhs()) <
454 std::tie(RhsBlock.Lhs(), RhsBlock.Rhs());
457 BCECmpChain::ContiguousBlocks *LastMergedBlock =
nullptr;
458 for (BCECmpBlock &
Block : Blocks) {
460 MergedBlocks.emplace_back();
461 LastMergedBlock = &MergedBlocks.back();
464 << LastMergedBlock->back().BB->getName() <<
"\n");
466 LastMergedBlock->push_back(std::move(
Block));
471 llvm::sort(MergedBlocks, [](
const BCECmpChain::ContiguousBlocks &LhsBlocks,
472 const BCECmpChain::ContiguousBlocks &RhsBlocks) {
479BCECmpChain::BCECmpChain(
const std::vector<BasicBlock *> &Blocks, PHINode &Phi,
482 assert(!Blocks.empty() &&
"a chain should have at least one block");
484 std::vector<BCECmpBlock> Comparisons;
485 BaseIdentifier BaseId;
488 if (
Block->hasAddressTaken()) {
495 LLVM_DEBUG(
dbgs() <<
"chain with invalid BCECmpBlock, no merge.\n");
498 if (Comparison->doesOtherWork()) {
500 <<
"' does extra work besides compare\n");
501 if (Comparisons.empty()) {
515 if (Comparison->canSplit(
AA)) {
517 <<
"Split initial block '" << Comparison->BB->getName()
518 <<
"' that does extra work besides compare\n");
519 Comparison->RequireSplit =
true;
523 <<
"ignoring initial block '" << Comparison->BB->getName()
524 <<
"' that does extra work besides compare\n");
557 if (Comparisons.empty()) {
558 LLVM_DEBUG(
dbgs() <<
"chain with no BCE basic blocks, no merge\n");
561 EntryBlock_ = Comparisons[0].BB;
562 MergedBlocks_ =
mergeBlocks(std::move(Comparisons));
569class MergedBlockName {
571 SmallString<16> Scratch;
575 : Name(makeName(Comparisons)) {}
576 const StringRef Name;
582 if (Comparisons.
size() == 1)
583 return Comparisons[0].BB->getName();
584 const int size = std::accumulate(Comparisons.
begin(), Comparisons.
end(), 0,
585 [](
int i,
const BCECmpBlock &Cmp) {
586 return i + Cmp.BB->getName().size();
589 return StringRef(
"", 0);
595 Scratch.reserve(
size + Comparisons.
size() - 1);
596 const auto append = [
this](StringRef str) {
597 Scratch.append(str.begin(), str.end());
599 append(Comparisons[0].BB->getName());
600 for (
int I = 1,
E = Comparisons.
size();
I <
E; ++
I) {
607 return Scratch.str();
614static std::optional<SmallVector<uint32_t, 2>>
619 if (Comparisons.
size() == 1) {
631 for (
const auto &
C : Comparisons) {
649 assert(!Comparisons.
empty() &&
"merging zero comparisons");
651 const BCECmpBlock &FirstCmp = Comparisons[0];
656 NextCmpBlock->
getParent(), InsertBefore);
660 if (FirstCmp.Lhs().GEP)
661 Lhs = Builder.Insert(FirstCmp.Lhs().GEP->clone());
663 Lhs = FirstCmp.Lhs().LoadI->getPointerOperand();
664 if (FirstCmp.Rhs().GEP)
665 Rhs = Builder.Insert(FirstCmp.Rhs().GEP->clone());
667 Rhs = FirstCmp.Rhs().LoadI->getPointerOperand();
669 Value *IsEqual =
nullptr;
677 Comparisons, [](
const BCECmpBlock &
B) {
return B.RequireSplit; });
678 if (ToSplit != Comparisons.
end()) {
680 ToSplit->split(BB,
AA);
683 if (Comparisons.
size() == 1) {
686 Instruction *
const LhsLoad = Builder.Insert(FirstCmp.Lhs().LoadI->clone());
687 Instruction *
const RhsLoad = Builder.Insert(FirstCmp.Rhs().LoadI->clone());
692 IsEqual = Builder.CreateICmpEQ(LhsLoad, RhsLoad);
694 const unsigned TotalSizeBits = std::accumulate(
695 Comparisons.
begin(), Comparisons.
end(), 0u,
696 [](
int Size,
const BCECmpBlock &
C) { return Size + C.SizeBits(); });
699 unsigned SizeTBits = TLI.
getSizeTSize(*Phi.getModule());
703 const auto &
DL = Phi.getDataLayout();
706 ConstantInt::get(Builder.getIntNTy(SizeTBits), TotalSizeBits / 8),
708 IsEqual = Builder.CreateICmpEQ(
709 MemCmpCall, ConstantInt::get(Builder.getIntNTy(IntBits), 0));
714 if (NextCmpBlock == PhiBB) {
716 Builder.CreateBr(PhiBB);
717 Phi.addIncoming(IsEqual, BB);
721 auto *BI = Builder.CreateCondBr(IsEqual, NextCmpBlock, PhiBB);
733 assert(atLeastOneMerged() &&
"simplifying trivial BCECmpChain");
734 LLVM_DEBUG(
dbgs() <<
"Simplifying comparison chain starting at block "
735 << EntryBlock_->
getName() <<
"\n");
741 for (
const auto &Blocks :
reverse(MergedBlocks_)) {
743 Blocks, InsertBefore, NextCmpBlock, Phi_, TLI, AA, DTU);
754 DTU.
applyUpdates({{DominatorTree::Delete, Pred, EntryBlock_},
755 {DominatorTree::Insert, Pred, NextCmpBlock}});
760 const bool ChainEntryIsFnEntry = EntryBlock_->
isEntryBlock();
761 if (ChainEntryIsFnEntry && DTU.
hasDomTree()) {
763 << EntryBlock_->
getName() <<
" to "
764 << NextCmpBlock->
getName() <<
"\n");
766 DTU.
applyUpdates({{DominatorTree::Delete, NextCmpBlock, EntryBlock_}});
768 EntryBlock_ =
nullptr;
771 SmallVector<BasicBlock *, 16> DeadBlocks;
772 for (
const auto &Blocks : MergedBlocks_) {
773 for (
const BCECmpBlock &
Block : Blocks) {
781 MergedBlocks_.clear();
785static std::vector<BasicBlock *>
788 std::vector<BasicBlock *> Blocks(NumBlocks);
789 assert(LastBlock &&
"invalid last block");
791 for (
int BlockIndex = NumBlocks - 1; BlockIndex > 0; --BlockIndex) {
796 <<
" has its address taken\n");
799 Blocks[BlockIndex] = CurBlock;
801 if (!SinglePredecessor) {
804 <<
" has two or more predecessors\n");
807 if (Phi.getBasicBlockIndex(SinglePredecessor) < 0) {
810 <<
" does not link back to the phi\n");
813 CurBlock = SinglePredecessor;
815 Blocks[0] = CurBlock;
822 if (Phi.getNumIncomingValues() <= 1) {
843 for (
unsigned I = 0;
I < Phi.getNumIncomingValues(); ++
I) {
852 Phi.getIncomingBlock(
I)) {
860 <<
"skip: non-constant value not from cmp or not from last block.\n");
863 LastBlock = Phi.getIncomingBlock(
I);
877 if (Blocks.empty())
return false;
878 BCECmpChain CmpChain(Blocks, Phi,
AA);
880 if (!CmpChain.atLeastOneMerged()) {
885 return CmpChain.simplify(TLI,
AA, DTU);
895 if (!
TTI.enableMemCmpExpansion(
F.hasOptSize(),
true))
899 if (!TLI.
has(LibFunc_memcmp))
903 DomTreeUpdater::UpdateStrategy::Eager);
905 bool MadeChange =
false;
917class MergeICmpsLegacyPass :
public FunctionPass {
921 MergeICmpsLegacyPass() : FunctionPass(
ID) {
926 if (skipFunction(
F))
return false;
927 const auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(
F);
928 const auto &
TTI = getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
F);
931 auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>();
932 auto &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
933 return runImpl(
F, TLI,
TTI, AA, DTWP ? &DTWP->getDomTree() :
nullptr);
937 void getAnalysisUsage(AnalysisUsage &AU)
const override {
948char MergeICmpsLegacyPass::ID = 0;
950 "Merge contiguous icmps into a memcmp",
false,
false)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool runOnFunction(Function &F, bool PostInlining)
static bool runImpl(Function &F, const TargetLowering &TLI, const LibcallLoweringInfo &Libcalls, AssumptionCache *AC)
This is the interface for a simple mod/ref and alias analysis over globals.
static void enqueueBlock(std::vector< BCECmpBlock > &Comparisons, BCECmpBlock &&Comparison)
static std::vector< BCECmpChain::ContiguousBlocks > mergeBlocks(std::vector< BCECmpBlock > &&Blocks)
Given a chain of comparison blocks, groups the blocks into contiguous ranges that can be merged toget...
static std::optional< SmallVector< uint32_t, 2 > > computeMergedBranchWeights(ArrayRef< BCECmpBlock > Comparisons)
Determine the branch weights for the resulting conditional branch, resulting after merging Comparison...
static std::optional< BCECmpBlock > visitCmpBlock(Value *const Val, BasicBlock *const Block, const BasicBlock *const PhiBlock, BaseIdentifier &BaseId)
static bool areContiguous(const BCECmpBlock &First, const BCECmpBlock &Second)
static std::vector< BasicBlock * > getOrderedBlocks(PHINode &Phi, BasicBlock *const LastBlock, int NumBlocks)
static unsigned getMinOrigOrder(const BCECmpChain::ContiguousBlocks &Blocks)
static BCEAtom visitICmpLoadOperand(Value *const Val, BaseIdentifier &BaseId)
static std::optional< BCECmp > visitICmp(const ICmpInst *const CmpI, const ICmpInst::Predicate ExpectedPredicate, BaseIdentifier &BaseId)
static BasicBlock * mergeComparisons(ArrayRef< BCECmpBlock > Comparisons, BasicBlock *const InsertBefore, BasicBlock *const NextCmpBlock, PHINode &Phi, const TargetLibraryInfo &TLI, AliasAnalysis &AA, DomTreeUpdater &DTU)
static bool processPhi(PHINode &Phi, const TargetLibraryInfo &TLI, AliasAnalysis &AA, DomTreeUpdater &DTU)
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file contains the declarations for profiling metadata utility functions.
const SmallVectorImpl< MachineOperand > & Cond
This file defines the SmallString class.
A manager for alias analyses.
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
ModRefInfo getModRefInfo(const Instruction *I, const std::optional< MemoryLocation > &OptLoc)
Check whether or not an instruction may read or write the optionally specified memory location.
Class for arbitrary precision integers.
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.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
bool empty() const
empty - Check if the array is empty.
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
const Function * getParent() const
Return the enclosing method, or null if none.
bool hasAddressTaken() const
Returns true if there are any uses of this basic block other than direct branches,...
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
LLVM_ABI bool isEntryBlock() const
Return true if this is the entry block of the containing function.
LLVM_ABI const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
LLVM_ABI const BasicBlock * getSingleSuccessor() const
Return the successor of this block if it has a single successor.
LLVM_ABI LLVMContext & getContext() const
Get the context in which this basic block lives.
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...
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Predicate getPredicate() const
Return the predicate for this instruction.
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
Analysis pass which computes a DominatorTree.
DomTreeNodeBase< NodeT > * setNewRoot(NodeT *BB)
Add a new node to the forward dominator tree and make it a new root.
static constexpr UpdateKind Insert
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
DomTreeT & getDomTree()
Flush DomTree updates and return DomTree.
void applyUpdates(ArrayRef< UpdateT > Updates)
Submit updates to all available trees.
bool hasDomTree() const
Returns true if it holds a DomTreeT.
This instruction compares its operands according to the predicate given to the constructor.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
LLVM_ABI bool mayWriteToMemory() const LLVM_READONLY
Return true if this instruction may modify memory.
LLVM_ABI bool comesBefore(const Instruction *Other) const
Given an instruction Other in the same basic block as this instruction, return true if this instructi...
LLVM_ABI void moveBeforePreserving(InstListType::iterator MovePos)
Perform a moveBefore operation, while signalling that the caller intends to preserve the original ord...
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
This is an important class for using LLVM in a threaded context.
static LLVM_ABI MemoryLocation get(const LoadInst *LI)
Return a location with information about the memory reference by the given instruction.
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Pass interface - Implemented by all 'passes'.
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 & preserve()
Mark an analysis as preserved.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
constexpr bool empty() const
empty - Check if the string is empty.
Analysis pass providing the TargetTransformInfo.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
bool has(LibFunc F) const
Tests whether a library function is available.
unsigned getSizeTSize(const Module &M) const
Returns the size of the size_t type in bits.
unsigned getIntSize() const
Get size of a C-level int or unsigned int, in bits.
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
LLVM_ABI bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
const ParentTy * getParent() const
Abstract Attribute helper functions.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ BasicBlock
Various leaf nodes.
NodeAddr< PhiNode * > Phi
LLVM_ABI void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
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.
bool operator<(int64_t V1, const APSInt &V2)
FunctionAddr VTableAddr Value
cl::opt< bool > ProfcheckDisableMetadataFixes
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI void setBranchWeights(Instruction &I, ArrayRef< uint32_t > Weights, bool IsExpected, bool ElideAllZero=false)
Create a new branch_weights metadata node and add or overwrite a prof metadata reference to instructi...
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 Value * emitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B, const DataLayout &DL, const TargetLibraryInfo *TLI)
Emit a call to the memcmp function.
LLVM_ABI SmallVector< uint32_t > fitWeights(ArrayRef< uint64_t > Weights)
Push the weights right to fit in uint32_t.
auto reverse(ContainerTy &&C)
bool isModSet(const ModRefInfo MRI)
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
iterator_range< SplittingIterator > split(StringRef Str, StringRef Separator)
Split the specified string over a separator and return a range-compatible iterable over its partition...
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...
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
LLVM_ABI Pass * createMergeICmpsLegacyPass()
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI bool isDereferenceablePointer(const Value *V, Type *Ty, const DataLayout &DL, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr)
Return true if this is always a dereferenceable pointer.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI bool extractBranchWeights(const MDNode *ProfileData, SmallVectorImpl< uint32_t > &Weights)
Extract branch weights from MD_prof metadata.
auto pred_begin(const MachineBasicBlock *BB)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
SmallVector< uint64_t, 2 > getDisjunctionWeights(const SmallVector< T1, 2 > &B1, const SmallVector< T2, 2 > &B2)
Get the branch weights of a branch conditioned on b1 || b2, where b1 and b2 are 2 booleans that are t...
bool pred_empty(const BasicBlock *BB)
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI void DeleteDeadBlocks(ArrayRef< BasicBlock * > BBs, DomTreeUpdater *DTU=nullptr, bool KeepOneInputPHIs=false)
Delete the specified blocks from BB.
LLVM_ABI void initializeMergeICmpsLegacyPassPass(PassRegistry &)
AAResults AliasAnalysis
Temporary typedef for legacy code that uses a generic AliasAnalysis pointer or reference.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)