36#define DEBUG_TYPE "expand-memcmp"
39STATISTIC(NumMemCmpNotConstant,
"Number of memcmp calls without constant size");
41 "Number of memcmp calls with size greater than max size");
42STATISTIC(NumMemCmpInlined,
"Number of inlined memcmp calls");
46 cl::desc(
"The number of loads per basic block for inline expansion of "
47 "memcmp that is only being compared against zero."));
51 cl::desc(
"Set maximum number of loads used in expanded memcmp"));
55 cl::desc(
"Set maximum number of loads used in expanded memcmp for -Os/Oz"));
62class MemCmpExpansion {
68 ResultBlock() =
default;
71 CallInst *
const CI =
nullptr;
74 unsigned MaxLoadSize = 0;
75 uint64_t NumLoadsNonOneByte = 0;
76 const uint64_t NumLoadsPerBlockForZeroCmp;
77 std::vector<BasicBlock *> LoadCmpBlocks;
79 PHINode *PhiRes =
nullptr;
80 const bool IsUsedForZeroCmp;
82 DomTreeUpdater *DTU =
nullptr;
88 LoadEntry(
unsigned LoadSize, uint64_t Offset)
89 : LoadSize(LoadSize), Offset(Offset) {
97 using LoadEntryVector = SmallVector<LoadEntry, 8>;
98 LoadEntryVector LoadSequence;
100 void createLoadCmpBlocks();
101 void createResultBlock();
102 void setupResultBlockPHINodes();
103 void setupEndBlockPHINodes();
104 Value *getCompareLoadPairs(
unsigned BlockIndex,
unsigned &LoadIndex);
105 void emitLoadCompareBlock(
unsigned BlockIndex);
106 void emitLoadCompareBlockMultipleLoads(
unsigned BlockIndex,
107 unsigned &LoadIndex);
108 void emitLoadCompareByteBlock(
unsigned BlockIndex,
unsigned OffsetBytes);
109 void emitMemCmpResultBlock();
110 Value *getMemCmpExpansionZeroCase();
111 Value *getMemCmpEqZeroOneBlock();
112 Value *getMemCmpOneBlock();
114 Value *Lhs =
nullptr;
115 Value *Rhs =
nullptr;
117 LoadPair getLoadPair(
Type *LoadSizeType,
Type *BSwapSizeType,
118 Type *CmpSizeType,
unsigned OffsetBytes);
120 static LoadEntryVector
121 computeGreedyLoadSequence(uint64_t Size, llvm::ArrayRef<unsigned> LoadSizes,
122 unsigned MaxNumLoads,
unsigned &NumLoadsNonOneByte);
123 static LoadEntryVector
124 computeOverlappingLoadSequence(uint64_t Size,
unsigned MaxLoadSize,
125 unsigned MaxNumLoads,
126 unsigned &NumLoadsNonOneByte);
128 static void optimiseLoadSequence(
129 LoadEntryVector &LoadSequence,
130 const TargetTransformInfo::MemCmpExpansionOptions &
Options,
131 bool IsUsedForZeroCmp);
134 MemCmpExpansion(CallInst *CI, uint64_t Size,
135 const TargetTransformInfo::MemCmpExpansionOptions &
Options,
136 const bool IsUsedForZeroCmp,
const DataLayout &TheDataLayout,
137 DomTreeUpdater *DTU);
139 unsigned getNumBlocks();
140 uint64_t getNumLoads()
const {
return LoadSequence.size(); }
142 Value *getMemCmpExpansion();
145MemCmpExpansion::LoadEntryVector MemCmpExpansion::computeGreedyLoadSequence(
147 const unsigned MaxNumLoads,
unsigned &NumLoadsNonOneByte) {
148 NumLoadsNonOneByte = 0;
149 LoadEntryVector LoadSequence;
152 const unsigned LoadSize = LoadSizes.
front();
153 const uint64_t NumLoadsForThisSize =
Size / LoadSize;
154 if (LoadSequence.size() + NumLoadsForThisSize > MaxNumLoads) {
161 if (NumLoadsForThisSize > 0) {
162 for (uint64_t
I = 0;
I < NumLoadsForThisSize; ++
I) {
163 LoadSequence.push_back({LoadSize,
Offset});
167 ++NumLoadsNonOneByte;
175MemCmpExpansion::LoadEntryVector
176MemCmpExpansion::computeOverlappingLoadSequence(uint64_t
Size,
177 const unsigned MaxLoadSize,
178 const unsigned MaxNumLoads,
179 unsigned &NumLoadsNonOneByte) {
181 if (
Size < 2 || MaxLoadSize < 2)
186 const uint64_t NumNonOverlappingLoads =
Size / MaxLoadSize;
187 assert(NumNonOverlappingLoads &&
"there must be at least one load");
190 Size =
Size - NumNonOverlappingLoads * MaxLoadSize;
197 if ((NumNonOverlappingLoads + 1) > MaxNumLoads)
201 LoadEntryVector LoadSequence;
203 for (uint64_t
I = 0;
I < NumNonOverlappingLoads; ++
I) {
204 LoadSequence.push_back({MaxLoadSize,
Offset});
210 LoadSequence.push_back({MaxLoadSize,
Offset - (MaxLoadSize -
Size)});
211 NumLoadsNonOneByte = 1;
215void MemCmpExpansion::optimiseLoadSequence(
216 LoadEntryVector &LoadSequence,
217 const TargetTransformInfo::MemCmpExpansionOptions &
Options,
218 bool IsUsedForZeroCmp) {
223 if (IsUsedForZeroCmp ||
Options.AllowedTailExpansions.empty())
226 while (LoadSequence.size() >= 2) {
227 auto Last = LoadSequence[LoadSequence.size() - 1];
228 auto PreLast = LoadSequence[LoadSequence.size() - 2];
231 if (PreLast.Offset + PreLast.LoadSize !=
Last.Offset)
234 auto LoadSize =
Last.LoadSize + PreLast.LoadSize;
235 if (
find(
Options.AllowedTailExpansions, LoadSize) ==
236 Options.AllowedTailExpansions.end())
240 LoadSequence.pop_back();
241 LoadSequence.pop_back();
242 LoadSequence.emplace_back(PreLast.Offset, LoadSize);
254MemCmpExpansion::MemCmpExpansion(
255 CallInst *
const CI, uint64_t
Size,
256 const TargetTransformInfo::MemCmpExpansionOptions &
Options,
257 const bool IsUsedForZeroCmp,
const DataLayout &TheDataLayout,
259 : CI(CI),
Size(
Size), NumLoadsPerBlockForZeroCmp(
Options.NumLoadsPerBlock),
260 IsUsedForZeroCmp(IsUsedForZeroCmp),
DL(TheDataLayout), DTU(DTU),
268 assert(!LoadSizes.
empty() &&
"cannot load Size bytes");
269 MaxLoadSize = LoadSizes.
front();
271 unsigned GreedyNumLoadsNonOneByte = 0;
272 LoadSequence = computeGreedyLoadSequence(
Size, LoadSizes,
Options.MaxNumLoads,
273 GreedyNumLoadsNonOneByte);
274 NumLoadsNonOneByte = GreedyNumLoadsNonOneByte;
275 assert(LoadSequence.size() <=
Options.MaxNumLoads &&
"broken invariant");
278 if (
Options.AllowOverlappingLoads &&
279 (LoadSequence.empty() || LoadSequence.size() > 2)) {
280 unsigned OverlappingNumLoadsNonOneByte = 0;
281 auto OverlappingLoads = computeOverlappingLoadSequence(
282 Size, MaxLoadSize,
Options.MaxNumLoads, OverlappingNumLoadsNonOneByte);
283 if (!OverlappingLoads.empty() &&
284 (LoadSequence.empty() ||
285 OverlappingLoads.size() < LoadSequence.size())) {
286 LoadSequence = OverlappingLoads;
287 NumLoadsNonOneByte = OverlappingNumLoadsNonOneByte;
290 assert(LoadSequence.size() <=
Options.MaxNumLoads &&
"broken invariant");
291 optimiseLoadSequence(LoadSequence,
Options, IsUsedForZeroCmp);
294unsigned MemCmpExpansion::getNumBlocks() {
295 if (IsUsedForZeroCmp)
296 return getNumLoads() / NumLoadsPerBlockForZeroCmp +
297 (getNumLoads() % NumLoadsPerBlockForZeroCmp != 0 ? 1 : 0);
298 return getNumLoads();
301void MemCmpExpansion::createLoadCmpBlocks() {
302 for (
unsigned i = 0; i < getNumBlocks(); i++) {
305 LoadCmpBlocks.push_back(BB);
309void MemCmpExpansion::createResultBlock() {
314MemCmpExpansion::LoadPair MemCmpExpansion::getLoadPair(
Type *LoadSizeType,
317 unsigned OffsetBytes) {
323 if (OffsetBytes > 0) {
324 auto *ByteType = Type::getInt8Ty(CI->
getContext());
332 Value *Lhs =
nullptr;
338 Value *Rhs =
nullptr;
345 if (BSwapSizeType && LoadSizeType != BSwapSizeType) {
353 CI->
getModule(), Intrinsic::bswap, BSwapSizeType);
359 if (CmpSizeType !=
nullptr && CmpSizeType != Lhs->
getType()) {
370void MemCmpExpansion::emitLoadCompareByteBlock(
unsigned BlockIndex,
371 unsigned OffsetBytes) {
374 const LoadPair Loads =
375 getLoadPair(Type::getInt8Ty(CI->
getContext()),
nullptr,
376 Type::getInt32Ty(CI->
getContext()), OffsetBytes);
381 if (BlockIndex < (LoadCmpBlocks.size() - 1)) {
385 ConstantInt::get(Diff->
getType(), 0));
386 Builder.
CreateCondBr(Cmp, EndBlock, LoadCmpBlocks[BlockIndex + 1]);
389 {{DominatorTree::Insert, BB, EndBlock},
390 {DominatorTree::Insert, BB, LoadCmpBlocks[BlockIndex + 1]}});
395 DTU->
applyUpdates({{DominatorTree::Insert, BB, EndBlock}});
402Value *MemCmpExpansion::getCompareLoadPairs(
unsigned BlockIndex,
403 unsigned &LoadIndex) {
404 assert(LoadIndex < getNumLoads() &&
405 "getCompareLoadPairs() called with no remaining loads");
406 std::vector<Value *> XorList, OrList;
407 Value *Diff =
nullptr;
409 const unsigned NumLoads =
410 std::min(getNumLoads() - LoadIndex, NumLoadsPerBlockForZeroCmp);
413 if (LoadCmpBlocks.empty())
422 IntegerType *
const MaxLoadType =
423 NumLoads == 1 ? nullptr
426 for (
unsigned i = 0; i < NumLoads; ++i, ++LoadIndex) {
427 const LoadEntry &CurLoadEntry = LoadSequence[LoadIndex];
428 const LoadPair Loads = getLoadPair(
430 MaxLoadType, CurLoadEntry.Offset);
435 Diff = Builder.
CreateXor(Loads.Lhs, Loads.Rhs);
437 XorList.push_back(Diff);
444 auto pairWiseOr = [&](std::vector<Value *> &InList) -> std::vector<Value *> {
445 std::vector<Value *> OutList;
446 for (
unsigned i = 0; i < InList.size() - 1; i = i + 2) {
448 OutList.push_back(
Or);
450 if (InList.size() % 2 != 0)
451 OutList.push_back(InList.back());
457 OrList = pairWiseOr(XorList);
460 while (OrList.size() != 1) {
461 OrList = pairWiseOr(OrList);
464 assert(Diff &&
"Failed to find comparison diff");
471void MemCmpExpansion::emitLoadCompareBlockMultipleLoads(
unsigned BlockIndex,
472 unsigned &LoadIndex) {
473 Value *
Cmp = getCompareLoadPairs(BlockIndex, LoadIndex);
475 BasicBlock *NextBB = (BlockIndex == (LoadCmpBlocks.size() - 1))
477 : LoadCmpBlocks[BlockIndex + 1];
481 CondBrInst *CmpBr = Builder.
CreateCondBr(Cmp, ResBlock.BB, NextBB);
485 DTU->
applyUpdates({{DominatorTree::Insert, BB, ResBlock.BB},
486 {DominatorTree::Insert, BB, NextBB}});
491 if (BlockIndex == LoadCmpBlocks.size() - 1) {
493 PhiRes->
addIncoming(Zero, LoadCmpBlocks[BlockIndex]);
506void MemCmpExpansion::emitLoadCompareBlock(
unsigned BlockIndex) {
508 const LoadEntry &CurLoadEntry = LoadSequence[BlockIndex];
510 if (CurLoadEntry.LoadSize == 1) {
511 MemCmpExpansion::emitLoadCompareByteBlock(BlockIndex, CurLoadEntry.Offset);
517 Type *BSwapSizeType =
524 std::max(MaxLoadSize, (
unsigned)
PowerOf2Ceil(CurLoadEntry.LoadSize)) * 8);
525 assert(CurLoadEntry.LoadSize <= MaxLoadSize &&
"Unexpected load type");
529 const LoadPair Loads = getLoadPair(LoadSizeType, BSwapSizeType, MaxLoadType,
530 CurLoadEntry.Offset);
534 if (!IsUsedForZeroCmp) {
535 ResBlock.PhiSrc1->addIncoming(Loads.Lhs, LoadCmpBlocks[BlockIndex]);
536 ResBlock.PhiSrc2->addIncoming(Loads.Rhs, LoadCmpBlocks[BlockIndex]);
540 BasicBlock *NextBB = (BlockIndex == (LoadCmpBlocks.size() - 1))
542 : LoadCmpBlocks[BlockIndex + 1];
546 CondBrInst *CmpBr = Builder.
CreateCondBr(Cmp, NextBB, ResBlock.BB);
551 {DominatorTree::Insert, BB, ResBlock.BB}});
556 if (BlockIndex == LoadCmpBlocks.size() - 1) {
558 PhiRes->
addIncoming(Zero, LoadCmpBlocks[BlockIndex]);
565void MemCmpExpansion::emitMemCmpResultBlock() {
568 if (IsUsedForZeroCmp) {
575 DTU->
applyUpdates({{DominatorTree::Insert, ResBlock.BB, EndBlock}});
593 DTU->
applyUpdates({{DominatorTree::Insert, ResBlock.BB, EndBlock}});
596void MemCmpExpansion::setupResultBlockPHINodes() {
601 Builder.
CreatePHI(MaxLoadType, NumLoadsNonOneByte,
"phi.src1");
603 Builder.
CreatePHI(MaxLoadType, NumLoadsNonOneByte,
"phi.src2");
606void MemCmpExpansion::setupEndBlockPHINodes() {
611Value *MemCmpExpansion::getMemCmpExpansionZeroCase() {
612 unsigned LoadIndex = 0;
615 for (
unsigned I = 0;
I < getNumBlocks(); ++
I) {
616 emitLoadCompareBlockMultipleLoads(
I, LoadIndex);
619 emitMemCmpResultBlock();
626Value *MemCmpExpansion::getMemCmpEqZeroOneBlock() {
627 unsigned LoadIndex = 0;
628 Value *
Cmp = getCompareLoadPairs(0, LoadIndex);
629 assert(LoadIndex == getNumLoads() &&
"some entries were not consumed");
638Value *MemCmpExpansion::getMemCmpOneBlock() {
639 bool NeedsBSwap =
DL.isLittleEndian() &&
Size != 1;
641 Type *BSwapSizeType =
651 const LoadPair Loads = getLoadPair(LoadSizeType, BSwapSizeType,
653 return Builder.
CreateSub(Loads.Lhs, Loads.Rhs);
656 const LoadPair Loads = getLoadPair(LoadSizeType, BSwapSizeType, MaxLoadType,
664 CmpPredicate Pred = ICmpInst::Predicate::BAD_ICMP_PREDICATE;
665 bool NeedsZExt =
false;
674 Pred = ICmpInst::ICMP_SLT;
679 Pred = ICmpInst::ICMP_SGE;
683 Pred = ICmpInst::ICMP_SLE;
689 if (ICmpInst::isSigned(Pred)) {
691 Loads.Lhs, Loads.Rhs);
693 UI->replaceAllUsesWith(Result);
694 UI->eraseFromParent();
702 {Loads.Lhs, Loads.Rhs});
707Value *MemCmpExpansion::getMemCmpExpansion() {
709 if (getNumBlocks() != 1) {
711 EndBlock =
SplitBlock(StartBlock, CI, DTU,
nullptr,
712 nullptr,
"endblock");
713 setupEndBlockPHINodes();
720 if (!IsUsedForZeroCmp) setupResultBlockPHINodes();
723 createLoadCmpBlocks();
729 DTU->
applyUpdates({{DominatorTree::Insert, StartBlock, LoadCmpBlocks[0]},
730 {DominatorTree::Delete, StartBlock, EndBlock}});
735 if (IsUsedForZeroCmp)
736 return getNumBlocks() == 1 ? getMemCmpEqZeroOneBlock()
737 : getMemCmpExpansionZeroCase();
739 if (getNumBlocks() == 1)
740 return getMemCmpOneBlock();
742 for (
unsigned I = 0;
I < getNumBlocks(); ++
I) {
743 emitLoadCompareBlock(
I);
746 emitMemCmpResultBlock();
823static bool expandMemCmp(CallInst *CI,
const TargetTransformInfo *
TTI,
824 const DataLayout *
DL, ProfileSummaryInfo *PSI,
825 BlockFrequencyInfo *BFI, DomTreeUpdater *DTU,
836 NumMemCmpNotConstant++;
846 const bool IsUsedForZeroCmp =
867 NumMemCmpGreaterThanMax++;
882static PreservedAnalyses
runImpl(Function &
F,
const TargetLibraryInfo *TLI,
883 const TargetTransformInfo *
TTI,
884 ProfileSummaryInfo *PSI,
885 BlockFrequencyInfo *BFI, DominatorTree *DT) {
886 std::optional<DomTreeUpdater> DTU;
888 DTU.emplace(DT, DomTreeUpdater::UpdateStrategy::Lazy);
890 const DataLayout&
DL =
F.getDataLayout();
896 (Func == LibFunc_memcmp || Func == LibFunc_bcmp))
901 bool MadeChanges =
false;
902 for (
const auto [CI, Func] : MemCmpCalls) {
903 if (expandMemCmp(CI,
TTI, &
DL, PSI, BFI, DTU ? &*DTU :
nullptr,
904 Func == LibFunc_bcmp))
909 for (BasicBlock &BB :
F)
913 PreservedAnalyses PA;
914 PA.
preserve<DominatorTreeAnalysis>();
924 if (
F.hasFnAttribute(Attribute::SanitizeAddress) ||
925 F.hasFnAttribute(Attribute::SanitizeMemory) ||
926 F.hasFnAttribute(Attribute::SanitizeThread) ||
927 F.hasFnAttribute(Attribute::SanitizeHWAddress))
933 .getCachedResult<ProfileSummaryAnalysis>(*
F.getParent());
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Expand Atomic instructions
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)
void SetCurrentDebugLocation(const DebugLoc &L)
Set location information used by debugging information.
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
BasicBlock * GetInsertBlock() const
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 * > OverloadTypes, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with Args, mangled using OverloadTypes.
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.
void push_back(const T &Elt)
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 * > OverloadTys={})
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.
auto m_Value()
Match an arbitrary value and ignore it.
SpecificCmpClass_match< LHS, RHS, ICmpInst > m_SpecificICmp(CmpPredicate MatchPred, const LHS &L, const RHS &R)
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.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
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.