175 "disable-separate-const-offset-from-gep",
cl::init(
false),
176 cl::desc(
"Do not separate the constant offset from a GEP instruction"),
184 cl::desc(
"Verify this pass produces no dead code"),
202class ConstantOffsetExtractor {
214 User *&UserChainTail,
bool &PreservesNUW);
223 : IP(InsertionPt),
DL(InsertionPt->getDataLayout()) {}
242 APInt findInEitherOperand(BinaryOperator *BO,
bool SignExtended,
260 Value *rebuildWithoutConstOffset();
278 Value *distributeCastsAndCloneChain(
unsigned ChainIndex);
281 Value *removeConstOffset(
unsigned ChainIndex);
295 bool CanTraceInto(
bool SignExtended,
bool ZeroExtended, BinaryOperator *BO,
313 const DataLayout &DL;
319class SeparateConstOffsetFromGEPLegacyPass :
public FunctionPass {
323 SeparateConstOffsetFromGEPLegacyPass(
bool LowerGEP =
false)
324 : FunctionPass(ID), LowerGEP(LowerGEP) {
329 void getAnalysisUsage(AnalysisUsage &AU)
const override {
346class SeparateConstOffsetFromGEP {
348 SeparateConstOffsetFromGEP(
349 DominatorTree *DT, LoopInfo *LI, TargetLibraryInfo *TLI,
350 function_ref<TargetTransformInfo &(Function &)> GetTTI,
bool LowerGEP)
351 : DT(DT), LI(LI), TLI(TLI), GetTTI(GetTTI), LowerGEP(LowerGEP) {}
353 bool run(Function &
F);
357 using ExprKey = std::pair<Value *, Value *>;
360 static ExprKey createNormalizedCommutablePair(
Value *
A,
Value *
B) {
368 bool splitGEP(GetElementPtrInst *
GEP);
373 bool reorderGEP(GetElementPtrInst *
GEP, TargetTransformInfo &
TTI);
382 void lowerToSingleIndexGEPs(GetElementPtrInst *Variadic,
383 const APInt &AccumulativeByteOffset);
390 APInt accumulateByteOffset(GetElementPtrInst *
GEP,
bool &NeedsExtraction);
407 bool canonicalizeArrayIndicesToIndexSize(GetElementPtrInst *
GEP);
418 bool reuniteExts(Function &
F);
421 bool reuniteExts(Instruction *
I);
425 ExprKey
Key, Instruction *Dominatee,
426 DenseMap<ExprKey, SmallVector<Instruction *, 2>> &DominatingExprs);
429 void verifyNoDeadCode(Function &
F);
431 bool hasMoreThanOneUseInLoop(
Value *v, Loop *L);
434 void swapGEPOperand(GetElementPtrInst *
First, GetElementPtrInst *Second);
437 bool isLegalToSwapOperand(GetElementPtrInst *
First, GetElementPtrInst *Second,
440 const DataLayout *DL =
nullptr;
441 DominatorTree *DT =
nullptr;
443 TargetLibraryInfo *TLI;
445 function_ref<TargetTransformInfo &(
Function &)> GetTTI;
451 DenseMap<ExprKey, SmallVector<Instruction *, 2>> DominatingAdds;
452 DenseMap<ExprKey, SmallVector<Instruction *, 2>> DominatingSubs;
457char SeparateConstOffsetFromGEPLegacyPass::ID = 0;
460 SeparateConstOffsetFromGEPLegacyPass,
"separate-const-offset-from-gep",
461 "Split GEPs to a variadic base and a constant offset for better CSE",
false,
469 SeparateConstOffsetFromGEPLegacyPass,
"separate-const-offset-from-gep",
470 "Split GEPs to a variadic base and a constant offset for better CSE",
false,
474 return new SeparateConstOffsetFromGEPLegacyPass(LowerGEP);
477bool ConstantOffsetExtractor::CanTraceInto(
bool SignExtended,
484 if (BO->
getOpcode() != Instruction::Add &&
493 if (BO->
getOpcode() == Instruction::Or &&
500 if (ZeroExtended && !SignExtended && BO->
getOpcode() == Instruction::Sub)
524 if (!ConstLHS->isNegative())
528 if (!ConstRHS->isNegative())
535 if (BO->
getOpcode() == Instruction::Add ||
546APInt ConstantOffsetExtractor::findInEitherOperand(BinaryOperator *BO,
550 size_t ChainLength = UserChain.size();
554 APInt ConstantOffset =
find(BO->
getOperand(0), SignExtended, ZeroExtended,
561 if (ConstantOffset != 0)
return ConstantOffset;
565 UserChain.resize(ChainLength);
567 ConstantOffset =
find(BO->
getOperand(1), SignExtended, ZeroExtended,
572 ConstantOffset = -ConstantOffset;
575 if (ConstantOffset == 0)
576 UserChain.resize(ChainLength);
578 return ConstantOffset;
581APInt ConstantOffsetExtractor::find(
Value *V,
bool SignExtended,
590 if (U ==
nullptr)
return APInt(
BitWidth, 0);
595 ConstantOffset = CI->getValue();
598 if (CanTraceInto(SignExtended, ZeroExtended, BO,
NonNegative))
599 ConstantOffset = findInEitherOperand(BO, SignExtended, ZeroExtended);
605 ConstantOffset =
find(
U->getOperand(0),
true,
613 find(
U->getOperand(0),
false,
620 if (ConstantOffset != 0)
621 UserChain.push_back(U);
622 return ConstantOffset;
625Value *ConstantOffsetExtractor::applyCasts(
Value *V) {
652Value *ConstantOffsetExtractor::rebuildWithoutConstOffset() {
653 distributeCastsAndCloneChain(UserChain.size() - 1);
655 unsigned NewSize = 0;
656 for (User *
I : UserChain) {
658 UserChain[NewSize] =
I;
662 UserChain.resize(NewSize);
663 return removeConstOffset(UserChain.size() - 1);
667ConstantOffsetExtractor::distributeCastsAndCloneChain(
unsigned ChainIndex) {
668 User *
U = UserChain[ChainIndex];
669 if (ChainIndex == 0) {
678 "Only following instructions can be traced: sext, zext & trunc");
679 CastInsts.push_back(Cast);
680 UserChain[ChainIndex] =
nullptr;
681 return distributeCastsAndCloneChain(ChainIndex - 1);
687 unsigned OpNo = (BO->
getOperand(0) == UserChain[ChainIndex - 1] ? 0 : 1);
689 Value *NextInChain = distributeCastsAndCloneChain(ChainIndex - 1);
691 BinaryOperator *NewBO =
nullptr;
699 return UserChain[ChainIndex] = NewBO;
702Value *ConstantOffsetExtractor::removeConstOffset(
unsigned ChainIndex) {
703 if (ChainIndex == 0) {
705 return ConstantInt::getNullValue(UserChain[ChainIndex]->
getType());
710 "distributeCastsAndCloneChain clones each BinaryOperator in "
711 "UserChain, so no one should be used more than "
714 unsigned OpNo = (BO->
getOperand(0) == UserChain[ChainIndex - 1] ? 0 : 1);
716 Value *NextInChain = removeConstOffset(ChainIndex - 1);
722 if (CI->isZero() && !(BO->
getOpcode() == Instruction::Sub && OpNo == 0))
726 BinaryOperator::BinaryOps NewOp = BO->
getOpcode();
727 if (BO->
getOpcode() == Instruction::Or) {
741 NewOp = Instruction::Add;
744 BinaryOperator *NewBO;
760 if (Opcode == BinaryOperator::Or) {
773 return TI->hasNoUnsignedWrap();
778Value *ConstantOffsetExtractor::Extract(
Value *Idx, GetElementPtrInst *
GEP,
779 User *&UserChainTail,
780 bool &PreservesNUW) {
781 ConstantOffsetExtractor Extractor(
GEP->getIterator());
783 APInt ConstantOffset =
784 Extractor.find(Idx,
false,
false,
786 if (ConstantOffset == 0) {
787 UserChainTail =
nullptr;
795 Value *IdxWithoutConstOffset = Extractor.rebuildWithoutConstOffset();
796 UserChainTail = Extractor.UserChain.back();
797 return IdxWithoutConstOffset;
800APInt ConstantOffsetExtractor::Find(
Value *Idx, GetElementPtrInst *
GEP) {
802 return ConstantOffsetExtractor(
GEP->getIterator())
803 .find(Idx,
false,
false,
807bool SeparateConstOffsetFromGEP::canonicalizeArrayIndicesToIndexSize(
808 GetElementPtrInst *
GEP) {
810 Type *PtrIdxTy =
DL->getIndexType(
GEP->getType());
813 I !=
E; ++
I, ++GTI) {
816 if ((*I)->getType() != PtrIdxTy) {
826APInt SeparateConstOffsetFromGEP::accumulateByteOffset(GetElementPtrInst *
GEP,
827 bool &NeedsExtraction) {
828 NeedsExtraction =
false;
829 unsigned IdxWidth =
DL->getIndexTypeSizeInBits(
GEP->getType());
830 APInt AccumulativeByteOffset(IdxWidth, 0);
832 for (
unsigned I = 1,
E =
GEP->getNumOperands();
I !=
E; ++
I, ++GTI) {
839 APInt ConstantOffset =
840 ConstantOffsetExtractor::Find(
GEP->getOperand(
I),
GEP)
842 if (ConstantOffset != 0) {
843 NeedsExtraction =
true;
847 AccumulativeByteOffset +=
848 ConstantOffset * APInt(IdxWidth,
852 }
else if (LowerGEP) {
857 NeedsExtraction =
true;
858 AccumulativeByteOffset +=
859 APInt(IdxWidth,
DL->getStructLayout(StTy)->getElementOffset(
Field),
864 return AccumulativeByteOffset;
867void SeparateConstOffsetFromGEP::lowerToSingleIndexGEPs(
868 GetElementPtrInst *Variadic,
const APInt &AccumulativeByteOffset) {
875 bool isSwapCandidate =
876 L &&
L->isLoopInvariant(ResultPtr) &&
877 !hasMoreThanOneUseInLoop(ResultPtr, L);
878 Value *FirstResult =
nullptr;
883 for (
unsigned I = 1,
E =
Variadic->getNumOperands();
I !=
E; ++
I, ++GTI) {
894 if (ElementSize != 1) {
896 Idx = Builder.CreateShl(
897 Idx, ConstantInt::get(PtrIndexTy, ElementSize.
logBase2()));
900 Builder.CreateMul(Idx, ConstantInt::get(PtrIndexTy, ElementSize));
904 ResultPtr = Builder.CreatePtrAdd(ResultPtr, Idx,
"uglygep");
905 if (FirstResult ==
nullptr)
906 FirstResult = ResultPtr;
911 if (AccumulativeByteOffset != 0) {
912 Value *
Offset = ConstantInt::get(PtrIndexTy, AccumulativeByteOffset);
913 ResultPtr = Builder.CreatePtrAdd(ResultPtr,
Offset,
"uglygep");
915 isSwapCandidate =
false;
922 if (isSwapCandidate && isLegalToSwapOperand(FirstGEP, SecondGEP, L))
923 swapGEPOperand(FirstGEP, SecondGEP);
925 Variadic->replaceAllUsesWith(ResultPtr);
929bool SeparateConstOffsetFromGEP::reorderGEP(GetElementPtrInst *
GEP,
930 TargetTransformInfo &
TTI) {
935 bool NestedNeedsExtraction;
936 APInt NestedByteOffset = accumulateByteOffset(PtrGEP, NestedNeedsExtraction);
937 if (!NestedNeedsExtraction)
940 unsigned AddrSpace = PtrGEP->getPointerAddressSpace();
947 bool GEPInBounds =
GEP->isInBounds();
948 bool PtrGEPInBounds = PtrGEP->isInBounds();
949 bool IsChainInBounds = GEPInBounds && PtrGEPInBounds;
950 if (IsChainInBounds) {
951 auto IsKnownNonNegative = [
this](
Value *
V) {
954 IsChainInBounds &=
all_of(
GEP->indices(), IsKnownNonNegative);
956 IsChainInBounds &=
all_of(PtrGEP->indices(), IsKnownNonNegative);
961 Value *NewSrc = Builder.CreateGEP(
962 GEP->getSourceElementType(), PtrGEP->getPointerOperand(),
963 SmallVector<Value *, 4>(
GEP->indices()),
"", IsChainInBounds);
964 Value *NewGEP = Builder.CreateGEP(PtrGEP->getSourceElementType(), NewSrc,
965 SmallVector<Value *, 4>(PtrGEP->indices()),
966 "", IsChainInBounds);
967 GEP->replaceAllUsesWith(NewGEP);
972bool SeparateConstOffsetFromGEP::splitGEP(GetElementPtrInst *
GEP) {
974 if (
GEP->getType()->isVectorTy())
981 const APInt *BaseOffset;
982 bool ExtractBase =
match(
GEP->getPointerOperand(),
985 unsigned IdxWidth =
DL->getIndexTypeSizeInBits(
GEP->getType());
986 APInt BaseByteOffset =
987 ExtractBase ? BaseOffset->
sextOrTrunc(IdxWidth) : APInt(IdxWidth, 0);
991 if (
GEP->hasAllConstantIndices() && !ExtractBase)
994 bool Changed = canonicalizeArrayIndicesToIndexSize(
GEP);
996 bool NeedsExtraction;
997 APInt NonBaseByteOffset = accumulateByteOffset(
GEP, NeedsExtraction);
998 APInt AccumulativeByteOffset = BaseByteOffset + NonBaseByteOffset;
1000 TargetTransformInfo &
TTI = GetTTI(*
GEP->getFunction());
1002 if (!NeedsExtraction && !ExtractBase) {
1015 unsigned AddrSpace =
GEP->getPointerAddressSpace();
1017 GEP->getResultElementType(),
1019 true, 0, AddrSpace)) {
1025 ExtractBase =
false;
1026 BaseByteOffset = APInt(IdxWidth, 0);
1027 AccumulativeByteOffset = NonBaseByteOffset;
1029 GEP->getResultElementType(),
1031 true, 0, AddrSpace))
1034 NeedsExtraction =
true;
1039 bool AllOffsetsNonNegative = AccumulativeByteOffset.
isNonNegative();
1040 bool AllNUWPreserved =
GEP->hasNoUnsignedWrap();
1041 bool NewGEPInBounds =
GEP->isInBounds();
1042 bool NewGEPNUSW =
GEP->hasNoUnsignedSignedWrap();
1052 for (
unsigned I = 1,
E =
GEP->getNumOperands();
I !=
E; ++
I, ++GTI) {
1061 User *UserChainTail;
1063 Value *NewIdx = ConstantOffsetExtractor::Extract(Idx,
GEP, UserChainTail,
1065 if (NewIdx !=
nullptr) {
1067 GEP->setOperand(
I, NewIdx);
1073 AllNUWPreserved &= PreservesNUW;
1075 AllOffsetsNonNegative =
1081 AllNUWPreserved &=
Base->hasNoUnsignedWrap();
1082 NewGEPInBounds &=
Base->isInBounds();
1083 NewGEPNUSW &=
Base->hasNoUnsignedSignedWrap();
1086 GEP->setOperand(0, NewBase);
1112 bool CanPreserveInBoundsNUSW = AllOffsetsNonNegative;
1116 if (AllNUWPreserved) {
1124 CanPreserveInBoundsNUSW |= NewGEPNUSW;
1127 if (CanPreserveInBoundsNUSW) {
1130 else if (NewGEPNUSW)
1134 GEP->setNoWrapFlags(NewGEPFlags);
1138 lowerToSingleIndexGEPs(
GEP, AccumulativeByteOffset);
1143 if (AccumulativeByteOffset == 0)
1166 Type *PtrIdxTy =
DL->getIndexType(
GEP->getType());
1169 NewGEP, ConstantInt::get(PtrIdxTy, AccumulativeByteOffset),
1170 GEP->getName(), NewGEPFlags));
1173 GEP->replaceAllUsesWith(NewGEP);
1174 GEP->eraseFromParent();
1179bool SeparateConstOffsetFromGEPLegacyPass::runOnFunction(Function &
F) {
1180 if (skipFunction(
F))
1182 auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
1183 auto *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
1184 auto *TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(
F);
1185 auto GetTTI = [
this](
Function &
F) -> TargetTransformInfo & {
1186 return this->getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
F);
1188 SeparateConstOffsetFromGEP Impl(DT, LI, TLI, GetTTI, LowerGEP);
1192bool SeparateConstOffsetFromGEP::run(Function &
F) {
1196 DL = &
F.getDataLayout();
1199 ReversePostOrderTraversal<Function *> RPOT(&
F);
1200 for (BasicBlock *
B : RPOT) {
1214 verifyNoDeadCode(
F);
1219Instruction *SeparateConstOffsetFromGEP::findClosestMatchingDominator(
1220 ExprKey
Key, Instruction *Dominatee,
1221 DenseMap<ExprKey, SmallVector<Instruction *, 2>> &DominatingExprs) {
1222 auto Pos = DominatingExprs.find(
Key);
1223 if (Pos == DominatingExprs.end())
1226 auto &Candidates = Pos->second;
1231 while (!Candidates.empty()) {
1233 if (DT->
dominates(Candidate, Dominatee))
1235 Candidates.pop_back();
1240bool SeparateConstOffsetFromGEP::reuniteExts(Instruction *
I) {
1241 if (!
I->getType()->isIntOrIntVectorTy())
1251 ExprKey
Key = createNormalizedCommutablePair(
LHS,
RHS);
1252 if (
auto *Dom = findClosestMatchingDominator(
Key,
I, DominatingAdds)) {
1254 new SExtInst(Dom,
I->getType(),
"",
I->getIterator());
1256 I->replaceAllUsesWith(NewSExt);
1265 findClosestMatchingDominator({
LHS,
RHS},
I, DominatingSubs)) {
1267 new SExtInst(Dom,
I->getType(),
"",
I->getIterator());
1269 I->replaceAllUsesWith(NewSExt);
1280 ExprKey
Key = createNormalizedCommutablePair(
LHS,
RHS);
1281 DominatingAdds[
Key].push_back(
I);
1285 DominatingSubs[{
LHS,
RHS}].push_back(
I);
1290bool SeparateConstOffsetFromGEP::reuniteExts(Function &
F) {
1292 DominatingAdds.clear();
1293 DominatingSubs.clear();
1302void SeparateConstOffsetFromGEP::verifyNoDeadCode(Function &
F) {
1303 for (BasicBlock &
B :
F) {
1304 for (Instruction &
I :
B) {
1306 std::string ErrMessage;
1307 raw_string_ostream RSO(ErrMessage);
1308 RSO <<
"Dead instruction detected!\n" <<
I <<
"\n";
1315bool SeparateConstOffsetFromGEP::isLegalToSwapOperand(
1316 GetElementPtrInst *FirstGEP, GetElementPtrInst *SecondGEP, Loop *CurLoop) {
1317 if (!FirstGEP || !FirstGEP->
hasOneUse())
1323 if (FirstGEP == SecondGEP)
1329 if (FirstNum != SecondNum || FirstNum != 2)
1354 if (FirstOffsetDef && FirstOffsetDef->
isShift() &&
1363 if ((opc == Instruction::Add || opc == Instruction::Sub) &&
1371bool SeparateConstOffsetFromGEP::hasMoreThanOneUseInLoop(
Value *V, Loop *L) {
1378 for (User *U :
V->users()) {
1380 if (
L->contains(User))
1381 if (++UsesInLoop > 1)
1387void SeparateConstOffsetFromGEP::swapGEPOperand(GetElementPtrInst *
First,
1388 GetElementPtrInst *Second) {
1391 First->setOperand(1, Offset2);
1395 const DataLayout &DAL =
First->getDataLayout();
1401 uint64_t ObjectSize;
1403 Offset.ugt(ObjectSize)) {
1408 First->setIsInBounds(
true);
1429 SeparateConstOffsetFromGEP Impl(DT, LI, TLI, GetTTI, LowerGEP);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseMap class.
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
static bool runOnFunction(Function &F, bool PostInlining)
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
static const T * Find(StringRef S, ArrayRef< T > A)
Find KV in array using binary search.
OptimizedStructLayoutField Field
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
static cl::opt< bool > DisableSeparateConstOffsetFromGEP("disable-separate-const-offset-from-gep", cl::init(false), cl::desc("Do not separate the constant offset from a GEP instruction"), cl::Hidden)
static bool allowsPreservingNUW(const User *U)
A helper function to check if reassociating through an entry in the user chain would invalidate the G...
static cl::opt< bool > VerifyNoDeadCode("reassociate-geps-verify-no-dead-code", cl::init(false), cl::desc("Verify this pass produces no dead code"), cl::Hidden)
This file defines the SmallVector class.
static SymbolRef::Type getType(const Symbol *Sym)
Class for arbitrary precision integers.
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
LLVM_ABI APInt sextOrTrunc(unsigned width) const
Sign extend or truncate to width.
unsigned logBase2() const
bool isNonNegative() const
Determine if this APInt Value is non-negative (>= 0)
LLVM_ABI APInt sext(unsigned width) const
Sign extend to a new width.
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
int64_t getSExtValue() const
Get sign extended value.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
AnalysisUsage & addRequired()
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
InstListType::iterator iterator
Instruction iterators...
BinaryOps getOpcode() const
static LLVM_ABI BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name=Twine(), InsertPosition InsertBefore=nullptr)
Construct a binary instruction, given the opcode and the two operands.
Represents analyses that only rely on functions' control flow.
static LLVM_ABI CastInst * CreateIntegerCast(Value *S, Type *Ty, bool isSigned, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Create a ZExt, BitCast, or Trunc for int -> int casts.
unsigned getIndexSizeInBits(unsigned AS) const
The size in bits of indices used for address calculation in getelementptr and for addresses in the gi...
Analysis pass which computes a DominatorTree.
Legacy analysis pass which computes a DominatorTree.
LLVM_ABI bool isReachableFromEntry(const Use &U) const
Provide an overload for a Use.
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
FunctionPass class - This class is used to implement most global optimizations.
static GEPNoWrapFlags inBounds()
static GEPNoWrapFlags noUnsignedWrap()
static GEPNoWrapFlags noUnsignedSignedWrap()
static GEPNoWrapFlags none()
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
LLVM_ABI void setNoWrapFlags(GEPNoWrapFlags NW)
Set nowrap flags for GEP instruction.
LLVM_ABI bool hasNoUnsignedWrap() const LLVM_READONLY
Determine whether the no unsigned wrap flag is set.
LLVM_ABI bool hasNoSignedWrap() const LLVM_READONLY
Determine whether the no signed wrap flag is set.
LLVM_ABI void insertBefore(InstListType::iterator InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified position.
LLVM_ABI void dropPoisonGeneratingFlags()
Drops flags that may cause this instruction to evaluate to poison despite having non-poison inputs.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
LLVM_ABI void copyMetadata(const Instruction &SrcInst, ArrayRef< unsigned > WL=ArrayRef< unsigned >())
Copy metadata from SrcInst to this instruction.
Analysis pass that exposes the LoopInfo for a function.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
The legacy pass manager's analysis pass to compute loop information.
bool isLoopInvariant(const Value *V) const
Return true if the specified value is loop invariant.
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
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 & preserveSet()
Mark an analysis set as preserved.
void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
PreservedAnalyses run(Function &F, FunctionAnalysisManager &)
StringRef - Represent a constant reference to a string, i.e.
Analysis pass providing the TargetTransformInfo.
Analysis pass providing the TargetLibraryInfo.
This class represents a truncation of integer types.
LLVM_ABI unsigned getIntegerBitWidth() const
LLVM_ABI bool isScalableTy(SmallPtrSetImpl< const Type * > &Visited) const
Return true if this is a type whose size is a known multiple of vscale.
void setOperand(unsigned i, Value *Val)
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
const Value * stripAndAccumulateInBoundsConstantOffsets(const DataLayout &DL, APInt &Offset) const
This is a wrapper around stripAndAccumulateConstantOffsets with the in-bounds requirement set to fals...
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
An efficient, type-erasing, non-owning reference to a callable.
bool isSequential() const
StructType * getStructType() const
TypeSize getSequentialElementStride(const DataLayout &DL) const
Type * getIndexedType() const
const ParentTy * getParent() const
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
@ BasicBlock
Various leaf nodes.
PtrAdd_match< PointerOpTy, OffsetOpTy > m_PtrAdd(const PointerOpTy &PointerOp, const OffsetOpTy &OffsetOp)
Matches GEP with i8 source element type.
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Sub, OverflowingBinaryOperator::NoSignedWrap > m_NSWSub(const LHS &L, const RHS &R)
bool match(Val *V, const Pattern &P)
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoSignedWrap > m_NSWAdd(const LHS &L, const RHS &R)
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
initializer< Ty > init(const Ty &Val)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
@ User
could "use" a pointer
NodeAddr< NodeBase * > Node
friend class Instruction
Iterator for Instructions in a `BasicBlock.
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.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI bool RecursivelyDeleteTriviallyDeadInstructions(Value *V, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr, std::function< void(Value *)> AboutToDeleteCallback=std::function< void(Value *)>())
If the specified value is a trivially dead instruction, delete it.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
LLVM_ABI void initializeSeparateConstOffsetFromGEPLegacyPassPass(PassRegistry &)
auto dyn_cast_or_null(const Y &Val)
LLVM_ABI bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction is not used, and the instruction will return.
LLVM_ABI bool getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout &DL, const TargetLibraryInfo *TLI, ObjectSizeOpts Opts={})
Compute the size of the object pointed by Ptr.
auto reverse(ContainerTy &&C)
LLVM_ABI bool programUndefinedIfPoison(const Instruction *Inst)
generic_gep_type_iterator<> gep_type_iterator
LLVM_ABI Constant * ConstantFoldCastOperand(unsigned Opcode, Constant *C, Type *DestTy, const DataLayout &DL)
Attempt to constant fold a cast with the specified operand.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI FunctionPass * createSeparateConstOffsetFromGEPPass(bool LowerGEP=false)
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
gep_type_iterator gep_type_begin(const User *GEP)
iterator_range< df_iterator< T > > depth_first(const T &G)
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI bool isKnownNonNegative(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Returns true if the give value is known to be non-negative.
A CRTP mix-in to automatically provide informational APIs needed for passes.