35#define DEBUG_TYPE "expand-memcmp"
38STATISTIC(NumMemCmpNotConstant,
"Number of memcmp calls without constant size");
40 "Number of memcmp calls with size greater than max size");
41STATISTIC(NumMemCmpInlined,
"Number of inlined memcmp calls");
45 cl::desc(
"The number of loads per basic block for inline expansion of "
46 "memcmp that is only being compared against zero."));
50 cl::desc(
"Set maximum number of loads used in expanded memcmp"));
54 cl::desc(
"Set maximum number of loads used in expanded memcmp for -Os/Oz"));
61class MemCmpExpansion {
67 ResultBlock() =
default;
70 CallInst *
const CI =
nullptr;
73 unsigned MaxLoadSize = 0;
74 uint64_t NumLoadsNonOneByte = 0;
75 const uint64_t NumLoadsPerBlockForZeroCmp;
76 std::vector<BasicBlock *> LoadCmpBlocks;
78 PHINode *PhiRes =
nullptr;
79 const bool IsUsedForZeroCmp;
81 DomTreeUpdater *DTU =
nullptr;
87 LoadEntry(
unsigned LoadSize, uint64_t Offset)
88 : LoadSize(LoadSize), Offset(Offset) {
96 using LoadEntryVector = SmallVector<LoadEntry, 8>;
97 LoadEntryVector LoadSequence;
99 void createLoadCmpBlocks();
100 void createResultBlock();
101 void setupResultBlockPHINodes();
102 void setupEndBlockPHINodes();
103 Value *getCompareLoadPairs(
unsigned BlockIndex,
unsigned &LoadIndex);
104 void emitLoadCompareBlock(
unsigned BlockIndex);
105 void emitLoadCompareBlockMultipleLoads(
unsigned BlockIndex,
106 unsigned &LoadIndex);
107 void emitLoadCompareByteBlock(
unsigned BlockIndex,
unsigned OffsetBytes);
108 void emitMemCmpResultBlock();
109 Value *getMemCmpExpansionZeroCase();
110 Value *getMemCmpEqZeroOneBlock();
111 Value *getMemCmpOneBlock();
113 Value *Lhs =
nullptr;
114 Value *Rhs =
nullptr;
116 LoadPair getLoadPair(
Type *LoadSizeType,
Type *BSwapSizeType,
117 Type *CmpSizeType,
unsigned OffsetBytes);
119 static LoadEntryVector
120 computeGreedyLoadSequence(uint64_t Size, llvm::ArrayRef<unsigned> LoadSizes,
121 unsigned MaxNumLoads,
unsigned &NumLoadsNonOneByte);
122 static LoadEntryVector
123 computeOverlappingLoadSequence(uint64_t Size,
unsigned MaxLoadSize,
124 unsigned MaxNumLoads,
125 unsigned &NumLoadsNonOneByte);
127 static void optimiseLoadSequence(
128 LoadEntryVector &LoadSequence,
129 const TargetTransformInfo::MemCmpExpansionOptions &
Options,
130 bool IsUsedForZeroCmp);
133 MemCmpExpansion(CallInst *CI, uint64_t Size,
134 const TargetTransformInfo::MemCmpExpansionOptions &
Options,
135 const bool IsUsedForZeroCmp,
const DataLayout &TheDataLayout,
136 DomTreeUpdater *DTU);
138 unsigned getNumBlocks();
139 uint64_t getNumLoads()
const {
return LoadSequence.size(); }
141 Value *getMemCmpExpansion();
144MemCmpExpansion::LoadEntryVector MemCmpExpansion::computeGreedyLoadSequence(
146 const unsigned MaxNumLoads,
unsigned &NumLoadsNonOneByte) {
147 NumLoadsNonOneByte = 0;
148 LoadEntryVector LoadSequence;
151 const unsigned LoadSize = LoadSizes.
front();
152 const uint64_t NumLoadsForThisSize =
Size / LoadSize;
153 if (LoadSequence.size() + NumLoadsForThisSize > MaxNumLoads) {
160 if (NumLoadsForThisSize > 0) {
161 for (uint64_t
I = 0;
I < NumLoadsForThisSize; ++
I) {
162 LoadSequence.push_back({LoadSize,
Offset});
166 ++NumLoadsNonOneByte;
174MemCmpExpansion::LoadEntryVector
175MemCmpExpansion::computeOverlappingLoadSequence(uint64_t
Size,
176 const unsigned MaxLoadSize,
177 const unsigned MaxNumLoads,
178 unsigned &NumLoadsNonOneByte) {
180 if (
Size < 2 || MaxLoadSize < 2)
185 const uint64_t NumNonOverlappingLoads =
Size / MaxLoadSize;
186 assert(NumNonOverlappingLoads &&
"there must be at least one load");
189 Size =
Size - NumNonOverlappingLoads * MaxLoadSize;
196 if ((NumNonOverlappingLoads + 1) > MaxNumLoads)
200 LoadEntryVector LoadSequence;
202 for (uint64_t
I = 0;
I < NumNonOverlappingLoads; ++
I) {
203 LoadSequence.push_back({MaxLoadSize,
Offset});
209 LoadSequence.push_back({MaxLoadSize,
Offset - (MaxLoadSize -
Size)});
210 NumLoadsNonOneByte = 1;
214void MemCmpExpansion::optimiseLoadSequence(
215 LoadEntryVector &LoadSequence,
216 const TargetTransformInfo::MemCmpExpansionOptions &
Options,
217 bool IsUsedForZeroCmp) {
222 if (IsUsedForZeroCmp ||
Options.AllowedTailExpansions.empty())
225 while (LoadSequence.size() >= 2) {
226 auto Last = LoadSequence[LoadSequence.size() - 1];
227 auto PreLast = LoadSequence[LoadSequence.size() - 2];
230 if (PreLast.Offset + PreLast.LoadSize !=
Last.Offset)
233 auto LoadSize =
Last.LoadSize + PreLast.LoadSize;
234 if (
find(
Options.AllowedTailExpansions, LoadSize) ==
235 Options.AllowedTailExpansions.end())
239 LoadSequence.pop_back();
240 LoadSequence.pop_back();
241 LoadSequence.emplace_back(PreLast.Offset, LoadSize);
253MemCmpExpansion::MemCmpExpansion(
254 CallInst *
const CI, uint64_t
Size,
255 const TargetTransformInfo::MemCmpExpansionOptions &
Options,
256 const bool IsUsedForZeroCmp,
const DataLayout &TheDataLayout,
258 : CI(CI),
Size(
Size), NumLoadsPerBlockForZeroCmp(
Options.NumLoadsPerBlock),
259 IsUsedForZeroCmp(IsUsedForZeroCmp),
DL(TheDataLayout), DTU(DTU),
267 assert(!LoadSizes.
empty() &&
"cannot load Size bytes");
268 MaxLoadSize = LoadSizes.
front();
270 unsigned GreedyNumLoadsNonOneByte = 0;
271 LoadSequence = computeGreedyLoadSequence(
Size, LoadSizes,
Options.MaxNumLoads,
272 GreedyNumLoadsNonOneByte);
273 NumLoadsNonOneByte = GreedyNumLoadsNonOneByte;
274 assert(LoadSequence.size() <=
Options.MaxNumLoads &&
"broken invariant");
277 if (
Options.AllowOverlappingLoads &&
278 (LoadSequence.empty() || LoadSequence.size() > 2)) {
279 unsigned OverlappingNumLoadsNonOneByte = 0;
280 auto OverlappingLoads = computeOverlappingLoadSequence(
281 Size, MaxLoadSize,
Options.MaxNumLoads, OverlappingNumLoadsNonOneByte);
282 if (!OverlappingLoads.empty() &&
283 (LoadSequence.empty() ||
284 OverlappingLoads.size() < LoadSequence.size())) {
285 LoadSequence = OverlappingLoads;
286 NumLoadsNonOneByte = OverlappingNumLoadsNonOneByte;
289 assert(LoadSequence.size() <=
Options.MaxNumLoads &&
"broken invariant");
290 optimiseLoadSequence(LoadSequence,
Options, IsUsedForZeroCmp);
293unsigned MemCmpExpansion::getNumBlocks() {
294 if (IsUsedForZeroCmp)
295 return getNumLoads() / NumLoadsPerBlockForZeroCmp +
296 (getNumLoads() % NumLoadsPerBlockForZeroCmp != 0 ? 1 : 0);
297 return getNumLoads();
300void MemCmpExpansion::createLoadCmpBlocks() {
301 for (
unsigned i = 0; i < getNumBlocks(); i++) {
304 LoadCmpBlocks.push_back(BB);
308void MemCmpExpansion::createResultBlock() {
313MemCmpExpansion::LoadPair MemCmpExpansion::getLoadPair(
Type *LoadSizeType,
316 unsigned OffsetBytes) {
322 if (OffsetBytes > 0) {
323 auto *ByteType = Type::getInt8Ty(CI->
getContext());
331 Value *Lhs =
nullptr;
337 Value *Rhs =
nullptr;
344 if (BSwapSizeType && LoadSizeType != BSwapSizeType) {
352 CI->
getModule(), Intrinsic::bswap, BSwapSizeType);
358 if (CmpSizeType !=
nullptr && CmpSizeType != Lhs->
getType()) {
369void MemCmpExpansion::emitLoadCompareByteBlock(
unsigned BlockIndex,
370 unsigned OffsetBytes) {
373 const LoadPair Loads =
374 getLoadPair(Type::getInt8Ty(CI->
getContext()),
nullptr,
375 Type::getInt32Ty(CI->
getContext()), OffsetBytes);
380 if (BlockIndex < (LoadCmpBlocks.size() - 1)) {
384 ConstantInt::get(Diff->
getType(), 0));
385 Builder.
CreateCondBr(Cmp, EndBlock, LoadCmpBlocks[BlockIndex + 1]);
388 {{DominatorTree::Insert, BB, EndBlock},
389 {DominatorTree::Insert, BB, LoadCmpBlocks[BlockIndex + 1]}});
394 DTU->
applyUpdates({{DominatorTree::Insert, BB, EndBlock}});
401Value *MemCmpExpansion::getCompareLoadPairs(
unsigned BlockIndex,
402 unsigned &LoadIndex) {
403 assert(LoadIndex < getNumLoads() &&
404 "getCompareLoadPairs() called with no remaining loads");
405 std::vector<Value *> XorList, OrList;
406 Value *Diff =
nullptr;
408 const unsigned NumLoads =
409 std::min(getNumLoads() - LoadIndex, NumLoadsPerBlockForZeroCmp);
412 if (LoadCmpBlocks.empty())
421 IntegerType *
const MaxLoadType =
422 NumLoads == 1 ? nullptr
425 for (
unsigned i = 0; i < NumLoads; ++i, ++LoadIndex) {
426 const LoadEntry &CurLoadEntry = LoadSequence[LoadIndex];
427 const LoadPair Loads = getLoadPair(
429 MaxLoadType, CurLoadEntry.Offset);
434 Diff = Builder.
CreateXor(Loads.Lhs, Loads.Rhs);
436 XorList.push_back(Diff);
443 auto pairWiseOr = [&](std::vector<Value *> &InList) -> std::vector<Value *> {
444 std::vector<Value *> OutList;
445 for (
unsigned i = 0; i < InList.size() - 1; i = i + 2) {
447 OutList.push_back(
Or);
449 if (InList.size() % 2 != 0)
450 OutList.push_back(InList.back());
456 OrList = pairWiseOr(XorList);
459 while (OrList.size() != 1) {
460 OrList = pairWiseOr(OrList);
463 assert(Diff &&
"Failed to find comparison diff");
470void MemCmpExpansion::emitLoadCompareBlockMultipleLoads(
unsigned BlockIndex,
471 unsigned &LoadIndex) {
472 Value *
Cmp = getCompareLoadPairs(BlockIndex, LoadIndex);
474 BasicBlock *NextBB = (BlockIndex == (LoadCmpBlocks.size() - 1))
476 : LoadCmpBlocks[BlockIndex + 1];
480 CondBrInst *CmpBr = Builder.
CreateCondBr(Cmp, ResBlock.BB, NextBB);
484 DTU->
applyUpdates({{DominatorTree::Insert, BB, ResBlock.BB},
485 {DominatorTree::Insert, BB, NextBB}});
490 if (BlockIndex == LoadCmpBlocks.size() - 1) {
492 PhiRes->
addIncoming(Zero, LoadCmpBlocks[BlockIndex]);
505void MemCmpExpansion::emitLoadCompareBlock(
unsigned BlockIndex) {
507 const LoadEntry &CurLoadEntry = LoadSequence[BlockIndex];
509 if (CurLoadEntry.LoadSize == 1) {
510 MemCmpExpansion::emitLoadCompareByteBlock(BlockIndex, CurLoadEntry.Offset);
516 Type *BSwapSizeType =
523 std::max(MaxLoadSize, (
unsigned)
PowerOf2Ceil(CurLoadEntry.LoadSize)) * 8);
524 assert(CurLoadEntry.LoadSize <= MaxLoadSize &&
"Unexpected load type");
528 const LoadPair Loads = getLoadPair(LoadSizeType, BSwapSizeType, MaxLoadType,
529 CurLoadEntry.Offset);
533 if (!IsUsedForZeroCmp) {
534 ResBlock.PhiSrc1->addIncoming(Loads.Lhs, LoadCmpBlocks[BlockIndex]);
535 ResBlock.PhiSrc2->addIncoming(Loads.Rhs, LoadCmpBlocks[BlockIndex]);
539 BasicBlock *NextBB = (BlockIndex == (LoadCmpBlocks.size() - 1))
541 : LoadCmpBlocks[BlockIndex + 1];
545 CondBrInst *CmpBr = Builder.
CreateCondBr(Cmp, NextBB, ResBlock.BB);
550 {DominatorTree::Insert, BB, ResBlock.BB}});
555 if (BlockIndex == LoadCmpBlocks.size() - 1) {
557 PhiRes->
addIncoming(Zero, LoadCmpBlocks[BlockIndex]);
564void MemCmpExpansion::emitMemCmpResultBlock() {
567 if (IsUsedForZeroCmp) {
574 DTU->
applyUpdates({{DominatorTree::Insert, ResBlock.BB, EndBlock}});
592 DTU->
applyUpdates({{DominatorTree::Insert, ResBlock.BB, EndBlock}});
595void MemCmpExpansion::setupResultBlockPHINodes() {
600 Builder.
CreatePHI(MaxLoadType, NumLoadsNonOneByte,
"phi.src1");
602 Builder.
CreatePHI(MaxLoadType, NumLoadsNonOneByte,
"phi.src2");
605void MemCmpExpansion::setupEndBlockPHINodes() {
610Value *MemCmpExpansion::getMemCmpExpansionZeroCase() {
611 unsigned LoadIndex = 0;
614 for (
unsigned I = 0;
I < getNumBlocks(); ++
I) {
615 emitLoadCompareBlockMultipleLoads(
I, LoadIndex);
618 emitMemCmpResultBlock();
625Value *MemCmpExpansion::getMemCmpEqZeroOneBlock() {
626 unsigned LoadIndex = 0;
627 Value *
Cmp = getCompareLoadPairs(0, LoadIndex);
628 assert(LoadIndex == getNumLoads() &&
"some entries were not consumed");
637Value *MemCmpExpansion::getMemCmpOneBlock() {
638 bool NeedsBSwap =
DL.isLittleEndian() &&
Size != 1;
640 Type *BSwapSizeType =
650 const LoadPair Loads = getLoadPair(LoadSizeType, BSwapSizeType,
652 return Builder.
CreateSub(Loads.Lhs, Loads.Rhs);
655 const LoadPair Loads = getLoadPair(LoadSizeType, BSwapSizeType, MaxLoadType,
663 CmpPredicate Pred = ICmpInst::Predicate::BAD_ICMP_PREDICATE;
664 bool NeedsZExt =
false;
673 Pred = ICmpInst::ICMP_SLT;
678 Pred = ICmpInst::ICMP_SGE;
682 Pred = ICmpInst::ICMP_SLE;
688 if (ICmpInst::isSigned(Pred)) {
690 Loads.Lhs, Loads.Rhs);
692 UI->replaceAllUsesWith(Result);
693 UI->eraseFromParent();
701 {Loads.Lhs, Loads.Rhs});
706Value *MemCmpExpansion::getMemCmpExpansion() {
708 if (getNumBlocks() != 1) {
710 EndBlock =
SplitBlock(StartBlock, CI, DTU,
nullptr,
711 nullptr,
"endblock");
712 setupEndBlockPHINodes();
719 if (!IsUsedForZeroCmp) setupResultBlockPHINodes();
722 createLoadCmpBlocks();
728 DTU->
applyUpdates({{DominatorTree::Insert, StartBlock, LoadCmpBlocks[0]},
729 {DominatorTree::Delete, StartBlock, EndBlock}});
734 if (IsUsedForZeroCmp)
735 return getNumBlocks() == 1 ? getMemCmpEqZeroOneBlock()
736 : getMemCmpExpansionZeroCase();
738 if (getNumBlocks() == 1)
739 return getMemCmpOneBlock();
741 for (
unsigned I = 0;
I < getNumBlocks(); ++
I) {
742 emitLoadCompareBlock(
I);
745 emitMemCmpResultBlock();
822static bool expandMemCmp(CallInst *CI,
const TargetTransformInfo *
TTI,
823 const DataLayout *
DL, ProfileSummaryInfo *PSI,
824 BlockFrequencyInfo *BFI, DomTreeUpdater *DTU,
835 NumMemCmpNotConstant++;
845 const bool IsUsedForZeroCmp =
866 NumMemCmpGreaterThanMax++;
882static bool runOnBlock(BasicBlock &BB,
const TargetLibraryInfo *TLI,
883 const TargetTransformInfo *
TTI,
const DataLayout &
DL,
884 ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI,
885 DomTreeUpdater *DTU);
887static PreservedAnalyses
runImpl(Function &
F,
const TargetLibraryInfo *TLI,
888 const TargetTransformInfo *
TTI,
889 ProfileSummaryInfo *PSI,
890 BlockFrequencyInfo *BFI, DominatorTree *DT);
892bool runOnBlock(BasicBlock &BB,
const TargetLibraryInfo *TLI,
893 const TargetTransformInfo *
TTI,
const DataLayout &
DL,
894 ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI,
895 DomTreeUpdater *DTU) {
896 for (Instruction &
I : BB) {
903 (Func == LibFunc_memcmp || Func == LibFunc_bcmp) &&
904 expandMemCmp(CI,
TTI, &
DL, PSI, BFI, DTU, Func == LibFunc_bcmp)) {
911PreservedAnalyses
runImpl(Function &
F,
const TargetLibraryInfo *TLI,
912 const TargetTransformInfo *
TTI,
913 ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI,
915 std::optional<DomTreeUpdater> DTU;
917 DTU.emplace(DT, DomTreeUpdater::UpdateStrategy::Lazy);
919 const DataLayout&
DL =
F.getDataLayout();
920 bool MadeChanges =
false;
921 for (
auto BBIt =
F.begin(); BBIt !=
F.end();) {
922 if (runOnBlock(*BBIt, TLI,
TTI,
DL, PSI, BFI, DTU ? &*DTU :
nullptr)) {
932 for (BasicBlock &BB :
F)
936 PreservedAnalyses PA;
937 PA.
preserve<DominatorTreeAnalysis>();
947 if (
F.hasFnAttribute(Attribute::SanitizeAddress) ||
948 F.hasFnAttribute(Attribute::SanitizeMemory) ||
949 F.hasFnAttribute(Attribute::SanitizeThread) ||
950 F.hasFnAttribute(Attribute::SanitizeHWAddress))
956 .getCachedResult<ProfileSummaryAnalysis>(*
F.getParent());
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
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
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)
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; assumes that the block is well-formed.
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.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)
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.
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.
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.
@ 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.
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.