65#define DEBUG_TYPE "mergeicmps"
77 BCEAtom(GetElementPtrInst *GEP, LoadInst *LoadI,
int BaseId, APInt Offset)
78 : GEP(GEP), LoadI(LoadI), BaseId(BaseId), Offset(std::
move(Offset)) {}
80 BCEAtom(
const BCEAtom &) =
delete;
81 BCEAtom &operator=(
const BCEAtom &) =
delete;
83 BCEAtom(BCEAtom &&that) =
default;
84 BCEAtom &operator=(BCEAtom &&that) {
90 Offset = std::move(that.Offset);
105 return BaseId !=
O.BaseId ? BaseId <
O.BaseId : Offset.slt(
O.Offset);
108 GetElementPtrInst *GEP =
nullptr;
109 LoadInst *LoadI =
nullptr;
116class BaseIdentifier {
122 const auto Insertion = BaseToIndex.try_emplace(
Base, Order);
123 if (Insertion.second)
125 return Insertion.first->second;
130 DenseMap<const Value*, int> BaseToIndex;
142 if (LoadI->isUsedOutsideOfBlock(LoadI->getParent())) {
147 if (!LoadI->isSimple()) {
151 Value *Addr = LoadI->getOperand(0);
159 const auto &
DL = LoadI->getDataLayout();
160 if (!
DL.typeSizeEqualsStoreSize(LoadI->getType())) {
170 if (
GEP->isUsedOutsideOfBlock(LoadI->getParent())) {
176 Base =
GEP->getPointerOperand();
192 const ICmpInst *CmpI;
194 BCECmp(BCEAtom L, BCEAtom R,
int SizeBits,
const ICmpInst *CmpI)
195 : Lhs(std::
move(
L)), Rhs(std::
move(
R)), SizeBits(SizeBits), CmpI(CmpI) {
207 typedef SmallDenseSet<const Instruction *, 8> InstructionSet;
209 BCECmpBlock(BCECmp Cmp, BasicBlock *BB, InstructionSet BlockInsts)
210 : BB(BB), BlockInsts(std::
move(BlockInsts)), Cmp(std::
move(Cmp)) {}
212 const BCEAtom &Lhs()
const {
return Cmp.Lhs; }
213 const BCEAtom &Rhs()
const {
return Cmp.Rhs; }
214 int SizeBits()
const {
return Cmp.SizeBits; }
216 DebugLoc getCmpDebugLoc()
const {
return Cmp.CmpI->getDebugLoc(); }
219 bool doesOtherWork()
const;
225 bool canSplit(
AliasAnalysis &AA, Instruction *&SplitAt)
const;
231 bool canSinkBCECmpInst(
const Instruction *,
AliasAnalysis &AA)
const;
241 InstructionSet BlockInsts;
243 bool RequireSplit =
false;
245 unsigned OrigOrder = 0;
252bool BCECmpBlock::canSinkBCECmpInst(
const Instruction *Inst,
257 auto MayClobber = [&](LoadInst *LI) {
263 if (MayClobber(Cmp.Lhs.LoadI) || MayClobber(Cmp.Rhs.LoadI))
269 const Instruction *OpI = dyn_cast<Instruction>(Op);
270 return OpI && BlockInsts.contains(OpI);
274void BCECmpBlock::split(BasicBlock *NewParent,
AliasAnalysis &AA)
const {
275 llvm::SmallVector<Instruction *, 4> OtherInsts;
276 for (Instruction &Inst : *BB) {
277 if (BlockInsts.
count(&Inst))
279 assert(canSinkBCECmpInst(&Inst, AA) &&
"Split unsplittable block");
286 for (Instruction *Inst :
reverse(OtherInsts))
290bool BCECmpBlock::canSplit(
AliasAnalysis &AA, Instruction *&SplitAt)
const {
292 for (Instruction &Inst : *BB) {
293 if (!BlockInsts.
count(&Inst)) {
295 if (!canSinkBCECmpInst(&Inst, AA))
302bool BCECmpBlock::doesOtherWork()
const {
307 for (
const Instruction &Inst : *BB) {
308 if (!BlockInsts.
count(&Inst))
316static std::optional<BCECmp>
341 return BCECmp(std::move(Lhs), std::move(Rhs),
347static std::optional<BCECmpBlock>
349 const BasicBlock *
const PhiBlock, BaseIdentifier &BaseId) {
352 auto *Term =
Block->getTerminator();
367 if (!Const->isZero())
370 assert(BranchI->getNumSuccessors() == 2 &&
"expecting a cond branch");
371 BasicBlock *
const FalseBlock = BranchI->getSuccessor(1);
372 Cond = BranchI->getCondition();
383 std::optional<BCECmp> Result =
visitICmp(CmpI, ExpectedPredicate, BaseId);
387 BCECmpBlock::InstructionSet BlockInsts(
388 {Result->Lhs.LoadI, Result->Rhs.LoadI, Result->CmpI, Term});
390 BlockInsts.insert(Result->Lhs.GEP);
392 BlockInsts.insert(Result->Rhs.GEP);
393 return BCECmpBlock(std::move(*Result),
Block, BlockInsts);
397 BCECmpBlock &&Comparison) {
399 <<
"': Found cmp of " << Comparison.SizeBits()
400 <<
" bits between " << Comparison.Lhs().BaseId <<
" + "
401 << Comparison.Lhs().Offset <<
" and "
402 << Comparison.Rhs().BaseId <<
" + "
403 << Comparison.Rhs().Offset <<
"\n");
405 Comparison.OrigOrder = Comparisons.size();
406 Comparisons.push_back(std::move(Comparison));
413 using ContiguousBlocks = std::vector<BCECmpBlock>;
415 BCECmpChain(
const std::vector<BasicBlock *> &Blocks, PHINode &Phi,
418 bool isDereferenceable();
421 DomTreeUpdater &DTU);
423 bool atLeastOneMerged()
const {
424 return any_of(MergedBlocks_,
425 [](
const auto &Blocks) {
return Blocks.size() > 1; });
431 std::vector<ContiguousBlocks> MergedBlocks_;
441 return First.Lhs().BaseId == Second.Lhs().BaseId &&
442 First.Rhs().BaseId == Second.Rhs().BaseId &&
443 First.Lhs().Offset +
First.SizeBits() / 8 == Second.Lhs().Offset &&
444 First.Rhs().Offset +
First.SizeBits() / 8 == Second.Rhs().Offset;
448 unsigned MinOrigOrder = std::numeric_limits<unsigned>::max();
449 for (
const BCECmpBlock &
Block : Blocks)
450 MinOrigOrder = std::min(MinOrigOrder,
Block.OrigOrder);
456static std::vector<BCECmpChain::ContiguousBlocks>
458 std::vector<BCECmpChain::ContiguousBlocks> MergedBlocks;
462 [](
const BCECmpBlock &LhsBlock,
const BCECmpBlock &RhsBlock) {
463 return std::tie(LhsBlock.Lhs(), LhsBlock.Rhs()) <
464 std::tie(RhsBlock.Lhs(), RhsBlock.Rhs());
467 BCECmpChain::ContiguousBlocks *LastMergedBlock =
nullptr;
468 for (BCECmpBlock &
Block : Blocks) {
470 MergedBlocks.emplace_back();
471 LastMergedBlock = &MergedBlocks.back();
474 << LastMergedBlock->back().BB->getName() <<
"\n");
476 LastMergedBlock->push_back(std::move(
Block));
481 llvm::sort(MergedBlocks, [](
const BCECmpChain::ContiguousBlocks &LhsBlocks,
482 const BCECmpChain::ContiguousBlocks &RhsBlocks) {
489BCECmpChain::BCECmpChain(
const std::vector<BasicBlock *> &Blocks, PHINode &Phi,
492 assert(!Blocks.empty() &&
"a chain should have at least one block");
494 std::vector<BCECmpBlock> Comparisons;
495 BaseIdentifier BaseId;
498 if (
Block->hasAddressTaken()) {
505 LLVM_DEBUG(
dbgs() <<
"chain with invalid BCECmpBlock, no merge.\n");
508 if (Comparison->doesOtherWork()) {
510 <<
"' does extra work besides compare\n");
511 if (Comparisons.empty()) {
525 if (Comparison->canSplit(
AA, SplitAt)) {
527 <<
"Split initial block '" << Comparison->BB->getName()
528 <<
"' that does extra work besides compare\n");
529 Comparison->RequireSplit =
true;
534 <<
"ignoring initial block '" << Comparison->BB->getName()
535 <<
"' that does extra work besides compare\n");
568 if (Comparisons.empty()) {
569 LLVM_DEBUG(
dbgs() <<
"chain with no BCE basic blocks, no merge\n");
572 EntryBlock_ = Comparisons[0].BB;
573 MergedBlocks_ =
mergeBlocks(std::move(Comparisons));
580class MergedBlockName {
582 SmallString<16> Scratch;
586 : Name(makeName(Comparisons)) {}
587 const StringRef Name;
593 if (Comparisons.
size() == 1)
594 return Comparisons[0].BB->getName();
595 const int size = std::accumulate(Comparisons.
begin(), Comparisons.
end(), 0,
596 [](
int i,
const BCECmpBlock &Cmp) {
597 return i + Cmp.BB->getName().size();
600 return StringRef(
"", 0);
606 Scratch.reserve(
size + Comparisons.
size() - 1);
607 const auto append = [
this](StringRef str) {
608 Scratch.append(str.begin(), str.end());
610 append(Comparisons[0].BB->getName());
611 for (
int I = 1,
E = Comparisons.
size();
I <
E; ++
I) {
618 return Scratch.str();
625static std::optional<SmallVector<uint32_t, 2>>
630 if (Comparisons.
size() == 1) {
642 for (
const auto &
C : Comparisons) {
660 assert(!Comparisons.
empty() &&
"merging zero comparisons");
662 const BCECmpBlock &FirstCmp = Comparisons[0];
667 NextCmpBlock->
getParent(), InsertBefore);
671 if (FirstCmp.Lhs().GEP)
672 Lhs = Builder.Insert(FirstCmp.Lhs().GEP->clone());
674 Lhs = FirstCmp.Lhs().LoadI->getPointerOperand();
675 if (FirstCmp.Rhs().GEP)
676 Rhs = Builder.Insert(FirstCmp.Rhs().GEP->clone());
678 Rhs = FirstCmp.Rhs().LoadI->getPointerOperand();
680 Value *IsEqual =
nullptr;
688 Comparisons, [](
const BCECmpBlock &
B) {
return B.RequireSplit; });
689 if (ToSplit != Comparisons.
end()) {
691 ToSplit->split(BB,
AA);
694 if (Comparisons.
size() == 1) {
697 Instruction *
const LhsLoad = Builder.Insert(FirstCmp.Lhs().LoadI->clone());
698 Instruction *
const RhsLoad = Builder.Insert(FirstCmp.Rhs().LoadI->clone());
703 Builder.SetCurrentDebugLocation(Comparisons[0].getCmpDebugLoc());
704 IsEqual = Builder.CreateICmpEQ(LhsLoad, RhsLoad);
706 const unsigned TotalSizeBits = std::accumulate(
707 Comparisons.
begin(), Comparisons.
end(), 0u,
708 [](
int Size,
const BCECmpBlock &
C) { return Size + C.SizeBits(); });
713 for (
auto &Comparison : Comparisons)
714 OrigCmpDebugLocs.
push_back(Comparison.getCmpDebugLoc());
716 Builder.SetCurrentDebugLocation(CmpDebugLoc);
719 unsigned SizeTBits = TLI.
getSizeTSize(*Phi.getModule());
723 const auto &
DL = Phi.getDataLayout();
726 ConstantInt::get(Builder.getIntNTy(SizeTBits), TotalSizeBits / 8),
728 IsEqual = Builder.CreateICmpEQ(
729 MemCmpCall, ConstantInt::get(Builder.getIntNTy(IntBits), 0));
735 for (
auto &Comparison : Comparisons)
737 Comparison.BB->getTerminator()->getDebugLoc());
739 Builder.SetCurrentDebugLocation(BranchDebugLoc);
743 if (NextCmpBlock == PhiBB) {
745 Builder.CreateBr(PhiBB);
746 Phi.addIncoming(IsEqual, BB);
750 auto *BI = Builder.CreateCondBr(IsEqual, NextCmpBlock, PhiBB);
764bool BCECmpChain::isDereferenceable() {
772 for (
const auto &Blocks : MergedBlocks_) {
773 const BCECmpBlock &LowestBlock = Blocks.front();
774 const Value *Lhs = LowestBlock.Lhs().LoadI->getPointerOperand();
775 const Value *Rhs = LowestBlock.Rhs().LoadI->getPointerOperand();
776 const DataLayout &
DL = LowestBlock.Lhs().LoadI->getDataLayout();
778 unsigned SizeInBits = 0;
779 for (
const BCECmpBlock &
Block : Blocks)
780 SizeInBits +=
Block.SizeBits();
782 APInt
Size(64, SizeInBits / 8);
783 SimplifyQuery SQ(
DL, CxtI);
791bool BCECmpChain::simplify(
const TargetLibraryInfo &TLI,
AliasAnalysis &AA,
792 DomTreeUpdater &DTU) {
793 assert(atLeastOneMerged() &&
"simplifying trivial BCECmpChain");
794 LLVM_DEBUG(
dbgs() <<
"Simplifying comparison chain starting at block "
795 << EntryBlock_->
getName() <<
"\n");
801 for (
const auto &Blocks :
reverse(MergedBlocks_)) {
803 Blocks, InsertBefore, NextCmpBlock, Phi_, TLI, AA, DTU);
814 DTU.
applyUpdates({{DominatorTree::Delete, Pred, EntryBlock_},
815 {DominatorTree::Insert, Pred, NextCmpBlock}});
820 const bool ChainEntryIsFnEntry = EntryBlock_->
isEntryBlock();
821 if (ChainEntryIsFnEntry && DTU.
hasDomTree()) {
823 << EntryBlock_->
getName() <<
" to "
824 << NextCmpBlock->
getName() <<
"\n");
826 DTU.
applyUpdates({{DominatorTree::Delete, NextCmpBlock, EntryBlock_}});
828 EntryBlock_ =
nullptr;
831 SmallVector<BasicBlock *, 16> DeadBlocks;
832 for (
const auto &Blocks : MergedBlocks_) {
833 for (
const BCECmpBlock &
Block : Blocks) {
841 MergedBlocks_.clear();
845static std::vector<BasicBlock *>
848 std::vector<BasicBlock *> Blocks(NumBlocks);
849 assert(LastBlock &&
"invalid last block");
851 for (
int BlockIndex = NumBlocks - 1; BlockIndex > 0; --BlockIndex) {
856 <<
" has its address taken\n");
859 Blocks[BlockIndex] = CurBlock;
861 if (!SinglePredecessor) {
864 <<
" has two or more predecessors\n");
867 if (Phi.getBasicBlockIndex(SinglePredecessor) < 0) {
870 <<
" does not link back to the phi\n");
873 CurBlock = SinglePredecessor;
875 Blocks[0] = CurBlock;
882 if (Phi.getNumIncomingValues() <= 1) {
903 for (
unsigned I = 0;
I < Phi.getNumIncomingValues(); ++
I) {
912 Phi.getIncomingBlock(
I)) {
920 <<
"skip: non-constant value not from cmp or not from last block.\n");
923 LastBlock = Phi.getIncomingBlock(
I);
937 if (Blocks.empty())
return false;
938 BCECmpChain CmpChain(Blocks, Phi,
AA);
940 if (!CmpChain.atLeastOneMerged()) {
945 if (!CmpChain.isDereferenceable()) {
950 return CmpChain.simplify(TLI,
AA, DTU);
960 if (!
TTI.enableMemCmpExpansion(
F.hasOptSize(),
true))
968 DomTreeUpdater::UpdateStrategy::Eager);
970 bool MadeChange =
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 runImpl(MachineFunction &MF)
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)
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.
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.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
bool empty() const
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.
const Instruction & front() const
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; assumes that the block is well-formed.
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)
static LLVM_ABI DebugLoc getMergedLocations(ArrayRef< DebugLoc > Locs)
Try to combine the vector of locations passed as input in a single one.
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.
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 reserve(size_type N)
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
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.
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
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
Abstract Attribute helper functions.
@ C
The default llvm calling convention, compatible with C.
@ BasicBlock
Various leaf nodes.
NodeAddr< PhiNode * > Phi
friend class Instruction
Iterator for Instructions in a `BasicBlock.
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)
LLVM_ABI 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.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
LLVM_ABI bool isLibFuncEmittable(const Module *M, const TargetLibraryInfo *TLI, LibFunc TheLibFunc)
Check whether the library function is available on target and also that it in the current Module is a...
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.
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
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 bool isDereferenceablePointer(const Value *V, Type *Ty, const SimplifyQuery &Q, bool IgnoreFree=false)
Equivalent to isDereferenceableAndAlignedPointer with an alignment of 1.
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.
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)