65#define DEBUG_TYPE "mergeicmps"
77 BCEAtom(
const BCEAtom &) =
delete;
78 BCEAtom &operator=(
const BCEAtom &) =
delete;
80 BCEAtom(BCEAtom &&that) =
default;
81 BCEAtom &operator=(BCEAtom &&that) {
87 Offset = std::move(that.Offset);
102 return BaseId != O.BaseId ? BaseId < O.BaseId :
Offset.slt(O.Offset);
113class BaseIdentifier {
119 const auto Insertion = BaseToIndex.try_emplace(
Base, Order);
120 if (Insertion.second)
122 return Insertion.first->second;
139 if (LoadI->isUsedOutsideOfBlock(LoadI->getParent())) {
144 if (!LoadI->isSimple()) {
148 Value *Addr = LoadI->getOperand(0);
156 const auto &
DL = LoadI->getDataLayout();
157 if (!
DL.typeSizeEqualsStoreSize(LoadI->getType())) {
167 if (
GEP->isUsedOutsideOfBlock(LoadI->getParent())) {
173 Base =
GEP->getPointerOperand();
189 const ICmpInst *CmpI;
191 BCECmp(BCEAtom L, BCEAtom R,
int SizeBits,
const ICmpInst *CmpI)
192 : Lhs(std::
move(
L)), Rhs(std::
move(
R)), SizeBits(SizeBits), CmpI(CmpI) {
204 typedef SmallDenseSet<const Instruction *, 8> InstructionSet;
206 BCECmpBlock(BCECmp Cmp, BasicBlock *BB, InstructionSet BlockInsts)
207 : BB(BB), BlockInsts(std::
move(BlockInsts)), Cmp(std::
move(Cmp)) {}
209 const BCEAtom &Lhs()
const {
return Cmp.Lhs; }
210 const BCEAtom &Rhs()
const {
return Cmp.Rhs; }
211 int SizeBits()
const {
return Cmp.SizeBits; }
213 DebugLoc getCmpDebugLoc()
const {
return Cmp.CmpI->getDebugLoc(); }
216 bool doesOtherWork()
const;
222 bool canSplit(
AliasAnalysis &AA, Instruction *&SplitAt)
const;
228 bool canSinkBCECmpInst(
const Instruction *,
AliasAnalysis &AA)
const;
238 InstructionSet BlockInsts;
240 bool RequireSplit =
false;
242 unsigned OrigOrder = 0;
249bool BCECmpBlock::canSinkBCECmpInst(
const Instruction *Inst,
254 auto MayClobber = [&](LoadInst *LI) {
260 if (MayClobber(Cmp.Lhs.LoadI) || MayClobber(Cmp.Rhs.LoadI))
266 const Instruction *OpI = dyn_cast<Instruction>(Op);
267 return OpI && BlockInsts.contains(OpI);
271void BCECmpBlock::split(BasicBlock *NewParent,
AliasAnalysis &AA)
const {
272 llvm::SmallVector<Instruction *, 4> OtherInsts;
273 for (Instruction &Inst : *BB) {
274 if (BlockInsts.
count(&Inst))
276 assert(canSinkBCECmpInst(&Inst, AA) &&
"Split unsplittable block");
283 for (Instruction *Inst :
reverse(OtherInsts))
287bool BCECmpBlock::canSplit(
AliasAnalysis &AA, Instruction *&SplitAt)
const {
289 for (Instruction &Inst : *BB) {
290 if (!BlockInsts.
count(&Inst)) {
292 if (!canSinkBCECmpInst(&Inst, AA))
299bool BCECmpBlock::doesOtherWork()
const {
304 for (
const Instruction &Inst : *BB) {
305 if (!BlockInsts.
count(&Inst))
313static std::optional<BCECmp>
338 return BCECmp(std::move(Lhs), std::move(Rhs),
344static std::optional<BCECmpBlock>
346 const BasicBlock *
const PhiBlock, BaseIdentifier &BaseId) {
349 auto *Term =
Block->getTerminator();
364 if (!Const->isZero())
367 assert(BranchI->getNumSuccessors() == 2 &&
"expecting a cond branch");
368 BasicBlock *
const FalseBlock = BranchI->getSuccessor(1);
369 Cond = BranchI->getCondition();
380 std::optional<BCECmp> Result =
visitICmp(CmpI, ExpectedPredicate, BaseId);
384 BCECmpBlock::InstructionSet BlockInsts(
385 {Result->Lhs.LoadI, Result->Rhs.LoadI, Result->CmpI, Term});
387 BlockInsts.insert(Result->Lhs.GEP);
389 BlockInsts.insert(Result->Rhs.GEP);
390 return BCECmpBlock(std::move(*Result),
Block, BlockInsts);
394 BCECmpBlock &&Comparison) {
396 <<
"': Found cmp of " << Comparison.SizeBits()
397 <<
" bits between " << Comparison.Lhs().BaseId <<
" + "
398 << Comparison.Lhs().Offset <<
" and "
399 << Comparison.Rhs().BaseId <<
" + "
400 << Comparison.Rhs().Offset <<
"\n");
402 Comparison.OrigOrder = Comparisons.size();
403 Comparisons.push_back(std::move(Comparison));
410 using ContiguousBlocks = std::vector<BCECmpBlock>;
412 BCECmpChain(
const std::vector<BasicBlock *> &Blocks, PHINode &Phi,
415 bool isDereferenceable();
418 DomTreeUpdater &DTU);
420 bool atLeastOneMerged()
const {
421 return any_of(MergedBlocks_,
422 [](
const auto &Blocks) {
return Blocks.size() > 1; });
428 std::vector<ContiguousBlocks> MergedBlocks_;
438 return First.Lhs().BaseId == Second.Lhs().BaseId &&
439 First.Rhs().BaseId == Second.Rhs().BaseId &&
440 First.Lhs().Offset +
First.SizeBits() / 8 == Second.Lhs().Offset &&
441 First.Rhs().Offset +
First.SizeBits() / 8 == Second.Rhs().Offset;
445 unsigned MinOrigOrder = std::numeric_limits<unsigned>::max();
446 for (
const BCECmpBlock &
Block : Blocks)
447 MinOrigOrder = std::min(MinOrigOrder,
Block.OrigOrder);
453static std::vector<BCECmpChain::ContiguousBlocks>
455 std::vector<BCECmpChain::ContiguousBlocks> MergedBlocks;
459 [](
const BCECmpBlock &LhsBlock,
const BCECmpBlock &RhsBlock) {
460 return std::tie(LhsBlock.Lhs(), LhsBlock.Rhs()) <
461 std::tie(RhsBlock.Lhs(), RhsBlock.Rhs());
464 BCECmpChain::ContiguousBlocks *LastMergedBlock =
nullptr;
465 for (BCECmpBlock &
Block : Blocks) {
467 MergedBlocks.emplace_back();
468 LastMergedBlock = &MergedBlocks.back();
471 << LastMergedBlock->back().BB->getName() <<
"\n");
473 LastMergedBlock->push_back(std::move(
Block));
478 llvm::sort(MergedBlocks, [](
const BCECmpChain::ContiguousBlocks &LhsBlocks,
479 const BCECmpChain::ContiguousBlocks &RhsBlocks) {
486BCECmpChain::BCECmpChain(
const std::vector<BasicBlock *> &Blocks, PHINode &Phi,
489 assert(!Blocks.empty() &&
"a chain should have at least one block");
491 std::vector<BCECmpBlock> Comparisons;
492 BaseIdentifier BaseId;
495 if (
Block->hasAddressTaken()) {
502 LLVM_DEBUG(
dbgs() <<
"chain with invalid BCECmpBlock, no merge.\n");
505 if (Comparison->doesOtherWork()) {
507 <<
"' does extra work besides compare\n");
508 if (Comparisons.empty()) {
522 if (Comparison->canSplit(
AA, SplitAt)) {
524 <<
"Split initial block '" << Comparison->BB->getName()
525 <<
"' that does extra work besides compare\n");
526 Comparison->RequireSplit =
true;
531 <<
"ignoring initial block '" << Comparison->BB->getName()
532 <<
"' that does extra work besides compare\n");
565 if (Comparisons.empty()) {
566 LLVM_DEBUG(
dbgs() <<
"chain with no BCE basic blocks, no merge\n");
569 EntryBlock_ = Comparisons[0].BB;
570 MergedBlocks_ =
mergeBlocks(std::move(Comparisons));
577class MergedBlockName {
579 SmallString<16> Scratch;
583 : Name(makeName(Comparisons)) {}
584 const StringRef Name;
590 if (Comparisons.
size() == 1)
591 return Comparisons[0].BB->getName();
592 const int size = std::accumulate(Comparisons.
begin(), Comparisons.
end(), 0,
593 [](
int i,
const BCECmpBlock &Cmp) {
594 return i + Cmp.BB->getName().size();
597 return StringRef(
"", 0);
603 Scratch.reserve(
size + Comparisons.
size() - 1);
604 const auto append = [
this](StringRef str) {
605 Scratch.append(str.begin(), str.end());
607 append(Comparisons[0].BB->getName());
608 for (
int I = 1,
E = Comparisons.
size();
I <
E; ++
I) {
615 return Scratch.str();
622static std::optional<SmallVector<uint32_t, 2>>
625 if (Comparisons.
size() == 1) {
637 for (
const auto &
C : Comparisons) {
655 assert(!Comparisons.
empty() &&
"merging zero comparisons");
657 const BCECmpBlock &FirstCmp = Comparisons[0];
662 NextCmpBlock->
getParent(), InsertBefore);
666 if (FirstCmp.Lhs().GEP)
667 Lhs = Builder.Insert(FirstCmp.Lhs().GEP->clone());
669 Lhs = FirstCmp.Lhs().LoadI->getPointerOperand();
670 if (FirstCmp.Rhs().GEP)
671 Rhs = Builder.Insert(FirstCmp.Rhs().GEP->clone());
673 Rhs = FirstCmp.Rhs().LoadI->getPointerOperand();
675 Value *IsEqual =
nullptr;
683 Comparisons, [](
const BCECmpBlock &
B) {
return B.RequireSplit; });
684 if (ToSplit != Comparisons.
end()) {
686 ToSplit->split(BB,
AA);
689 if (Comparisons.
size() == 1) {
692 Instruction *
const LhsLoad = Builder.Insert(FirstCmp.Lhs().LoadI->clone());
693 Instruction *
const RhsLoad = Builder.Insert(FirstCmp.Rhs().LoadI->clone());
698 Builder.SetCurrentDebugLocation(Comparisons[0].getCmpDebugLoc());
699 IsEqual = Builder.CreateICmpEQ(LhsLoad, RhsLoad);
701 const unsigned TotalSizeBits = std::accumulate(
702 Comparisons.
begin(), Comparisons.
end(), 0u,
703 [](
int Size,
const BCECmpBlock &
C) { return Size + C.SizeBits(); });
708 for (
auto &Comparison : Comparisons)
709 OrigCmpDebugLocs.
push_back(Comparison.getCmpDebugLoc());
711 Builder.SetCurrentDebugLocation(CmpDebugLoc);
714 unsigned SizeTBits = TLI.
getSizeTSize(*Phi.getModule());
718 const auto &
DL = Phi.getDataLayout();
721 ConstantInt::get(Builder.getIntNTy(SizeTBits), TotalSizeBits / 8),
723 IsEqual = Builder.CreateICmpEQ(
724 MemCmpCall, ConstantInt::get(Builder.getIntNTy(IntBits), 0));
730 for (
auto &Comparison : Comparisons)
732 Comparison.BB->getTerminator()->getDebugLoc());
734 Builder.SetCurrentDebugLocation(BranchDebugLoc);
738 if (NextCmpBlock == PhiBB) {
740 Builder.CreateBr(PhiBB);
741 Phi.addIncoming(IsEqual, BB);
745 auto *BI = Builder.CreateCondBr(IsEqual, NextCmpBlock, PhiBB);
759bool BCECmpChain::isDereferenceable() {
767 for (
const auto &Blocks : MergedBlocks_) {
768 const BCECmpBlock &LowestBlock = Blocks.front();
769 const Value *Lhs = LowestBlock.Lhs().LoadI->getPointerOperand();
770 const Value *Rhs = LowestBlock.Rhs().LoadI->getPointerOperand();
771 const DataLayout &
DL = LowestBlock.Lhs().LoadI->getDataLayout();
773 unsigned SizeInBits = 0;
774 for (
const BCECmpBlock &
Block : Blocks)
775 SizeInBits +=
Block.SizeBits();
777 APInt
Size(64, SizeInBits / 8);
778 SimplifyQuery SQ(
DL, CxtI);
786bool BCECmpChain::simplify(
const TargetLibraryInfo &TLI,
AliasAnalysis &AA,
787 DomTreeUpdater &DTU) {
788 assert(atLeastOneMerged() &&
"simplifying trivial BCECmpChain");
789 LLVM_DEBUG(
dbgs() <<
"Simplifying comparison chain starting at block "
790 << EntryBlock_->
getName() <<
"\n");
796 for (
const auto &Blocks :
reverse(MergedBlocks_)) {
798 Blocks, InsertBefore, NextCmpBlock, Phi_, TLI, AA, DTU);
809 DTU.
applyUpdates({{DominatorTree::Delete, Pred, EntryBlock_},
810 {DominatorTree::Insert, Pred, NextCmpBlock}});
815 const bool ChainEntryIsFnEntry = EntryBlock_->
isEntryBlock();
816 if (ChainEntryIsFnEntry && DTU.
hasDomTree()) {
818 << EntryBlock_->
getName() <<
" to "
819 << NextCmpBlock->
getName() <<
"\n");
821 DTU.
applyUpdates({{DominatorTree::Delete, NextCmpBlock, EntryBlock_}});
823 EntryBlock_ =
nullptr;
826 SmallVector<BasicBlock *, 16> DeadBlocks;
827 for (
const auto &Blocks : MergedBlocks_) {
828 for (
const BCECmpBlock &
Block : Blocks) {
836 MergedBlocks_.clear();
840static std::vector<BasicBlock *>
843 std::vector<BasicBlock *> Blocks(NumBlocks);
844 assert(LastBlock &&
"invalid last block");
846 for (
int BlockIndex = NumBlocks - 1; BlockIndex > 0; --BlockIndex) {
851 <<
" has its address taken\n");
854 Blocks[BlockIndex] = CurBlock;
856 if (!SinglePredecessor) {
859 <<
" has two or more predecessors\n");
862 if (Phi.getBasicBlockIndex(SinglePredecessor) < 0) {
865 <<
" does not link back to the phi\n");
868 CurBlock = SinglePredecessor;
870 Blocks[0] = CurBlock;
877 if (Phi.getNumIncomingValues() <= 1) {
898 for (
unsigned I = 0;
I < Phi.getNumIncomingValues(); ++
I) {
907 Phi.getIncomingBlock(
I)) {
915 <<
"skip: non-constant value not from cmp or not from last block.\n");
918 LastBlock = Phi.getIncomingBlock(
I);
932 if (Blocks.empty())
return false;
933 BCECmpChain CmpChain(Blocks, Phi,
AA);
935 if (!CmpChain.atLeastOneMerged()) {
940 if (!CmpChain.isDereferenceable()) {
945 return CmpChain.simplify(TLI,
AA, DTU);
955 if (!
TTI.enableMemCmpExpansion(
F.hasOptSize(),
true))
963 DomTreeUpdater::UpdateStrategy::Eager);
965 bool MadeChange =
false;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
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.
An instruction for reading from memory.
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.
@ 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)
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)