38#define DEBUG_TYPE "expand-memcmp"
41STATISTIC(NumMemCmpNotConstant,
"Number of memcmp calls without constant size");
43 "Number of memcmp calls with size greater than max size");
44STATISTIC(NumMemCmpInlined,
"Number of inlined memcmp calls");
48 cl::desc(
"The number of loads per basic block for inline expansion of "
49 "memcmp that is only being compared against zero."));
53 cl::desc(
"Set maximum number of loads used in expanded memcmp"));
57 cl::desc(
"Set maximum number of loads used in expanded memcmp for -Os/Oz"));
64class MemCmpExpansion {
70 ResultBlock() =
default;
73 CallInst *
const CI =
nullptr;
76 unsigned MaxLoadSize = 0;
77 uint64_t NumLoadsNonOneByte = 0;
78 const uint64_t NumLoadsPerBlockForZeroCmp;
79 std::vector<BasicBlock *> LoadCmpBlocks;
81 PHINode *PhiRes =
nullptr;
82 const bool IsUsedForZeroCmp;
84 DomTreeUpdater *DTU =
nullptr;
90 LoadEntry(
unsigned LoadSize, uint64_t Offset)
91 : LoadSize(LoadSize), Offset(Offset) {
99 using LoadEntryVector = SmallVector<LoadEntry, 8>;
100 LoadEntryVector LoadSequence;
102 void createLoadCmpBlocks();
103 void createResultBlock();
104 void setupResultBlockPHINodes();
105 void setupEndBlockPHINodes();
106 Value *getCompareLoadPairs(
unsigned BlockIndex,
unsigned &LoadIndex);
107 void emitLoadCompareBlock(
unsigned BlockIndex);
108 void emitLoadCompareBlockMultipleLoads(
unsigned BlockIndex,
109 unsigned &LoadIndex);
110 void emitLoadCompareByteBlock(
unsigned BlockIndex,
unsigned OffsetBytes);
111 void emitMemCmpResultBlock();
112 Value *getMemCmpExpansionZeroCase();
113 Value *getMemCmpEqZeroOneBlock();
114 Value *getMemCmpOneBlock();
116 Value *Lhs =
nullptr;
117 Value *Rhs =
nullptr;
119 LoadPair getLoadPair(
Type *LoadSizeType,
Type *BSwapSizeType,
120 Type *CmpSizeType,
unsigned OffsetBytes);
122 static LoadEntryVector
123 computeGreedyLoadSequence(uint64_t Size, llvm::ArrayRef<unsigned> LoadSizes,
124 unsigned MaxNumLoads,
unsigned &NumLoadsNonOneByte);
125 static LoadEntryVector
126 computeOverlappingLoadSequence(uint64_t Size,
unsigned MaxLoadSize,
127 unsigned MaxNumLoads,
128 unsigned &NumLoadsNonOneByte);
130 static void optimiseLoadSequence(
131 LoadEntryVector &LoadSequence,
132 const TargetTransformInfo::MemCmpExpansionOptions &
Options,
133 bool IsUsedForZeroCmp);
136 MemCmpExpansion(CallInst *CI, uint64_t Size,
137 const TargetTransformInfo::MemCmpExpansionOptions &
Options,
138 const bool IsUsedForZeroCmp,
const DataLayout &TheDataLayout,
139 DomTreeUpdater *DTU);
141 unsigned getNumBlocks();
142 uint64_t getNumLoads()
const {
return LoadSequence.size(); }
144 Value *getMemCmpExpansion();
147MemCmpExpansion::LoadEntryVector MemCmpExpansion::computeGreedyLoadSequence(
149 const unsigned MaxNumLoads,
unsigned &NumLoadsNonOneByte) {
150 NumLoadsNonOneByte = 0;
151 LoadEntryVector LoadSequence;
154 const unsigned LoadSize = LoadSizes.
front();
155 const uint64_t NumLoadsForThisSize =
Size / LoadSize;
156 if (LoadSequence.size() + NumLoadsForThisSize > MaxNumLoads) {
163 if (NumLoadsForThisSize > 0) {
164 for (uint64_t
I = 0;
I < NumLoadsForThisSize; ++
I) {
165 LoadSequence.push_back({LoadSize,
Offset});
169 ++NumLoadsNonOneByte;
177MemCmpExpansion::LoadEntryVector
178MemCmpExpansion::computeOverlappingLoadSequence(uint64_t
Size,
179 const unsigned MaxLoadSize,
180 const unsigned MaxNumLoads,
181 unsigned &NumLoadsNonOneByte) {
183 if (
Size < 2 || MaxLoadSize < 2)
188 const uint64_t NumNonOverlappingLoads =
Size / MaxLoadSize;
189 assert(NumNonOverlappingLoads &&
"there must be at least one load");
192 Size =
Size - NumNonOverlappingLoads * MaxLoadSize;
199 if ((NumNonOverlappingLoads + 1) > MaxNumLoads)
203 LoadEntryVector LoadSequence;
205 for (uint64_t
I = 0;
I < NumNonOverlappingLoads; ++
I) {
206 LoadSequence.push_back({MaxLoadSize,
Offset});
212 LoadSequence.push_back({MaxLoadSize,
Offset - (MaxLoadSize -
Size)});
213 NumLoadsNonOneByte = 1;
217void MemCmpExpansion::optimiseLoadSequence(
218 LoadEntryVector &LoadSequence,
219 const TargetTransformInfo::MemCmpExpansionOptions &
Options,
220 bool IsUsedForZeroCmp) {
225 if (IsUsedForZeroCmp ||
Options.AllowedTailExpansions.empty())
228 while (LoadSequence.size() >= 2) {
229 auto Last = LoadSequence[LoadSequence.size() - 1];
230 auto PreLast = LoadSequence[LoadSequence.size() - 2];
233 if (PreLast.Offset + PreLast.LoadSize !=
Last.Offset)
236 auto LoadSize =
Last.LoadSize + PreLast.LoadSize;
237 if (
find(
Options.AllowedTailExpansions, LoadSize) ==
238 Options.AllowedTailExpansions.end())
242 LoadSequence.pop_back();
243 LoadSequence.pop_back();
244 LoadSequence.emplace_back(PreLast.Offset, LoadSize);
256MemCmpExpansion::MemCmpExpansion(
257 CallInst *
const CI, uint64_t
Size,
258 const TargetTransformInfo::MemCmpExpansionOptions &
Options,
259 const bool IsUsedForZeroCmp,
const DataLayout &TheDataLayout,
261 : CI(CI),
Size(
Size), NumLoadsPerBlockForZeroCmp(
Options.NumLoadsPerBlock),
262 IsUsedForZeroCmp(IsUsedForZeroCmp),
DL(TheDataLayout), DTU(DTU),
270 assert(!LoadSizes.
empty() &&
"cannot load Size bytes");
271 MaxLoadSize = LoadSizes.
front();
273 unsigned GreedyNumLoadsNonOneByte = 0;
274 LoadSequence = computeGreedyLoadSequence(
Size, LoadSizes,
Options.MaxNumLoads,
275 GreedyNumLoadsNonOneByte);
276 NumLoadsNonOneByte = GreedyNumLoadsNonOneByte;
277 assert(LoadSequence.size() <=
Options.MaxNumLoads &&
"broken invariant");
280 if (
Options.AllowOverlappingLoads &&
281 (LoadSequence.empty() || LoadSequence.size() > 2)) {
282 unsigned OverlappingNumLoadsNonOneByte = 0;
283 auto OverlappingLoads = computeOverlappingLoadSequence(
284 Size, MaxLoadSize,
Options.MaxNumLoads, OverlappingNumLoadsNonOneByte);
285 if (!OverlappingLoads.empty() &&
286 (LoadSequence.empty() ||
287 OverlappingLoads.size() < LoadSequence.size())) {
288 LoadSequence = OverlappingLoads;
289 NumLoadsNonOneByte = OverlappingNumLoadsNonOneByte;
292 assert(LoadSequence.size() <=
Options.MaxNumLoads &&
"broken invariant");
293 optimiseLoadSequence(LoadSequence,
Options, IsUsedForZeroCmp);
296unsigned MemCmpExpansion::getNumBlocks() {
297 if (IsUsedForZeroCmp)
298 return getNumLoads() / NumLoadsPerBlockForZeroCmp +
299 (getNumLoads() % NumLoadsPerBlockForZeroCmp != 0 ? 1 : 0);
300 return getNumLoads();
303void MemCmpExpansion::createLoadCmpBlocks() {
304 for (
unsigned i = 0; i < getNumBlocks(); i++) {
307 LoadCmpBlocks.push_back(BB);
311void MemCmpExpansion::createResultBlock() {
316MemCmpExpansion::LoadPair MemCmpExpansion::getLoadPair(
Type *LoadSizeType,
319 unsigned OffsetBytes) {
325 if (OffsetBytes > 0) {
326 auto *ByteType = Type::getInt8Ty(CI->
getContext());
334 Value *Lhs =
nullptr;
340 Value *Rhs =
nullptr;
347 if (BSwapSizeType && LoadSizeType != BSwapSizeType) {
355 CI->
getModule(), Intrinsic::bswap, BSwapSizeType);
361 if (CmpSizeType !=
nullptr && CmpSizeType != Lhs->
getType()) {
372void MemCmpExpansion::emitLoadCompareByteBlock(
unsigned BlockIndex,
373 unsigned OffsetBytes) {
376 const LoadPair Loads =
377 getLoadPair(Type::getInt8Ty(CI->
getContext()),
nullptr,
378 Type::getInt32Ty(CI->
getContext()), OffsetBytes);
383 if (BlockIndex < (LoadCmpBlocks.size() - 1)) {
387 ConstantInt::get(Diff->
getType(), 0));
388 Builder.
CreateCondBr(Cmp, EndBlock, LoadCmpBlocks[BlockIndex + 1]);
391 {{DominatorTree::Insert, BB, EndBlock},
392 {DominatorTree::Insert, BB, LoadCmpBlocks[BlockIndex + 1]}});
397 DTU->
applyUpdates({{DominatorTree::Insert, BB, EndBlock}});
404Value *MemCmpExpansion::getCompareLoadPairs(
unsigned BlockIndex,
405 unsigned &LoadIndex) {
406 assert(LoadIndex < getNumLoads() &&
407 "getCompareLoadPairs() called with no remaining loads");
408 std::vector<Value *> XorList, OrList;
409 Value *Diff =
nullptr;
411 const unsigned NumLoads =
412 std::min(getNumLoads() - LoadIndex, NumLoadsPerBlockForZeroCmp);
415 if (LoadCmpBlocks.empty())
424 IntegerType *
const MaxLoadType =
425 NumLoads == 1 ? nullptr
428 for (
unsigned i = 0; i < NumLoads; ++i, ++LoadIndex) {
429 const LoadEntry &CurLoadEntry = LoadSequence[LoadIndex];
430 const LoadPair Loads = getLoadPair(
432 MaxLoadType, CurLoadEntry.Offset);
437 Diff = Builder.
CreateXor(Loads.Lhs, Loads.Rhs);
439 XorList.push_back(Diff);
446 auto pairWiseOr = [&](std::vector<Value *> &InList) -> std::vector<Value *> {
447 std::vector<Value *> OutList;
448 for (
unsigned i = 0; i < InList.size() - 1; i = i + 2) {
450 OutList.push_back(
Or);
452 if (InList.size() % 2 != 0)
453 OutList.push_back(InList.back());
459 OrList = pairWiseOr(XorList);
462 while (OrList.size() != 1) {
463 OrList = pairWiseOr(OrList);
466 assert(Diff &&
"Failed to find comparison diff");
473void MemCmpExpansion::emitLoadCompareBlockMultipleLoads(
unsigned BlockIndex,
474 unsigned &LoadIndex) {
475 Value *
Cmp = getCompareLoadPairs(BlockIndex, LoadIndex);
477 BasicBlock *NextBB = (BlockIndex == (LoadCmpBlocks.size() - 1))
479 : LoadCmpBlocks[BlockIndex + 1];
483 CondBrInst *CmpBr = Builder.
CreateCondBr(Cmp, ResBlock.BB, NextBB);
487 DTU->
applyUpdates({{DominatorTree::Insert, BB, ResBlock.BB},
488 {DominatorTree::Insert, BB, NextBB}});
493 if (BlockIndex == LoadCmpBlocks.size() - 1) {
495 PhiRes->
addIncoming(Zero, LoadCmpBlocks[BlockIndex]);
508void MemCmpExpansion::emitLoadCompareBlock(
unsigned BlockIndex) {
510 const LoadEntry &CurLoadEntry = LoadSequence[BlockIndex];
512 if (CurLoadEntry.LoadSize == 1) {
513 MemCmpExpansion::emitLoadCompareByteBlock(BlockIndex, CurLoadEntry.Offset);
519 Type *BSwapSizeType =
526 std::max(MaxLoadSize, (
unsigned)
PowerOf2Ceil(CurLoadEntry.LoadSize)) * 8);
527 assert(CurLoadEntry.LoadSize <= MaxLoadSize &&
"Unexpected load type");
531 const LoadPair Loads = getLoadPair(LoadSizeType, BSwapSizeType, MaxLoadType,
532 CurLoadEntry.Offset);
536 if (!IsUsedForZeroCmp) {
537 ResBlock.PhiSrc1->addIncoming(Loads.Lhs, LoadCmpBlocks[BlockIndex]);
538 ResBlock.PhiSrc2->addIncoming(Loads.Rhs, LoadCmpBlocks[BlockIndex]);
542 BasicBlock *NextBB = (BlockIndex == (LoadCmpBlocks.size() - 1))
544 : LoadCmpBlocks[BlockIndex + 1];
548 CondBrInst *CmpBr = Builder.
CreateCondBr(Cmp, NextBB, ResBlock.BB);
553 {DominatorTree::Insert, BB, ResBlock.BB}});
558 if (BlockIndex == LoadCmpBlocks.size() - 1) {
560 PhiRes->
addIncoming(Zero, LoadCmpBlocks[BlockIndex]);
567void MemCmpExpansion::emitMemCmpResultBlock() {
570 if (IsUsedForZeroCmp) {
577 DTU->
applyUpdates({{DominatorTree::Insert, ResBlock.BB, EndBlock}});
595 DTU->
applyUpdates({{DominatorTree::Insert, ResBlock.BB, EndBlock}});
598void MemCmpExpansion::setupResultBlockPHINodes() {
603 Builder.
CreatePHI(MaxLoadType, NumLoadsNonOneByte,
"phi.src1");
605 Builder.
CreatePHI(MaxLoadType, NumLoadsNonOneByte,
"phi.src2");
608void MemCmpExpansion::setupEndBlockPHINodes() {
613Value *MemCmpExpansion::getMemCmpExpansionZeroCase() {
614 unsigned LoadIndex = 0;
617 for (
unsigned I = 0;
I < getNumBlocks(); ++
I) {
618 emitLoadCompareBlockMultipleLoads(
I, LoadIndex);
621 emitMemCmpResultBlock();
628Value *MemCmpExpansion::getMemCmpEqZeroOneBlock() {
629 unsigned LoadIndex = 0;
630 Value *
Cmp = getCompareLoadPairs(0, LoadIndex);
631 assert(LoadIndex == getNumLoads() &&
"some entries were not consumed");
640Value *MemCmpExpansion::getMemCmpOneBlock() {
641 bool NeedsBSwap =
DL.isLittleEndian() &&
Size != 1;
643 Type *BSwapSizeType =
653 const LoadPair Loads = getLoadPair(LoadSizeType, BSwapSizeType,
655 return Builder.
CreateSub(Loads.Lhs, Loads.Rhs);
658 const LoadPair Loads = getLoadPair(LoadSizeType, BSwapSizeType, MaxLoadType,
666 CmpPredicate Pred = ICmpInst::Predicate::BAD_ICMP_PREDICATE;
667 bool NeedsZExt =
false;
676 Pred = ICmpInst::ICMP_SLT;
681 Pred = ICmpInst::ICMP_SGE;
685 Pred = ICmpInst::ICMP_SLE;
691 if (ICmpInst::isSigned(Pred)) {
693 Loads.Lhs, Loads.Rhs);
695 UI->replaceAllUsesWith(Result);
696 UI->eraseFromParent();
704 {Loads.Lhs, Loads.Rhs});
709Value *MemCmpExpansion::getMemCmpExpansion() {
711 if (getNumBlocks() != 1) {
713 EndBlock =
SplitBlock(StartBlock, CI, DTU,
nullptr,
714 nullptr,
"endblock");
715 setupEndBlockPHINodes();
722 if (!IsUsedForZeroCmp) setupResultBlockPHINodes();
725 createLoadCmpBlocks();
731 DTU->
applyUpdates({{DominatorTree::Insert, StartBlock, LoadCmpBlocks[0]},
732 {DominatorTree::Delete, StartBlock, EndBlock}});
737 if (IsUsedForZeroCmp)
738 return getNumBlocks() == 1 ? getMemCmpEqZeroOneBlock()
739 : getMemCmpExpansionZeroCase();
741 if (getNumBlocks() == 1)
742 return getMemCmpOneBlock();
744 for (
unsigned I = 0;
I < getNumBlocks(); ++
I) {
745 emitLoadCompareBlock(
I);
748 emitMemCmpResultBlock();
825static bool expandMemCmp(CallInst *CI,
const TargetTransformInfo *
TTI,
826 const DataLayout *
DL, ProfileSummaryInfo *PSI,
827 BlockFrequencyInfo *BFI, DomTreeUpdater *DTU,
838 NumMemCmpNotConstant++;
848 const bool IsUsedForZeroCmp =
869 NumMemCmpGreaterThanMax++;
885static bool runOnBlock(BasicBlock &BB,
const TargetLibraryInfo *TLI,
886 const TargetTransformInfo *
TTI,
const DataLayout &
DL,
887 ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI,
888 DomTreeUpdater *DTU);
890static PreservedAnalyses
runImpl(Function &
F,
const TargetLibraryInfo *TLI,
891 const TargetTransformInfo *
TTI,
892 ProfileSummaryInfo *PSI,
893 BlockFrequencyInfo *BFI, DominatorTree *DT);
895class ExpandMemCmpLegacyPass :
public FunctionPass {
899 ExpandMemCmpLegacyPass() : FunctionPass(
ID) {}
902 if (skipFunction(
F))
return false;
904 auto *TPC = getAnalysisIfAvailable<TargetPassConfig>();
909 const TargetLibraryInfo *TLI =
910 &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(
F);
911 const TargetTransformInfo *
TTI =
912 &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
F);
913 auto *PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
915 &getAnalysis<LazyBlockFrequencyInfoPass>().getBFI() :
917 DominatorTree *DT =
nullptr;
918 if (
auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>())
919 DT = &DTWP->getDomTree();
921 return !PA.areAllPreserved();
925 void getAnalysisUsage(AnalysisUsage &AU)
const override {
931 FunctionPass::getAnalysisUsage(AU);
935bool runOnBlock(BasicBlock &BB,
const TargetLibraryInfo *TLI,
936 const TargetTransformInfo *
TTI,
const DataLayout &
DL,
937 ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI,
938 DomTreeUpdater *DTU) {
939 for (Instruction &
I : BB) {
946 (Func == LibFunc_memcmp || Func == LibFunc_bcmp) &&
947 expandMemCmp(CI,
TTI, &
DL, PSI, BFI, DTU, Func == LibFunc_bcmp)) {
954PreservedAnalyses
runImpl(Function &
F,
const TargetLibraryInfo *TLI,
955 const TargetTransformInfo *
TTI,
956 ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI,
958 std::optional<DomTreeUpdater> DTU;
960 DTU.emplace(DT, DomTreeUpdater::UpdateStrategy::Lazy);
962 const DataLayout&
DL =
F.getDataLayout();
963 bool MadeChanges =
false;
964 for (
auto BBIt =
F.begin(); BBIt !=
F.end();) {
965 if (runOnBlock(*BBIt, TLI,
TTI,
DL, PSI, BFI, DTU ? &*DTU :
nullptr)) {
975 for (BasicBlock &BB :
F)
979 PreservedAnalyses PA;
980 PA.
preserve<DominatorTreeAnalysis>();
991 .getCachedResult<ProfileSummaryAnalysis>(*
F.getParent());
1000char ExpandMemCmpLegacyPass::ID = 0;
1002 "Expand memcmp() to load/stores",
false,
false)
1012 return new ExpandMemCmpLegacyPass();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static bool runOnFunction(Function &F, bool PostInlining)
static bool runImpl(Function &F, const TargetLowering &TLI, const LibcallLoweringInfo &Libcalls, AssumptionCache *AC)
static cl::opt< unsigned > MaxLoadsPerMemcmpOptSize("max-loads-per-memcmp-opt-size", cl::Hidden, cl::desc("Set maximum number of loads used in expanded memcmp for -Os/Oz"))
static cl::opt< unsigned > MaxLoadsPerMemcmp("max-loads-per-memcmp", cl::Hidden, cl::desc("Set maximum number of loads used in expanded memcmp"))
static cl::opt< unsigned > MemCmpEqZeroNumLoadsPerBlock("memcmp-num-loads-per-block", cl::Hidden, cl::init(1), cl::desc("The number of loads per basic block for inline expansion of " "memcmp that is only being compared against zero."))
FunctionAnalysisManager FAM
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file contains the declarations for profiling metadata utility functions.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Target-Independent Code Generator Pass Configuration Options pass.
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),...
ArrayRef< T > drop_front(size_t N=1) const
Drop the first N elements of the array.
const T & front() const
front - Get the first element.
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.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
InstListType::iterator iterator
Instruction iterators...
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...
Analysis pass which computes BlockFrequencyInfo.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
Value * getArgOperand(unsigned i) const
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
Analysis pass which computes a DominatorTree.
Legacy analysis pass which computes a DominatorTree.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)
FunctionPass class - This class is used to implement most global optimizations.
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
void applyUpdates(ArrayRef< UpdateT > Updates)
Submit updates to all available trees.
Predicate getUnsignedPredicate() const
For example, EQ->EQ, SLE->ULE, UGT->UGT, etc.
Value * CreateConstGEP1_64(Type *Ty, Value *Ptr, uint64_t Idx0, const Twine &Name="")
LoadInst * CreateAlignedLoad(Type *Ty, Value *Ptr, MaybeAlign Align, const char *Name)
CondBrInst * CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False, MDNode *BranchWeights=nullptr, MDNode *Unpredictable=nullptr)
Create a conditional 'br Cond, TrueDest, FalseDest' instruction.
LLVM_ABI Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
BasicBlock * GetInsertBlock() const
void SetCurrentDebugLocation(DebugLoc L)
Set location information used by debugging information.
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
UncondBrInst * CreateBr(BasicBlock *Dest)
Create an unconditional 'br label X' instruction.
LLVM_ABI CallInst * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > Types, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with Args, mangled using Types.
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
LLVM_ABI void setSuccessor(unsigned Idx, BasicBlock *BB)
Update the specified successor to point at the provided block.
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
This is an alternative analysis pass to BlockFrequencyInfoWrapperPass.
static void getLazyBFIAnalysisUsage(AnalysisUsage &AU)
Helper for client passes to set up the analysis usage on behalf of this pass.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
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.
An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
bool hasProfileSummary() const
Returns true if profile summary is available.
Analysis pass providing the TargetTransformInfo.
Analysis pass providing the TargetLibraryInfo.
bool getLibFunc(StringRef funcName, LibFunc &F) const
Searches for a particular function name.
LLVM_ABI unsigned getIntegerBitWidth() const
Type * getType() const
All values are typed, get the type of this value.
user_iterator user_begin()
LLVM_ABI bool hasOneUser() const
Return true if there is exactly one user of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
LLVMContext & getContext() const
All values hold a context through their type.
LLVM_ABI Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
const ParentTy * getParent() const
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
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.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})
Look up the Function declaration of the intrinsic id in the Module M.
cst_pred_ty< is_all_ones > m_AllOnes()
Match an integer or vector with all bits set.
specific_intval< false > m_SpecificInt(const APInt &V)
Match a specific integer value or vector with all elements equal to the value.
bool match(Val *V, const Pattern &P)
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
SpecificCmpClass_match< LHS, RHS, ICmpInst > m_SpecificICmp(CmpPredicate MatchPred, const LHS &L, const RHS &R)
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
initializer< Ty > init(const Ty &Val)
NodeAddr< FuncNode * > Func
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI bool isOnlyUsedInZeroEqualityComparison(const Instruction *CxtI)
LLVM_ABI void setExplicitlyUnknownBranchWeightsIfProfiled(Instruction &I, StringRef PassName, const Function *F=nullptr)
Like setExplicitlyUnknownBranchWeights(...), but only sets unknown branch weights in the new instruct...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
OuterAnalysisManagerProxy< ModuleAnalysisManager, Function > ModuleAnalysisManagerFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
LLVM_ABI bool shouldOptimizeForSize(const MachineFunction *MF, ProfileSummaryInfo *PSI, const MachineBlockFrequencyInfo *BFI, PGSOQueryType QueryType=PGSOQueryType::Other)
Returns true if machine function MF is suggested to be size-optimized based on the profile.
LLVM_ABI bool SimplifyInstructionsInBlock(BasicBlock *BB, const TargetLibraryInfo *TLI=nullptr)
Scan the specified basic block and try to simplify any instructions in it and recursively delete dead...
uint64_t PowerOf2Ceil(uint64_t A)
Returns the power of two which is greater than or equal to the given value.
LLVM_ABI FunctionPass * createExpandMemCmpLegacyPass()
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
@ Or
Bitwise or logical OR of integers.
LLVM_ABI BasicBlock * SplitBlock(BasicBlock *Old, BasicBlock::iterator SplitPt, DominatorTree *DT, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="")
Split the specified block at the specified instruction.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
LLVM_ABI Constant * ConstantFoldLoadFromConstPtr(Constant *C, Type *Ty, APInt Offset, const DataLayout &DL)
Return the value that a load from C with offset Offset would produce if it is constant and determinab...
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.