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"));
62static Align getMemCmpArgAlignment(
const CallInst *CI,
unsigned ArgNo,
66 A = std::max(
A, *ParamAlign);
72class MemCmpExpansion {
75 PHINode *PhiSrc1 =
nullptr;
76 PHINode *PhiSrc2 =
nullptr;
78 ResultBlock() =
default;
81 CallInst *
const CI =
nullptr;
84 unsigned MaxLoadSize = 0;
85 uint64_t NumLoadsNonOneByte = 0;
86 const uint64_t NumLoadsPerBlockForZeroCmp;
87 std::vector<BasicBlock *> LoadCmpBlocks;
89 PHINode *PhiRes =
nullptr;
90 const bool IsUsedForZeroCmp;
92 const TargetTransformInfo &TTI;
94 const Align CommonAlign;
95 DomTreeUpdater *DTU =
nullptr;
101 LoadEntry(
unsigned LoadSize, uint64_t Offset)
102 : LoadSize(LoadSize), Offset(Offset) {
110 using LoadEntryVector = SmallVector<LoadEntry, 8>;
111 LoadEntryVector LoadSequence;
113 void createLoadCmpBlocks();
114 void createResultBlock();
115 void setupResultBlockPHINodes();
116 void setupEndBlockPHINodes();
117 Value *getCompareLoadPairs(
unsigned BlockIndex,
unsigned &LoadIndex);
118 void emitLoadCompareBlock(
unsigned BlockIndex);
119 void emitLoadCompareBlockMultipleLoads(
unsigned BlockIndex,
120 unsigned &LoadIndex);
121 void emitLoadCompareByteBlock(
unsigned BlockIndex,
unsigned OffsetBytes);
122 void emitMemCmpResultBlock();
123 Value *getMemCmpExpansionZeroCase();
124 Value *getMemCmpEqZeroOneBlock();
125 Value *getMemCmpOneBlock();
127 Value *Lhs =
nullptr;
128 Value *Rhs =
nullptr;
130 LoadPair getLoadPair(
Type *LoadSizeType,
Type *BSwapSizeType,
131 Type *CmpSizeType,
unsigned OffsetBytes);
137 bool isAccessAllowed(
unsigned LoadSize, uint64_t
Offset)
const;
139 static LoadEntryVector
140 computeGreedyLoadSequence(uint64_t Size, llvm::ArrayRef<unsigned> LoadSizes,
141 unsigned MaxNumLoads,
unsigned &NumLoadsNonOneByte);
143 computeOverlappingLoadSequence(uint64_t Size,
unsigned MaxLoadSize,
144 unsigned MaxNumLoads,
145 unsigned &NumLoadsNonOneByte)
const;
147 void optimiseLoadSequence(
148 LoadEntryVector &LoadSequence,
149 const TargetTransformInfo::MemCmpExpansionOptions &
Options,
150 bool IsUsedForZeroCmp)
const;
153 MemCmpExpansion(CallInst *CI, uint64_t Size,
154 const TargetTransformInfo::MemCmpExpansionOptions &
Options,
155 const bool IsUsedForZeroCmp,
const DataLayout &TheDataLayout,
156 DomTreeUpdater *DTU,
const TargetTransformInfo &TTI,
159 unsigned getNumBlocks();
160 uint64_t getNumLoads()
const {
return LoadSequence.size(); }
162 Value *getMemCmpExpansion();
172 Align CommonAlign,
unsigned LoadSize,
180 if (AccessAlign.
value() >= LoadSize)
183 return TTI.allowsMisalignedMemoryAccesses(CI->
getContext(), LoadSize * 8, AS,
191bool MemCmpExpansion::isAccessAllowed(
unsigned LoadSize,
193 return ::isAccessAllowed(CI,
TTI, CommonAlign, LoadSize,
Offset);
196MemCmpExpansion::LoadEntryVector MemCmpExpansion::computeGreedyLoadSequence(
197 uint64_t
Size, llvm::ArrayRef<unsigned> LoadSizes,
198 const unsigned MaxNumLoads,
unsigned &NumLoadsNonOneByte) {
199 NumLoadsNonOneByte = 0;
200 LoadEntryVector LoadSequence;
203 const unsigned LoadSize = LoadSizes.
front();
204 const uint64_t NumLoadsForThisSize =
Size / LoadSize;
205 if (LoadSequence.size() + NumLoadsForThisSize > MaxNumLoads) {
212 if (NumLoadsForThisSize > 0) {
213 for (uint64_t
I = 0;
I < NumLoadsForThisSize; ++
I) {
214 LoadSequence.push_back({LoadSize,
Offset});
218 ++NumLoadsNonOneByte;
226MemCmpExpansion::LoadEntryVector
227MemCmpExpansion::computeOverlappingLoadSequence(
228 uint64_t
Size,
const unsigned MaxLoadSize,
const unsigned MaxNumLoads,
229 unsigned &NumLoadsNonOneByte)
const {
231 if (
Size < 2 || MaxLoadSize < 2)
236 const uint64_t NumNonOverlappingLoads =
Size / MaxLoadSize;
237 assert(NumNonOverlappingLoads &&
"there must be at least one load");
240 Size =
Size - NumNonOverlappingLoads * MaxLoadSize;
247 if ((NumNonOverlappingLoads + 1) > MaxNumLoads)
251 LoadEntryVector LoadSequence;
253 for (uint64_t
I = 0;
I < NumNonOverlappingLoads; ++
I) {
254 LoadSequence.push_back({MaxLoadSize,
Offset});
261 uint64_t OverlapOffset =
Offset - (MaxLoadSize -
Size);
262 if (!isAccessAllowed(MaxLoadSize, OverlapOffset))
265 LoadSequence.push_back({MaxLoadSize, OverlapOffset});
266 NumLoadsNonOneByte = 1;
270void MemCmpExpansion::optimiseLoadSequence(
271 LoadEntryVector &LoadSequence,
272 const TargetTransformInfo::MemCmpExpansionOptions &
Options,
273 bool IsUsedForZeroCmp)
const {
278 if (IsUsedForZeroCmp ||
Options.AllowedTailExpansions.empty())
281 while (LoadSequence.size() >= 2) {
282 auto Last = LoadSequence[LoadSequence.size() - 1];
283 auto PreLast = LoadSequence[LoadSequence.size() - 2];
286 if (PreLast.Offset + PreLast.LoadSize !=
Last.Offset)
289 auto LoadSize =
Last.LoadSize + PreLast.LoadSize;
290 if (
find(
Options.AllowedTailExpansions, LoadSize) ==
291 Options.AllowedTailExpansions.end())
300 if (LoadSize > MaxLoadSize && LoadSequence.size() > 2)
304 LoadSequence.pop_back();
305 LoadSequence.pop_back();
306 LoadSequence.emplace_back(LoadSize, PreLast.Offset);
318MemCmpExpansion::MemCmpExpansion(
319 CallInst *
const CI, uint64_t
Size,
320 const TargetTransformInfo::MemCmpExpansionOptions &
Options,
321 const bool IsUsedForZeroCmp,
const DataLayout &TheDataLayout,
322 DomTreeUpdater *DTU,
const TargetTransformInfo &
TTI, Align CommonAlign)
323 : CI(CI),
Size(
Size), NumLoadsPerBlockForZeroCmp(
Options.NumLoadsPerBlock),
324 IsUsedForZeroCmp(IsUsedForZeroCmp),
DL(TheDataLayout),
TTI(
TTI),
325 CommonAlign(CommonAlign), DTU(DTU), Builder(CI) {
332 assert(!LoadSizes.
empty() &&
"cannot load Size bytes");
333 MaxLoadSize = LoadSizes.
front();
335 unsigned GreedyNumLoadsNonOneByte = 0;
336 LoadSequence = computeGreedyLoadSequence(
Size, LoadSizes,
Options.MaxNumLoads,
337 GreedyNumLoadsNonOneByte);
338 NumLoadsNonOneByte = GreedyNumLoadsNonOneByte;
339 assert(LoadSequence.size() <=
Options.MaxNumLoads &&
"broken invariant");
342 if (
Options.AllowOverlappingLoads &&
343 (LoadSequence.empty() || LoadSequence.size() > 2)) {
344 unsigned OverlappingNumLoadsNonOneByte = 0;
345 auto OverlappingLoads = computeOverlappingLoadSequence(
346 Size, MaxLoadSize,
Options.MaxNumLoads, OverlappingNumLoadsNonOneByte);
347 if (!OverlappingLoads.empty() &&
348 (LoadSequence.empty() ||
349 OverlappingLoads.size() < LoadSequence.size())) {
350 LoadSequence = OverlappingLoads;
351 NumLoadsNonOneByte = OverlappingNumLoadsNonOneByte;
354 assert(LoadSequence.size() <=
Options.MaxNumLoads &&
"broken invariant");
355 optimiseLoadSequence(LoadSequence,
Options, IsUsedForZeroCmp);
358unsigned MemCmpExpansion::getNumBlocks() {
359 if (IsUsedForZeroCmp)
360 return getNumLoads() / NumLoadsPerBlockForZeroCmp +
361 (getNumLoads() % NumLoadsPerBlockForZeroCmp != 0 ? 1 : 0);
362 return getNumLoads();
365void MemCmpExpansion::createLoadCmpBlocks() {
366 for (
unsigned i = 0; i < getNumBlocks(); i++) {
369 LoadCmpBlocks.push_back(BB);
373void MemCmpExpansion::createResultBlock() {
378MemCmpExpansion::LoadPair MemCmpExpansion::getLoadPair(
Type *LoadSizeType,
381 unsigned OffsetBytes) {
385 Align LhsAlign = getMemCmpArgAlignment(CI, 0,
DL);
386 Align RhsAlign = getMemCmpArgAlignment(CI, 1,
DL);
387 if (OffsetBytes > 0) {
388 auto *ByteType = Type::getInt8Ty(CI->
getContext());
396 Value *Lhs =
nullptr;
402 Value *Rhs =
nullptr;
409 if (BSwapSizeType && LoadSizeType != BSwapSizeType) {
417 CI->
getModule(), Intrinsic::bswap, BSwapSizeType);
423 if (CmpSizeType !=
nullptr && CmpSizeType != Lhs->
getType()) {
434void MemCmpExpansion::emitLoadCompareByteBlock(
unsigned BlockIndex,
435 unsigned OffsetBytes) {
438 const LoadPair Loads =
439 getLoadPair(Type::getInt8Ty(CI->
getContext()),
nullptr,
440 Type::getInt32Ty(CI->
getContext()), OffsetBytes);
445 if (BlockIndex < (LoadCmpBlocks.size() - 1)) {
449 ConstantInt::get(Diff->
getType(), 0));
450 Builder.
CreateCondBr(Cmp, EndBlock, LoadCmpBlocks[BlockIndex + 1]);
453 {{DominatorTree::Insert, BB, EndBlock},
454 {DominatorTree::Insert, BB, LoadCmpBlocks[BlockIndex + 1]}});
459 DTU->
applyUpdates({{DominatorTree::Insert, BB, EndBlock}});
466Value *MemCmpExpansion::getCompareLoadPairs(
unsigned BlockIndex,
467 unsigned &LoadIndex) {
468 assert(LoadIndex < getNumLoads() &&
469 "getCompareLoadPairs() called with no remaining loads");
470 std::vector<Value *> XorList, OrList;
471 Value *Diff =
nullptr;
473 const unsigned NumLoads =
474 std::min(getNumLoads() - LoadIndex, NumLoadsPerBlockForZeroCmp);
477 if (LoadCmpBlocks.empty())
486 IntegerType *
const MaxLoadType =
487 NumLoads == 1 ? nullptr
490 for (
unsigned i = 0; i < NumLoads; ++i, ++LoadIndex) {
491 const LoadEntry &CurLoadEntry = LoadSequence[LoadIndex];
492 const LoadPair Loads = getLoadPair(
494 MaxLoadType, CurLoadEntry.Offset);
499 Diff = Builder.
CreateXor(Loads.Lhs, Loads.Rhs);
501 XorList.push_back(Diff);
508 auto pairWiseOr = [&](std::vector<Value *> &InList) -> std::vector<Value *> {
509 std::vector<Value *> OutList;
510 for (
unsigned i = 0; i < InList.size() - 1; i = i + 2) {
512 OutList.push_back(
Or);
514 if (InList.size() % 2 != 0)
515 OutList.push_back(InList.back());
521 OrList = pairWiseOr(XorList);
524 while (OrList.size() != 1) {
525 OrList = pairWiseOr(OrList);
528 assert(Diff &&
"Failed to find comparison diff");
535void MemCmpExpansion::emitLoadCompareBlockMultipleLoads(
unsigned BlockIndex,
536 unsigned &LoadIndex) {
537 Value *
Cmp = getCompareLoadPairs(BlockIndex, LoadIndex);
539 BasicBlock *NextBB = (BlockIndex == (LoadCmpBlocks.size() - 1))
541 : LoadCmpBlocks[BlockIndex + 1];
545 CondBrInst *CmpBr = Builder.
CreateCondBr(Cmp, ResBlock.BB, NextBB);
549 DTU->
applyUpdates({{DominatorTree::Insert, BB, ResBlock.BB},
550 {DominatorTree::Insert, BB, NextBB}});
555 if (BlockIndex == LoadCmpBlocks.size() - 1) {
557 PhiRes->
addIncoming(Zero, LoadCmpBlocks[BlockIndex]);
570void MemCmpExpansion::emitLoadCompareBlock(
unsigned BlockIndex) {
572 const LoadEntry &CurLoadEntry = LoadSequence[BlockIndex];
574 if (CurLoadEntry.LoadSize == 1) {
575 MemCmpExpansion::emitLoadCompareByteBlock(BlockIndex, CurLoadEntry.Offset);
581 Type *BSwapSizeType =
588 std::max(MaxLoadSize, (
unsigned)
PowerOf2Ceil(CurLoadEntry.LoadSize)) * 8);
589 assert(CurLoadEntry.LoadSize <= MaxLoadSize &&
"Unexpected load type");
593 const LoadPair Loads = getLoadPair(LoadSizeType, BSwapSizeType, MaxLoadType,
594 CurLoadEntry.Offset);
598 if (!IsUsedForZeroCmp) {
599 ResBlock.PhiSrc1->addIncoming(Loads.Lhs, LoadCmpBlocks[BlockIndex]);
600 ResBlock.PhiSrc2->addIncoming(Loads.Rhs, LoadCmpBlocks[BlockIndex]);
604 BasicBlock *NextBB = (BlockIndex == (LoadCmpBlocks.size() - 1))
606 : LoadCmpBlocks[BlockIndex + 1];
610 CondBrInst *CmpBr = Builder.
CreateCondBr(Cmp, NextBB, ResBlock.BB);
615 {DominatorTree::Insert, BB, ResBlock.BB}});
620 if (BlockIndex == LoadCmpBlocks.size() - 1) {
622 PhiRes->
addIncoming(Zero, LoadCmpBlocks[BlockIndex]);
629void MemCmpExpansion::emitMemCmpResultBlock() {
632 if (IsUsedForZeroCmp) {
639 DTU->
applyUpdates({{DominatorTree::Insert, ResBlock.BB, EndBlock}});
657 DTU->
applyUpdates({{DominatorTree::Insert, ResBlock.BB, EndBlock}});
660void MemCmpExpansion::setupResultBlockPHINodes() {
665 Builder.
CreatePHI(MaxLoadType, NumLoadsNonOneByte,
"phi.src1");
667 Builder.
CreatePHI(MaxLoadType, NumLoadsNonOneByte,
"phi.src2");
670void MemCmpExpansion::setupEndBlockPHINodes() {
675Value *MemCmpExpansion::getMemCmpExpansionZeroCase() {
676 unsigned LoadIndex = 0;
679 for (
unsigned I = 0;
I < getNumBlocks(); ++
I) {
680 emitLoadCompareBlockMultipleLoads(
I, LoadIndex);
683 emitMemCmpResultBlock();
690Value *MemCmpExpansion::getMemCmpEqZeroOneBlock() {
691 unsigned LoadIndex = 0;
692 Value *
Cmp = getCompareLoadPairs(0, LoadIndex);
693 assert(LoadIndex == getNumLoads() &&
"some entries were not consumed");
702Value *MemCmpExpansion::getMemCmpOneBlock() {
703 bool NeedsBSwap =
DL.isLittleEndian() &&
Size != 1;
705 Type *BSwapSizeType =
715 const LoadPair Loads = getLoadPair(LoadSizeType, BSwapSizeType,
717 return Builder.
CreateSub(Loads.Lhs, Loads.Rhs);
720 const LoadPair Loads = getLoadPair(LoadSizeType, BSwapSizeType, MaxLoadType,
728 CmpPredicate Pred = ICmpInst::Predicate::BAD_ICMP_PREDICATE;
729 bool NeedsZExt =
false;
738 Pred = ICmpInst::ICMP_SLT;
743 Pred = ICmpInst::ICMP_SGE;
747 Pred = ICmpInst::ICMP_SLE;
753 if (ICmpInst::isSigned(Pred)) {
755 Loads.Lhs, Loads.Rhs);
757 UI->replaceAllUsesWith(Result);
758 UI->eraseFromParent();
766 {Loads.Lhs, Loads.Rhs});
771Value *MemCmpExpansion::getMemCmpExpansion() {
773 if (getNumBlocks() != 1) {
775 EndBlock =
SplitBlock(StartBlock, CI, DTU,
nullptr,
776 nullptr,
"endblock");
777 setupEndBlockPHINodes();
784 if (!IsUsedForZeroCmp) setupResultBlockPHINodes();
787 createLoadCmpBlocks();
793 DTU->
applyUpdates({{DominatorTree::Insert, StartBlock, LoadCmpBlocks[0]},
794 {DominatorTree::Delete, StartBlock, EndBlock}});
799 if (IsUsedForZeroCmp)
800 return getNumBlocks() == 1 ? getMemCmpEqZeroOneBlock()
801 : getMemCmpExpansionZeroCase();
803 if (getNumBlocks() == 1)
804 return getMemCmpOneBlock();
806 for (
unsigned I = 0;
I < getNumBlocks(); ++
I) {
807 emitLoadCompareBlock(
I);
810 emitMemCmpResultBlock();
887static bool expandMemCmp(CallInst *CI,
const TargetTransformInfo *
TTI,
888 const DataLayout *
DL, ProfileSummaryInfo *PSI,
889 BlockFrequencyInfo *BFI, DomTreeUpdater *DTU,
900 NumMemCmpNotConstant++;
910 const bool IsUsedForZeroCmp =
936 const Align CommonAlign = std::min(getMemCmpArgAlignment(CI, 0, *
DL),
937 getMemCmpArgAlignment(CI, 1, *
DL));
939 return !isAccessAllowed(CI, *TTI, CommonAlign, LoadSize, 0);
953 NumMemCmpGreaterThanMax++;
968static PreservedAnalyses
runImpl(Function &
F,
const TargetLibraryInfo *TLI,
969 const TargetTransformInfo *
TTI,
970 ProfileSummaryInfo *PSI,
971 BlockFrequencyInfo *BFI, DominatorTree *DT) {
972 std::optional<DomTreeUpdater> DTU;
974 DTU.emplace(DT, DomTreeUpdater::UpdateStrategy::Lazy);
976 const DataLayout&
DL =
F.getDataLayout();
982 (Func == LibFunc_memcmp || Func == LibFunc_bcmp))
987 bool MadeChanges =
false;
988 for (
const auto &[CI, Func] : MemCmpCalls) {
989 if (expandMemCmp(CI,
TTI, &
DL, PSI, BFI, DTU ? &*DTU :
nullptr,
990 Func == LibFunc_bcmp))
995 for (BasicBlock &BB :
F)
999 PreservedAnalyses PA;
1000 PA.
preserve<DominatorTreeAnalysis>();
1010 if (
F.hasFnAttribute(Attribute::SanitizeAddress) ||
1011 F.hasFnAttribute(Attribute::SanitizeMemory) ||
1012 F.hasFnAttribute(Attribute::SanitizeThread) ||
1013 F.hasFnAttribute(Attribute::SanitizeHWAddress))
1019 .getCachedResult<ProfileSummaryAnalysis>(*
F.getParent());
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Expand Atomic instructions
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static bool runImpl(MachineFunction &MF)
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)
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
Get the first element.
bool empty() const
Check if the array is empty.
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...
MaybeAlign getParamAlign(unsigned ArgNo) const
Extract the alignment for a call or parameter (0=unknown).
Value * getArgOperand(unsigned i) const
This class represents a function call, abstracting a target machine's calling convention.
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)
A parsed version of the target data layout string in and methods for querying it.
Analysis pass which computes a DominatorTree.
LLVM_ABI 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.
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)
LLVM_ABI Value * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > OverloadTypes, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="", ArrayRef< OperandBundleDef > OpBundles={}, function_ref< void(CallInst *)> SetFn=[](CallInst *) {})
Variant to create a possibly constant-folded intrinsic.
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
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
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.
@ 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.
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...
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
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.
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
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.
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.