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; }
217 bool doesOtherWork()
const;
223 bool canSplit(
AliasAnalysis &AA, Instruction *&SplitAt)
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))
288bool BCECmpBlock::canSplit(
AliasAnalysis &AA, Instruction *&SplitAt)
const {
290 for (Instruction &Inst : *BB) {
291 if (!BlockInsts.
count(&Inst)) {
293 if (!canSinkBCECmpInst(&Inst, AA))
300bool BCECmpBlock::doesOtherWork()
const {
305 for (
const Instruction &Inst : *BB) {
306 if (!BlockInsts.
count(&Inst))
314static std::optional<BCECmp>
339 return BCECmp(std::move(Lhs), std::move(Rhs),
345static std::optional<BCECmpBlock>
347 const BasicBlock *
const PhiBlock, BaseIdentifier &BaseId) {
350 auto *Term =
Block->getTerminator();
365 if (!Const->isZero())
368 assert(BranchI->getNumSuccessors() == 2 &&
"expecting a cond branch");
369 BasicBlock *
const FalseBlock = BranchI->getSuccessor(1);
370 Cond = BranchI->getCondition();
381 std::optional<BCECmp> Result =
visitICmp(CmpI, ExpectedPredicate, BaseId);
385 BCECmpBlock::InstructionSet BlockInsts(
386 {Result->Lhs.LoadI, Result->Rhs.LoadI, Result->CmpI, Term});
388 BlockInsts.insert(Result->Lhs.GEP);
390 BlockInsts.insert(Result->Rhs.GEP);
391 return BCECmpBlock(std::move(*Result),
Block, BlockInsts);
395 BCECmpBlock &&Comparison) {
397 <<
"': Found cmp of " << Comparison.SizeBits()
398 <<
" bits between " << Comparison.Lhs().BaseId <<
" + "
399 << Comparison.Lhs().Offset <<
" and "
400 << Comparison.Rhs().BaseId <<
" + "
401 << Comparison.Rhs().Offset <<
"\n");
403 Comparison.OrigOrder = Comparisons.size();
404 Comparisons.push_back(std::move(Comparison));
411 using ContiguousBlocks = std::vector<BCECmpBlock>;
413 BCECmpChain(
const std::vector<BasicBlock *> &Blocks, PHINode &Phi,
416 bool isDereferenceable();
419 DomTreeUpdater &DTU);
421 bool atLeastOneMerged()
const {
422 return any_of(MergedBlocks_,
423 [](
const auto &Blocks) {
return Blocks.size() > 1; });
429 std::vector<ContiguousBlocks> MergedBlocks_;
439 return First.Lhs().BaseId == Second.Lhs().BaseId &&
440 First.Rhs().BaseId == Second.Rhs().BaseId &&
441 First.Lhs().Offset +
First.SizeBits() / 8 == Second.Lhs().Offset &&
442 First.Rhs().Offset +
First.SizeBits() / 8 == Second.Rhs().Offset;
446 unsigned MinOrigOrder = std::numeric_limits<unsigned>::max();
447 for (
const BCECmpBlock &
Block : Blocks)
448 MinOrigOrder = std::min(MinOrigOrder,
Block.OrigOrder);
454static std::vector<BCECmpChain::ContiguousBlocks>
456 std::vector<BCECmpChain::ContiguousBlocks> MergedBlocks;
460 [](
const BCECmpBlock &LhsBlock,
const BCECmpBlock &RhsBlock) {
461 return std::tie(LhsBlock.Lhs(), LhsBlock.Rhs()) <
462 std::tie(RhsBlock.Lhs(), RhsBlock.Rhs());
465 BCECmpChain::ContiguousBlocks *LastMergedBlock =
nullptr;
466 for (BCECmpBlock &
Block : Blocks) {
468 MergedBlocks.emplace_back();
469 LastMergedBlock = &MergedBlocks.back();
472 << LastMergedBlock->back().BB->getName() <<
"\n");
474 LastMergedBlock->push_back(std::move(
Block));
479 llvm::sort(MergedBlocks, [](
const BCECmpChain::ContiguousBlocks &LhsBlocks,
480 const BCECmpChain::ContiguousBlocks &RhsBlocks) {
487BCECmpChain::BCECmpChain(
const std::vector<BasicBlock *> &Blocks, PHINode &Phi,
490 assert(!Blocks.empty() &&
"a chain should have at least one block");
492 std::vector<BCECmpBlock> Comparisons;
493 BaseIdentifier BaseId;
496 if (
Block->hasAddressTaken()) {
503 LLVM_DEBUG(
dbgs() <<
"chain with invalid BCECmpBlock, no merge.\n");
506 if (Comparison->doesOtherWork()) {
508 <<
"' does extra work besides compare\n");
509 if (Comparisons.empty()) {
523 if (Comparison->canSplit(
AA, SplitAt)) {
525 <<
"Split initial block '" << Comparison->BB->getName()
526 <<
"' that does extra work besides compare\n");
527 Comparison->RequireSplit =
true;
532 <<
"ignoring initial block '" << Comparison->BB->getName()
533 <<
"' that does extra work besides compare\n");
566 if (Comparisons.empty()) {
567 LLVM_DEBUG(
dbgs() <<
"chain with no BCE basic blocks, no merge\n");
570 EntryBlock_ = Comparisons[0].BB;
571 MergedBlocks_ =
mergeBlocks(std::move(Comparisons));
578class MergedBlockName {
580 SmallString<16> Scratch;
584 : Name(makeName(Comparisons)) {}
585 const StringRef Name;
591 if (Comparisons.
size() == 1)
592 return Comparisons[0].BB->getName();
593 const int size = std::accumulate(Comparisons.
begin(), Comparisons.
end(), 0,
594 [](
int i,
const BCECmpBlock &Cmp) {
595 return i + Cmp.BB->getName().size();
598 return StringRef(
"", 0);
604 Scratch.reserve(
size + Comparisons.
size() - 1);
605 const auto append = [
this](StringRef str) {
606 Scratch.append(str.begin(), str.end());
608 append(Comparisons[0].BB->getName());
609 for (
int I = 1,
E = Comparisons.
size();
I <
E; ++
I) {
616 return Scratch.str();
623static std::optional<SmallVector<uint32_t, 2>>
628 if (Comparisons.
size() == 1) {
640 for (
const auto &
C : Comparisons) {
658 assert(!Comparisons.
empty() &&
"merging zero comparisons");
660 const BCECmpBlock &FirstCmp = Comparisons[0];
665 NextCmpBlock->
getParent(), InsertBefore);
669 if (FirstCmp.Lhs().GEP)
670 Lhs = Builder.Insert(FirstCmp.Lhs().GEP->clone());
672 Lhs = FirstCmp.Lhs().LoadI->getPointerOperand();
673 if (FirstCmp.Rhs().GEP)
674 Rhs = Builder.Insert(FirstCmp.Rhs().GEP->clone());
676 Rhs = FirstCmp.Rhs().LoadI->getPointerOperand();
678 Value *IsEqual =
nullptr;
686 Comparisons, [](
const BCECmpBlock &
B) {
return B.RequireSplit; });
687 if (ToSplit != Comparisons.
end()) {
689 ToSplit->split(BB,
AA);
692 if (Comparisons.
size() == 1) {
695 Instruction *
const LhsLoad = Builder.Insert(FirstCmp.Lhs().LoadI->clone());
696 Instruction *
const RhsLoad = Builder.Insert(FirstCmp.Rhs().LoadI->clone());
701 IsEqual = Builder.CreateICmpEQ(LhsLoad, RhsLoad);
703 const unsigned TotalSizeBits = std::accumulate(
704 Comparisons.
begin(), Comparisons.
end(), 0u,
705 [](
int Size,
const BCECmpBlock &
C) { return Size + C.SizeBits(); });
708 unsigned SizeTBits = TLI.
getSizeTSize(*Phi.getModule());
712 const auto &
DL = Phi.getDataLayout();
715 ConstantInt::get(Builder.getIntNTy(SizeTBits), TotalSizeBits / 8),
717 IsEqual = Builder.CreateICmpEQ(
718 MemCmpCall, ConstantInt::get(Builder.getIntNTy(IntBits), 0));
723 if (NextCmpBlock == PhiBB) {
725 Builder.CreateBr(PhiBB);
726 Phi.addIncoming(IsEqual, BB);
730 auto *BI = Builder.CreateCondBr(IsEqual, NextCmpBlock, PhiBB);
744bool BCECmpChain::isDereferenceable() {
752 for (
const auto &Blocks : MergedBlocks_) {
753 const BCECmpBlock &LowestBlock = Blocks.front();
754 const Value *Lhs = LowestBlock.Lhs().LoadI->getPointerOperand();
755 const Value *Rhs = LowestBlock.Rhs().LoadI->getPointerOperand();
756 const DataLayout &
DL = LowestBlock.Lhs().LoadI->getDataLayout();
758 unsigned SizeInBits = 0;
759 for (
const BCECmpBlock &
Block : Blocks)
760 SizeInBits +=
Block.SizeBits();
762 APInt
Size(64, SizeInBits / 8);
763 SimplifyQuery SQ(
DL, CxtI);
771bool BCECmpChain::simplify(
const TargetLibraryInfo &TLI,
AliasAnalysis &AA,
772 DomTreeUpdater &DTU) {
773 assert(atLeastOneMerged() &&
"simplifying trivial BCECmpChain");
774 LLVM_DEBUG(
dbgs() <<
"Simplifying comparison chain starting at block "
775 << EntryBlock_->
getName() <<
"\n");
781 for (
const auto &Blocks :
reverse(MergedBlocks_)) {
783 Blocks, InsertBefore, NextCmpBlock, Phi_, TLI, AA, DTU);
794 DTU.
applyUpdates({{DominatorTree::Delete, Pred, EntryBlock_},
795 {DominatorTree::Insert, Pred, NextCmpBlock}});
800 const bool ChainEntryIsFnEntry = EntryBlock_->
isEntryBlock();
801 if (ChainEntryIsFnEntry && DTU.
hasDomTree()) {
803 << EntryBlock_->
getName() <<
" to "
804 << NextCmpBlock->
getName() <<
"\n");
806 DTU.
applyUpdates({{DominatorTree::Delete, NextCmpBlock, EntryBlock_}});
808 EntryBlock_ =
nullptr;
811 SmallVector<BasicBlock *, 16> DeadBlocks;
812 for (
const auto &Blocks : MergedBlocks_) {
813 for (
const BCECmpBlock &
Block : Blocks) {
821 MergedBlocks_.clear();
825static std::vector<BasicBlock *>
828 std::vector<BasicBlock *> Blocks(NumBlocks);
829 assert(LastBlock &&
"invalid last block");
831 for (
int BlockIndex = NumBlocks - 1; BlockIndex > 0; --BlockIndex) {
836 <<
" has its address taken\n");
839 Blocks[BlockIndex] = CurBlock;
841 if (!SinglePredecessor) {
844 <<
" has two or more predecessors\n");
847 if (Phi.getBasicBlockIndex(SinglePredecessor) < 0) {
850 <<
" does not link back to the phi\n");
853 CurBlock = SinglePredecessor;
855 Blocks[0] = CurBlock;
862 if (Phi.getNumIncomingValues() <= 1) {
883 for (
unsigned I = 0;
I < Phi.getNumIncomingValues(); ++
I) {
892 Phi.getIncomingBlock(
I)) {
900 <<
"skip: non-constant value not from cmp or not from last block.\n");
903 LastBlock = Phi.getIncomingBlock(
I);
917 if (Blocks.empty())
return false;
918 BCECmpChain CmpChain(Blocks, Phi,
AA);
920 if (!CmpChain.atLeastOneMerged()) {
925 if (!CmpChain.isDereferenceable()) {
930 return CmpChain.simplify(TLI,
AA, DTU);
940 if (!
TTI.enableMemCmpExpansion(
F.hasOptSize(),
true))
948 DomTreeUpdater::UpdateStrategy::Eager);
950 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.
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)
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
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
Abstract Attribute helper functions.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
@ 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)
FunctionAddr VTableAddr Value
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.
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
LLVM_ABI bool isDereferenceableAndAlignedPointer(const Value *V, Type *Ty, Align Alignment, const SimplifyQuery &Q, bool IgnoreFree=false)
Returns true if V is always a dereferenceable pointer with alignment greater or equal than requested.
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.
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)