67#define DEBUG_TYPE "mergeicmps" 
   79  BCEAtom(
const BCEAtom &) = 
delete;
 
   80  BCEAtom &operator=(
const BCEAtom &) = 
delete;
 
   82  BCEAtom(BCEAtom &&that) = 
default;
 
   83  BCEAtom &operator=(BCEAtom &&that) {
 
   89    Offset = std::move(that.Offset);
 
  104    return BaseId != O.BaseId ? BaseId < O.BaseId : 
Offset.slt(O.Offset);
 
  115class BaseIdentifier {
 
  121    const auto Insertion = BaseToIndex.try_emplace(
Base, Order);
 
  122    if (Insertion.second)
 
  124    return Insertion.first->second;
 
  141  if (LoadI->isUsedOutsideOfBlock(LoadI->getParent())) {
 
  146  if (!LoadI->isSimple()) {
 
  150  Value *Addr = LoadI->getOperand(0);
 
  155  const auto &
DL = LoadI->getDataLayout();
 
  168    if (
GEP->isUsedOutsideOfBlock(LoadI->getParent())) {
 
  174    Base = 
GEP->getPointerOperand();
 
 
  190  const ICmpInst *CmpI;
 
  192  BCECmp(BCEAtom L, BCEAtom R, 
int SizeBits, 
const ICmpInst *CmpI)
 
  193      : Lhs(std::
move(
L)), Rhs(std::
move(
R)), SizeBits(SizeBits), CmpI(CmpI) {
 
  205  typedef SmallDenseSet<const Instruction *, 8> InstructionSet;
 
  207  BCECmpBlock(BCECmp Cmp, BasicBlock *BB, InstructionSet BlockInsts)
 
  208      : BB(BB), BlockInsts(std::
move(BlockInsts)), Cmp(std::
move(Cmp)) {}
 
  210  const BCEAtom &Lhs()
 const { 
return Cmp.Lhs; }
 
  211  const BCEAtom &Rhs()
 const { 
return Cmp.Rhs; }
 
  212  int SizeBits()
 const { 
return Cmp.SizeBits; }
 
  215  bool doesOtherWork() 
const;
 
  225  bool canSinkBCECmpInst(
const Instruction *, 
AliasAnalysis &AA) 
const;
 
  235  InstructionSet BlockInsts;
 
  237  bool RequireSplit = 
false;
 
  239  unsigned OrigOrder = 0;
 
  246bool BCECmpBlock::canSinkBCECmpInst(
const Instruction *Inst,
 
  251    auto MayClobber = [&](LoadInst *LI) {
 
  257    if (MayClobber(Cmp.Lhs.LoadI) || MayClobber(Cmp.Rhs.LoadI))
 
  263    const Instruction *OpI = dyn_cast<Instruction>(Op);
 
  264    return OpI && BlockInsts.contains(OpI);
 
  268void BCECmpBlock::split(BasicBlock *NewParent, 
AliasAnalysis &AA)
 const {
 
  269  llvm::SmallVector<Instruction *, 4> OtherInsts;
 
  270  for (Instruction &Inst : *BB) {
 
  271    if (BlockInsts.
count(&Inst))
 
  273    assert(canSinkBCECmpInst(&Inst, AA) && 
"Split unsplittable block");
 
  280  for (Instruction *Inst : 
reverse(OtherInsts))
 
  285  for (Instruction &Inst : *BB) {
 
  286    if (!BlockInsts.
count(&Inst)) {
 
  287      if (!canSinkBCECmpInst(&Inst, AA))
 
  294bool BCECmpBlock::doesOtherWork()
 const {
 
  299  for (
const Instruction &Inst : *BB) {
 
  300    if (!BlockInsts.
count(&Inst))
 
  308static std::optional<BCECmp>
 
  332  return BCECmp(std::move(Lhs), std::move(Rhs),
 
 
  338static std::optional<BCECmpBlock>
 
  340              const BasicBlock *
const PhiBlock, BaseIdentifier &BaseId) {
 
  349  if (BranchI->isUnconditional()) {
 
  361    if (!Const->isZero())
 
  364    assert(BranchI->getNumSuccessors() == 2 && 
"expecting a cond branch");
 
  365    BasicBlock *
const FalseBlock = BranchI->getSuccessor(1);
 
  366    Cond = BranchI->getCondition();
 
  376  std::optional<BCECmp> Result = 
visitICmp(CmpI, ExpectedPredicate, BaseId);
 
  380  BCECmpBlock::InstructionSet BlockInsts(
 
  381      {Result->Lhs.LoadI, Result->Rhs.LoadI, Result->CmpI, BranchI});
 
  383    BlockInsts.insert(Result->Lhs.GEP);
 
  385    BlockInsts.insert(Result->Rhs.GEP);
 
  386  return BCECmpBlock(std::move(*Result), 
Block, BlockInsts);
 
 
  390                                BCECmpBlock &&Comparison) {
 
  392                    << 
"': Found cmp of " << Comparison.SizeBits()
 
  393                    << 
" bits between " << Comparison.Lhs().BaseId << 
" + " 
  394                    << Comparison.Lhs().Offset << 
" and " 
  395                    << Comparison.Rhs().BaseId << 
" + " 
  396                    << Comparison.Rhs().Offset << 
"\n");
 
  398  Comparison.OrigOrder = Comparisons.size();
 
  399  Comparisons.push_back(std::move(Comparison));
 
 
  406  using ContiguousBlocks = std::vector<BCECmpBlock>;
 
  408  BCECmpChain(
const std::vector<BasicBlock *> &Blocks, PHINode &Phi,
 
  412                DomTreeUpdater &DTU);
 
  414  bool atLeastOneMerged()
 const {
 
  415    return any_of(MergedBlocks_,
 
  416                  [](
const auto &Blocks) { 
return Blocks.size() > 1; });
 
  422  std::vector<ContiguousBlocks> MergedBlocks_;
 
  429  return First.Lhs().BaseId == Second.Lhs().BaseId &&
 
  430         First.Rhs().BaseId == Second.Rhs().BaseId &&
 
  431         First.Lhs().Offset + 
First.SizeBits() / 8 == Second.Lhs().Offset &&
 
  432         First.Rhs().Offset + 
First.SizeBits() / 8 == Second.Rhs().Offset;
 
 
  436  unsigned MinOrigOrder = std::numeric_limits<unsigned>::max();
 
  437  for (
const BCECmpBlock &
Block : Blocks)
 
  438    MinOrigOrder = std::min(MinOrigOrder, 
Block.OrigOrder);
 
 
  444static std::vector<BCECmpChain::ContiguousBlocks>
 
  446  std::vector<BCECmpChain::ContiguousBlocks> MergedBlocks;
 
  450             [](
const BCECmpBlock &LhsBlock, 
const BCECmpBlock &RhsBlock) {
 
  451               return std::tie(LhsBlock.Lhs(), LhsBlock.Rhs()) <
 
  452                      std::tie(RhsBlock.Lhs(), RhsBlock.Rhs());
 
  455  BCECmpChain::ContiguousBlocks *LastMergedBlock = 
nullptr;
 
  456  for (BCECmpBlock &
Block : Blocks) {
 
  458      MergedBlocks.emplace_back();
 
  459      LastMergedBlock = &MergedBlocks.back();
 
  462                        << LastMergedBlock->back().BB->getName() << 
"\n");
 
  464    LastMergedBlock->push_back(std::move(
Block));
 
  469  llvm::sort(MergedBlocks, [](
const BCECmpChain::ContiguousBlocks &LhsBlocks,
 
  470                              const BCECmpChain::ContiguousBlocks &RhsBlocks) {
 
 
  477BCECmpChain::BCECmpChain(
const std::vector<BasicBlock *> &Blocks, PHINode &Phi,
 
  480  assert(!Blocks.empty() && 
"a chain should have at least one block");
 
  482  std::vector<BCECmpBlock> Comparisons;
 
  483  BaseIdentifier BaseId;
 
  486    if (
Block->hasAddressTaken()) {
 
  493      LLVM_DEBUG(
dbgs() << 
"chain with invalid BCECmpBlock, no merge.\n");
 
  496    if (Comparison->doesOtherWork()) {
 
  498                        << 
"' does extra work besides compare\n");
 
  499      if (Comparisons.empty()) {
 
  513        if (Comparison->canSplit(
AA)) {
 
  515                     << 
"Split initial block '" << Comparison->BB->getName()
 
  516                     << 
"' that does extra work besides compare\n");
 
  517          Comparison->RequireSplit = 
true;
 
  521                     << 
"ignoring initial block '" << Comparison->BB->getName()
 
  522                     << 
"' that does extra work besides compare\n");
 
  555  if (Comparisons.empty()) {
 
  556    LLVM_DEBUG(
dbgs() << 
"chain with no BCE basic blocks, no merge\n");
 
  559  EntryBlock_ = Comparisons[0].BB;
 
  560  MergedBlocks_ = 
mergeBlocks(std::move(Comparisons));
 
  567class MergedBlockName {
 
  569  SmallString<16> Scratch;
 
  573      : Name(makeName(Comparisons)) {}
 
  574  const StringRef Name;
 
  580    if (Comparisons.
size() == 1)
 
  581      return Comparisons[0].BB->getName();
 
  582    const int size = std::accumulate(Comparisons.
begin(), Comparisons.
end(), 0,
 
  583                                     [](
int i, 
const BCECmpBlock &Cmp) {
 
  584                                       return i + Cmp.BB->getName().size();
 
  587      return StringRef(
"", 0);
 
  593    Scratch.reserve(
size + Comparisons.
size() - 1);
 
  594    const auto append = [
this](StringRef str) {
 
  595      Scratch.append(str.begin(), str.end());
 
  597    append(Comparisons[0].BB->getName());
 
  598    for (
int I = 1, 
E = Comparisons.
size(); 
I < 
E; ++
I) {
 
  605    return Scratch.str();
 
  616  assert(!Comparisons.
empty() && 
"merging zero comparisons");
 
  618  const BCECmpBlock &FirstCmp = Comparisons[0];
 
  623                         NextCmpBlock->
getParent(), InsertBefore);
 
  627  if (FirstCmp.Lhs().GEP)
 
  628    Lhs = Builder.Insert(FirstCmp.Lhs().GEP->clone());
 
  630    Lhs = FirstCmp.Lhs().LoadI->getPointerOperand();
 
  631  if (FirstCmp.Rhs().GEP)
 
  632    Rhs = Builder.Insert(FirstCmp.Rhs().GEP->clone());
 
  634    Rhs = FirstCmp.Rhs().LoadI->getPointerOperand();
 
  636  Value *IsEqual = 
nullptr;
 
  644      Comparisons, [](
const BCECmpBlock &
B) { 
return B.RequireSplit; });
 
  645  if (ToSplit != Comparisons.
end()) {
 
  647    ToSplit->split(BB, 
AA);
 
  650  if (Comparisons.
size() == 1) {
 
  653    Instruction *
const LhsLoad = Builder.Insert(FirstCmp.Lhs().LoadI->clone());
 
  654    Instruction *
const RhsLoad = Builder.Insert(FirstCmp.Rhs().LoadI->clone());
 
  658    IsEqual = Builder.CreateICmpEQ(LhsLoad, RhsLoad);
 
  660    const unsigned TotalSizeBits = std::accumulate(
 
  661        Comparisons.
begin(), Comparisons.
end(), 0u,
 
  662        [](
int Size, 
const BCECmpBlock &
C) { return Size + C.SizeBits(); });
 
  665    unsigned SizeTBits = TLI.
getSizeTSize(*Phi.getModule());
 
  669    const auto &
DL = Phi.getDataLayout();
 
  672        ConstantInt::get(Builder.getIntNTy(SizeTBits), TotalSizeBits / 8),
 
  674    IsEqual = Builder.CreateICmpEQ(
 
  675        MemCmpCall, ConstantInt::get(Builder.getIntNTy(IntBits), 0));
 
  680  if (NextCmpBlock == PhiBB) {
 
  682    Builder.CreateBr(PhiBB);
 
  683    Phi.addIncoming(IsEqual, BB);
 
  687    Builder.CreateCondBr(IsEqual, NextCmpBlock, PhiBB);
 
 
  697  assert(atLeastOneMerged() && 
"simplifying trivial BCECmpChain");
 
  698  LLVM_DEBUG(
dbgs() << 
"Simplifying comparison chain starting at block " 
  699                    << EntryBlock_->
getName() << 
"\n");
 
  705  for (
const auto &Blocks : 
reverse(MergedBlocks_)) {
 
  707        Blocks, InsertBefore, NextCmpBlock, Phi_, TLI, AA, DTU);
 
  718    DTU.
applyUpdates({{DominatorTree::Delete, Pred, EntryBlock_},
 
  719                      {DominatorTree::Insert, Pred, NextCmpBlock}});
 
  724  const bool ChainEntryIsFnEntry = EntryBlock_->
isEntryBlock();
 
  725  if (ChainEntryIsFnEntry && DTU.
hasDomTree()) {
 
  727                      << EntryBlock_->
getName() << 
" to " 
  728                      << NextCmpBlock->
getName() << 
"\n");
 
  730    DTU.
applyUpdates({{DominatorTree::Delete, NextCmpBlock, EntryBlock_}});
 
  732  EntryBlock_ = 
nullptr;
 
  735  SmallVector<BasicBlock *, 16> DeadBlocks;
 
  736  for (
const auto &Blocks : MergedBlocks_) {
 
  737    for (
const BCECmpBlock &
Block : Blocks) {
 
  745  MergedBlocks_.clear();
 
  749static std::vector<BasicBlock *>
 
  752  std::vector<BasicBlock *> Blocks(NumBlocks);
 
  753  assert(LastBlock && 
"invalid last block");
 
  755  for (
int BlockIndex = NumBlocks - 1; BlockIndex > 0; --BlockIndex) {
 
  760                        << 
" has its address taken\n");
 
  763    Blocks[BlockIndex] = CurBlock;
 
  765    if (!SinglePredecessor) {
 
  768                        << 
" has two or more predecessors\n");
 
  771    if (Phi.getBasicBlockIndex(SinglePredecessor) < 0) {
 
  774                        << 
" does not link back to the phi\n");
 
  777    CurBlock = SinglePredecessor;
 
  779  Blocks[0] = CurBlock;
 
 
  786  if (Phi.getNumIncomingValues() <= 1) {
 
  807  for (
unsigned I = 0; 
I < Phi.getNumIncomingValues(); ++
I) {
 
  816            Phi.getIncomingBlock(
I)) {
 
  824          << 
"skip: non-constant value not from cmp or not from last block.\n");
 
  827    LastBlock = Phi.getIncomingBlock(
I);
 
  841  if (Blocks.empty()) 
return false;
 
  842  BCECmpChain CmpChain(Blocks, Phi, 
AA);
 
  844  if (!CmpChain.atLeastOneMerged()) {
 
  849  return CmpChain.simplify(TLI, 
AA, DTU);
 
 
  859  if (!
TTI.enableMemCmpExpansion(
F.hasOptSize(), 
true))
 
  863  if (!TLI.
has(LibFunc_memcmp))
 
  867                     DomTreeUpdater::UpdateStrategy::Eager);
 
  869  bool MadeChange = 
false;
 
 
  881class MergeICmpsLegacyPass : 
public FunctionPass {
 
  885  MergeICmpsLegacyPass() : FunctionPass(
ID) {
 
  890    if (skipFunction(
F)) 
return false;
 
  891    const auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(
F);
 
  892    const auto &
TTI = getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
F);
 
  895    auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>();
 
  896    auto &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
 
  897    return runImpl(
F, TLI, 
TTI, AA, DTWP ? &DTWP->getDomTree() : 
nullptr);
 
  901  void getAnalysisUsage(AnalysisUsage &AU)
 const override {
 
  912char MergeICmpsLegacyPass::ID = 0;
 
  914                      "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, 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< 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)
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.
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.
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)
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
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.
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.
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.
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.
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)