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())) {
177 if (
GEP->isUsedOutsideOfBlock(LoadI->getParent())) {
183 Base =
GEP->getPointerOperand();
199 const ICmpInst *CmpI;
201 BCECmp(BCEAtom L, BCEAtom R,
int SizeBits,
const ICmpInst *CmpI)
202 : Lhs(std::
move(
L)), Rhs(std::
move(
R)), SizeBits(SizeBits), CmpI(CmpI) {
214 typedef SmallDenseSet<const Instruction *, 8> InstructionSet;
216 BCECmpBlock(BCECmp Cmp, BasicBlock *BB, InstructionSet BlockInsts)
217 : BB(BB), BlockInsts(std::
move(BlockInsts)), Cmp(std::
move(Cmp)) {}
219 const BCEAtom &Lhs()
const {
return Cmp.Lhs; }
220 const BCEAtom &Rhs()
const {
return Cmp.Rhs; }
221 int SizeBits()
const {
return Cmp.SizeBits; }
224 bool doesOtherWork()
const;
234 bool canSinkBCECmpInst(
const Instruction *,
AliasAnalysis &AA)
const;
244 InstructionSet BlockInsts;
246 bool RequireSplit =
false;
248 unsigned OrigOrder = 0;
255bool BCECmpBlock::canSinkBCECmpInst(
const Instruction *Inst,
260 auto MayClobber = [&](LoadInst *LI) {
266 if (MayClobber(Cmp.Lhs.LoadI) || MayClobber(Cmp.Rhs.LoadI))
272 const Instruction *OpI = dyn_cast<Instruction>(Op);
273 return OpI && BlockInsts.contains(OpI);
277void BCECmpBlock::split(BasicBlock *NewParent,
AliasAnalysis &AA)
const {
278 llvm::SmallVector<Instruction *, 4> OtherInsts;
279 for (Instruction &Inst : *BB) {
280 if (BlockInsts.
count(&Inst))
282 assert(canSinkBCECmpInst(&Inst, AA) &&
"Split unsplittable block");
289 for (Instruction *Inst :
reverse(OtherInsts))
294 for (Instruction &Inst : *BB) {
295 if (!BlockInsts.
count(&Inst)) {
296 if (!canSinkBCECmpInst(&Inst, AA))
303bool BCECmpBlock::doesOtherWork()
const {
308 for (
const Instruction &Inst : *BB) {
309 if (!BlockInsts.
count(&Inst))
317static std::optional<BCECmp>
342 return BCECmp(std::move(Lhs), std::move(Rhs),
348static std::optional<BCECmpBlock>
350 const BasicBlock *
const PhiBlock, BaseIdentifier &BaseId) {
353 auto *Term =
Block->getTerminator();
368 if (!Const->isZero())
371 assert(BranchI->getNumSuccessors() == 2 &&
"expecting a cond branch");
372 BasicBlock *
const FalseBlock = BranchI->getSuccessor(1);
373 Cond = BranchI->getCondition();
384 std::optional<BCECmp> Result =
visitICmp(CmpI, ExpectedPredicate, BaseId);
388 BCECmpBlock::InstructionSet BlockInsts(
389 {Result->Lhs.LoadI, Result->Rhs.LoadI, Result->CmpI, Term});
391 BlockInsts.insert(Result->Lhs.GEP);
393 BlockInsts.insert(Result->Rhs.GEP);
394 return BCECmpBlock(std::move(*Result),
Block, BlockInsts);
398 BCECmpBlock &&Comparison) {
400 <<
"': Found cmp of " << Comparison.SizeBits()
401 <<
" bits between " << Comparison.Lhs().BaseId <<
" + "
402 << Comparison.Lhs().Offset <<
" and "
403 << Comparison.Rhs().BaseId <<
" + "
404 << Comparison.Rhs().Offset <<
"\n");
406 Comparison.OrigOrder = Comparisons.size();
407 Comparisons.push_back(std::move(Comparison));
414 using ContiguousBlocks = std::vector<BCECmpBlock>;
416 BCECmpChain(
const std::vector<BasicBlock *> &Blocks, PHINode &Phi,
420 DomTreeUpdater &DTU);
422 bool atLeastOneMerged()
const {
423 return any_of(MergedBlocks_,
424 [](
const auto &Blocks) {
return Blocks.size() > 1; });
430 std::vector<ContiguousBlocks> MergedBlocks_;
437 return First.Lhs().BaseId == Second.Lhs().BaseId &&
438 First.Rhs().BaseId == Second.Rhs().BaseId &&
439 First.Lhs().Offset +
First.SizeBits() / 8 == Second.Lhs().Offset &&
440 First.Rhs().Offset +
First.SizeBits() / 8 == Second.Rhs().Offset;
444 unsigned MinOrigOrder = std::numeric_limits<unsigned>::max();
445 for (
const BCECmpBlock &
Block : Blocks)
446 MinOrigOrder = std::min(MinOrigOrder,
Block.OrigOrder);
452static std::vector<BCECmpChain::ContiguousBlocks>
454 std::vector<BCECmpChain::ContiguousBlocks> MergedBlocks;
458 [](
const BCECmpBlock &LhsBlock,
const BCECmpBlock &RhsBlock) {
459 return std::tie(LhsBlock.Lhs(), LhsBlock.Rhs()) <
460 std::tie(RhsBlock.Lhs(), RhsBlock.Rhs());
463 BCECmpChain::ContiguousBlocks *LastMergedBlock =
nullptr;
464 for (BCECmpBlock &
Block : Blocks) {
466 MergedBlocks.emplace_back();
467 LastMergedBlock = &MergedBlocks.back();
470 << LastMergedBlock->back().BB->getName() <<
"\n");
472 LastMergedBlock->push_back(std::move(
Block));
477 llvm::sort(MergedBlocks, [](
const BCECmpChain::ContiguousBlocks &LhsBlocks,
478 const BCECmpChain::ContiguousBlocks &RhsBlocks) {
485BCECmpChain::BCECmpChain(
const std::vector<BasicBlock *> &Blocks, PHINode &Phi,
488 assert(!Blocks.empty() &&
"a chain should have at least one block");
490 std::vector<BCECmpBlock> Comparisons;
491 BaseIdentifier BaseId;
494 if (
Block->hasAddressTaken()) {
501 LLVM_DEBUG(
dbgs() <<
"chain with invalid BCECmpBlock, no merge.\n");
504 if (Comparison->doesOtherWork()) {
506 <<
"' does extra work besides compare\n");
507 if (Comparisons.empty()) {
521 if (Comparison->canSplit(
AA)) {
523 <<
"Split initial block '" << Comparison->BB->getName()
524 <<
"' that does extra work besides compare\n");
525 Comparison->RequireSplit =
true;
529 <<
"ignoring initial block '" << Comparison->BB->getName()
530 <<
"' that does extra work besides compare\n");
563 if (Comparisons.empty()) {
564 LLVM_DEBUG(
dbgs() <<
"chain with no BCE basic blocks, no merge\n");
567 EntryBlock_ = Comparisons[0].BB;
568 MergedBlocks_ =
mergeBlocks(std::move(Comparisons));
575class MergedBlockName {
577 SmallString<16> Scratch;
581 : Name(makeName(Comparisons)) {}
582 const StringRef Name;
588 if (Comparisons.
size() == 1)
589 return Comparisons[0].BB->getName();
590 const int size = std::accumulate(Comparisons.
begin(), Comparisons.
end(), 0,
591 [](
int i,
const BCECmpBlock &Cmp) {
592 return i + Cmp.BB->getName().size();
595 return StringRef(
"", 0);
601 Scratch.reserve(
size + Comparisons.
size() - 1);
602 const auto append = [
this](StringRef str) {
603 Scratch.append(str.begin(), str.end());
605 append(Comparisons[0].BB->getName());
606 for (
int I = 1,
E = Comparisons.
size();
I <
E; ++
I) {
613 return Scratch.str();
620static 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 IsEqual = Builder.CreateICmpEQ(LhsLoad, RhsLoad);
700 const unsigned TotalSizeBits = std::accumulate(
701 Comparisons.
begin(), Comparisons.
end(), 0u,
702 [](
int Size,
const BCECmpBlock &
C) { return Size + C.SizeBits(); });
705 unsigned SizeTBits = TLI.
getSizeTSize(*Phi.getModule());
709 const auto &
DL = Phi.getDataLayout();
712 ConstantInt::get(Builder.getIntNTy(SizeTBits), TotalSizeBits / 8),
714 IsEqual = Builder.CreateICmpEQ(
715 MemCmpCall, ConstantInt::get(Builder.getIntNTy(IntBits), 0));
720 if (NextCmpBlock == PhiBB) {
722 Builder.CreateBr(PhiBB);
723 Phi.addIncoming(IsEqual, BB);
727 auto *BI = Builder.CreateCondBr(IsEqual, NextCmpBlock, PhiBB);
739 assert(atLeastOneMerged() &&
"simplifying trivial BCECmpChain");
740 LLVM_DEBUG(
dbgs() <<
"Simplifying comparison chain starting at block "
741 << EntryBlock_->
getName() <<
"\n");
747 for (
const auto &Blocks :
reverse(MergedBlocks_)) {
749 Blocks, InsertBefore, NextCmpBlock, Phi_, TLI, AA, DTU);
760 DTU.
applyUpdates({{DominatorTree::Delete, Pred, EntryBlock_},
761 {DominatorTree::Insert, Pred, NextCmpBlock}});
766 const bool ChainEntryIsFnEntry = EntryBlock_->
isEntryBlock();
767 if (ChainEntryIsFnEntry && DTU.
hasDomTree()) {
769 << EntryBlock_->
getName() <<
" to "
770 << NextCmpBlock->
getName() <<
"\n");
772 DTU.
applyUpdates({{DominatorTree::Delete, NextCmpBlock, EntryBlock_}});
774 EntryBlock_ =
nullptr;
777 SmallVector<BasicBlock *, 16> DeadBlocks;
778 for (
const auto &Blocks : MergedBlocks_) {
779 for (
const BCECmpBlock &
Block : Blocks) {
787 MergedBlocks_.clear();
791static std::vector<BasicBlock *>
794 std::vector<BasicBlock *> Blocks(NumBlocks);
795 assert(LastBlock &&
"invalid last block");
797 for (
int BlockIndex = NumBlocks - 1; BlockIndex > 0; --BlockIndex) {
802 <<
" has its address taken\n");
805 Blocks[BlockIndex] = CurBlock;
807 if (!SinglePredecessor) {
810 <<
" has two or more predecessors\n");
813 if (Phi.getBasicBlockIndex(SinglePredecessor) < 0) {
816 <<
" does not link back to the phi\n");
819 CurBlock = SinglePredecessor;
821 Blocks[0] = CurBlock;
828 if (Phi.getNumIncomingValues() <= 1) {
849 for (
unsigned I = 0;
I < Phi.getNumIncomingValues(); ++
I) {
858 Phi.getIncomingBlock(
I)) {
866 <<
"skip: non-constant value not from cmp or not from last block.\n");
869 LastBlock = Phi.getIncomingBlock(
I);
883 if (Blocks.empty())
return false;
884 BCECmpChain CmpChain(Blocks, Phi,
AA);
886 if (!CmpChain.atLeastOneMerged()) {
891 return CmpChain.simplify(TLI,
AA, DTU);
901 if (!
TTI.enableMemCmpExpansion(
F.hasOptSize(),
true))
909 DomTreeUpdater::UpdateStrategy::Eager);
911 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(Function &F, const TargetLowering &TLI, const LibcallLoweringInfo &Libcalls, AssumptionCache *AC)
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.
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)
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 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
Abstract Attribute helper functions.
@ 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 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 >
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.
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)