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()) {}
243 APInt findInEitherOperand(BinaryOperator *BO,
bool SignExtended,
261 Value *rebuildWithoutConstOffset();
279 Value *distributeCastsAndCloneChain(
unsigned ChainIndex);
282 Value *removeConstOffset(
unsigned ChainIndex);
297 bool canTraceInto(
bool SignExtended,
bool ZeroExtended, BinaryOperator *BO,
298 GetElementPtrInst *
GEP,
Value *Idx);
315 const DataLayout &DL;
321class SeparateConstOffsetFromGEPLegacyPass :
public FunctionPass {
325 SeparateConstOffsetFromGEPLegacyPass(
bool LowerGEP =
false)
326 : FunctionPass(ID), LowerGEP(LowerGEP) {
331 void getAnalysisUsage(AnalysisUsage &AU)
const override {
348class SeparateConstOffsetFromGEP {
350 SeparateConstOffsetFromGEP(
351 DominatorTree *DT, LoopInfo *LI, TargetLibraryInfo *TLI,
352 function_ref<TargetTransformInfo &(Function &)> GetTTI,
bool LowerGEP)
353 : DT(DT), LI(LI), TLI(TLI), GetTTI(GetTTI), LowerGEP(LowerGEP) {}
355 bool run(Function &
F);
359 using ExprKey = std::pair<Value *, Value *>;
362 static ExprKey createNormalizedCommutablePair(
Value *
A,
Value *
B) {
370 bool splitGEP(GetElementPtrInst *
GEP);
375 bool reorderGEP(GetElementPtrInst *
GEP, TargetTransformInfo &
TTI);
384 void lowerToSingleIndexGEPs(GetElementPtrInst *Variadic,
385 const APInt &AccumulativeByteOffset);
393 APInt accumulateByteOffset(GetElementPtrInst *
GEP,
bool &NeedsExtraction,
394 bool &SignedOverflow);
411 bool canonicalizeArrayIndicesToIndexSize(GetElementPtrInst *
GEP);
422 bool reuniteExts(Function &
F);
425 bool reuniteExts(Instruction *
I);
429 ExprKey
Key, Instruction *Dominatee,
430 DenseMap<ExprKey, SmallVector<Instruction *, 2>> &DominatingExprs);
433 void verifyNoDeadCode(Function &
F);
435 bool hasMoreThanOneUseInLoop(
Value *v, Loop *L);
438 void swapGEPOperand(GetElementPtrInst *
First, GetElementPtrInst *Second);
441 bool isLegalToSwapOperand(GetElementPtrInst *
First, GetElementPtrInst *Second,
444 const DataLayout *DL =
nullptr;
445 DominatorTree *DT =
nullptr;
447 TargetLibraryInfo *TLI;
449 function_ref<TargetTransformInfo &(
Function &)> GetTTI;
455 DenseMap<ExprKey, SmallVector<Instruction *, 2>> DominatingAdds;
456 DenseMap<ExprKey, SmallVector<Instruction *, 2>> DominatingSubs;
461char SeparateConstOffsetFromGEPLegacyPass::ID = 0;
464 SeparateConstOffsetFromGEPLegacyPass,
"separate-const-offset-from-gep",
465 "Split GEPs to a variadic base and a constant offset for better CSE",
false,
473 SeparateConstOffsetFromGEPLegacyPass,
"separate-const-offset-from-gep",
474 "Split GEPs to a variadic base and a constant offset for better CSE",
false,
478 return new SeparateConstOffsetFromGEPLegacyPass(LowerGEP);
517 if (!
GEP->isInBounds())
520 const Value *Ptr =
GEP->getPointerOperand();
534 unsigned N =
Add->getType()->getIntegerBitWidth();
535 TypeSize ElemSize =
DL.getTypeAllocSize(
GEP->getSourceElementType());
575 if (
auto AllocSize = AI->getAllocationSize(
DL))
576 if (!AllocSize->isScalable())
577 ObjSize = AllocSize->getFixedValue();
579 TypeSize GVSize =
DL.getTypeAllocSize(GV->getValueType());
583 if (ObjSize > 0 &&
APInt(128, ObjSize).ult(Threshold))
589bool ConstantOffsetExtractor::canTraceInto(
bool SignExtended,
bool ZeroExtended,
595 if (BO->
getOpcode() != Instruction::Add &&
603 if (BO->
getOpcode() == Instruction::Or &&
610 if (ZeroExtended && !SignExtended && BO->
getOpcode() == Instruction::Sub)
624 if (BO->
getOpcode() == Instruction::Add && !ZeroExtended &&
GEP) {
639 bool GEPInboundsNUW =
641 if (BO->
getOpcode() == Instruction::Add && SignExtended && !ZeroExtended &&
647 if (BO->
getOpcode() == Instruction::Add ||
658APInt ConstantOffsetExtractor::findInEitherOperand(BinaryOperator *BO,
662 size_t ChainLength = UserChain.size();
665 APInt ConstantOffset =
666 find(BO->
getOperand(0),
nullptr,
nullptr, SignExtended, ZeroExtended);
672 if (ConstantOffset != 0)
return ConstantOffset;
676 UserChain.resize(ChainLength);
679 find(BO->
getOperand(1),
nullptr,
nullptr, SignExtended, ZeroExtended);
683 ConstantOffset = -ConstantOffset;
686 if (ConstantOffset == 0)
687 UserChain.resize(ChainLength);
689 return ConstantOffset;
692APInt ConstantOffsetExtractor::find(
Value *V, GetElementPtrInst *
GEP,
693 Value *Idx,
bool SignExtended,
702 if (U ==
nullptr)
return APInt(
BitWidth, 0);
707 ConstantOffset = CI->getValue();
710 if (canTraceInto(SignExtended, ZeroExtended, BO,
GEP, Idx))
711 ConstantOffset = findInEitherOperand(BO, SignExtended, ZeroExtended);
714 find(
U->getOperand(0),
GEP, Idx, SignExtended, ZeroExtended)
718 find(
U->getOperand(0),
GEP, Idx,
true, ZeroExtended)
723 ConstantOffset =
find(
U->getOperand(0),
GEP, Idx,
false,
731 if (ConstantOffset != 0)
732 UserChain.push_back(U);
733 return ConstantOffset;
736Value *ConstantOffsetExtractor::applyCasts(
Value *V) {
763Value *ConstantOffsetExtractor::rebuildWithoutConstOffset() {
764 distributeCastsAndCloneChain(UserChain.size() - 1);
766 unsigned NewSize = 0;
767 for (User *
I : UserChain) {
769 UserChain[NewSize] =
I;
773 UserChain.resize(NewSize);
774 return removeConstOffset(UserChain.size() - 1);
778ConstantOffsetExtractor::distributeCastsAndCloneChain(
unsigned ChainIndex) {
779 User *
U = UserChain[ChainIndex];
780 if (ChainIndex == 0) {
789 "Only following instructions can be traced: sext, zext & trunc");
790 CastInsts.push_back(Cast);
791 UserChain[ChainIndex] =
nullptr;
792 return distributeCastsAndCloneChain(ChainIndex - 1);
798 unsigned OpNo = (BO->
getOperand(0) == UserChain[ChainIndex - 1] ? 0 : 1);
800 Value *NextInChain = distributeCastsAndCloneChain(ChainIndex - 1);
802 BinaryOperator *NewBO =
nullptr;
810 return UserChain[ChainIndex] = NewBO;
813Value *ConstantOffsetExtractor::removeConstOffset(
unsigned ChainIndex) {
814 if (ChainIndex == 0) {
816 return ConstantInt::getNullValue(UserChain[ChainIndex]->
getType());
821 "distributeCastsAndCloneChain clones each BinaryOperator in "
822 "UserChain, so no one should be used more than "
825 unsigned OpNo = (BO->
getOperand(0) == UserChain[ChainIndex - 1] ? 0 : 1);
827 Value *NextInChain = removeConstOffset(ChainIndex - 1);
833 if (CI->isZero() && !(BO->
getOpcode() == Instruction::Sub && OpNo == 0))
837 BinaryOperator::BinaryOps NewOp = BO->
getOpcode();
838 if (BO->
getOpcode() == Instruction::Or) {
852 NewOp = Instruction::Add;
855 BinaryOperator *NewBO;
871 if (Opcode == BinaryOperator::Or) {
884 return TI->hasNoUnsignedWrap();
889Value *ConstantOffsetExtractor::Extract(
Value *Idx, GetElementPtrInst *
GEP,
890 User *&UserChainTail,
891 bool &PreservesNUW) {
892 ConstantOffsetExtractor Extractor(
GEP->getIterator());
894 APInt ConstantOffset = Extractor.find(Idx,
GEP, Idx,
false,
896 if (ConstantOffset == 0) {
897 UserChainTail =
nullptr;
905 Value *IdxWithoutConstOffset = Extractor.rebuildWithoutConstOffset();
906 UserChainTail = Extractor.UserChain.back();
907 return IdxWithoutConstOffset;
910APInt ConstantOffsetExtractor::Find(
Value *Idx, GetElementPtrInst *
GEP) {
911 return ConstantOffsetExtractor(
GEP->getIterator())
912 .find(Idx,
GEP, Idx,
false,
false);
915bool SeparateConstOffsetFromGEP::canonicalizeArrayIndicesToIndexSize(
916 GetElementPtrInst *
GEP) {
918 Type *PtrIdxTy =
DL->getIndexType(
GEP->getType());
921 I !=
E; ++
I, ++GTI) {
924 if ((*I)->getType() != PtrIdxTy) {
934APInt SeparateConstOffsetFromGEP::accumulateByteOffset(GetElementPtrInst *
GEP,
935 bool &NeedsExtraction,
936 bool &SignedOverflow) {
937 NeedsExtraction =
false;
938 SignedOverflow =
false;
939 unsigned IdxWidth =
DL->getIndexTypeSizeInBits(
GEP->getType());
940 APInt AccumulativeByteOffset(IdxWidth, 0);
942 for (
unsigned I = 1,
E =
GEP->getNumOperands();
I !=
E; ++
I, ++GTI) {
949 APInt ConstantOffset =
950 ConstantOffsetExtractor::Find(
GEP->getOperand(
I),
GEP)
952 if (ConstantOffset != 0) {
953 NeedsExtraction =
true;
958 auto ByteOffset = ConstantOffset.
smul_ov(
962 SignedOverflow |= Overflow;
963 AccumulativeByteOffset =
964 AccumulativeByteOffset.sadd_ov(ByteOffset, Overflow);
965 SignedOverflow |= Overflow;
967 }
else if (LowerGEP) {
972 NeedsExtraction =
true;
973 AccumulativeByteOffset +=
974 APInt(IdxWidth,
DL->getStructLayout(StTy)->getElementOffset(
Field),
979 return AccumulativeByteOffset;
982void SeparateConstOffsetFromGEP::lowerToSingleIndexGEPs(
983 GetElementPtrInst *Variadic,
const APInt &AccumulativeByteOffset) {
990 bool isSwapCandidate =
991 L &&
L->isLoopInvariant(ResultPtr) &&
992 !hasMoreThanOneUseInLoop(ResultPtr, L);
993 Value *FirstResult =
nullptr;
998 for (
unsigned I = 1,
E =
Variadic->getNumOperands();
I !=
E; ++
I, ++GTI) {
1009 if (ElementSize != 1) {
1011 Idx = Builder.CreateShl(
1012 Idx, ConstantInt::get(PtrIndexTy, ElementSize.
logBase2()));
1015 Builder.CreateMul(Idx, ConstantInt::get(PtrIndexTy, ElementSize));
1019 ResultPtr = Builder.CreatePtrAdd(ResultPtr, Idx,
"uglygep");
1020 if (FirstResult ==
nullptr)
1021 FirstResult = ResultPtr;
1026 if (AccumulativeByteOffset != 0) {
1027 Value *
Offset = ConstantInt::get(PtrIndexTy, AccumulativeByteOffset);
1028 ResultPtr = Builder.CreatePtrAdd(ResultPtr,
Offset,
"uglygep");
1030 isSwapCandidate =
false;
1037 if (isSwapCandidate && isLegalToSwapOperand(FirstGEP, SecondGEP, L))
1038 swapGEPOperand(FirstGEP, SecondGEP);
1040 Variadic->replaceAllUsesWith(ResultPtr);
1044bool SeparateConstOffsetFromGEP::reorderGEP(GetElementPtrInst *
GEP,
1045 TargetTransformInfo &
TTI) {
1050 bool NestedNeedsExtraction, OffsetOverflow;
1051 APInt NestedByteOffset =
1052 accumulateByteOffset(PtrGEP, NestedNeedsExtraction, OffsetOverflow);
1053 if (!NestedNeedsExtraction)
1056 unsigned AddrSpace = PtrGEP->getPointerAddressSpace();
1060 true, 0, AddrSpace))
1063 bool GEPInBounds =
GEP->isInBounds();
1064 bool PtrGEPInBounds = PtrGEP->isInBounds();
1065 bool IsChainInBounds = GEPInBounds && PtrGEPInBounds;
1066 if (IsChainInBounds) {
1067 auto IsKnownNonNegative = [
this](
Value *
V) {
1070 IsChainInBounds &=
all_of(
GEP->indices(), IsKnownNonNegative);
1071 if (IsChainInBounds)
1072 IsChainInBounds &=
all_of(PtrGEP->indices(), IsKnownNonNegative);
1077 Value *NewSrc = Builder.CreateGEP(
1078 GEP->getSourceElementType(), PtrGEP->getPointerOperand(),
1079 SmallVector<Value *, 4>(
GEP->indices()),
"", IsChainInBounds);
1080 Value *NewGEP = Builder.CreateGEP(PtrGEP->getSourceElementType(), NewSrc,
1081 SmallVector<Value *, 4>(PtrGEP->indices()),
1082 "", IsChainInBounds);
1083 GEP->replaceAllUsesWith(NewGEP);
1088bool SeparateConstOffsetFromGEP::splitGEP(GetElementPtrInst *
GEP) {
1090 if (
GEP->getType()->isVectorTy())
1097 const APInt *BaseOffset;
1098 bool ExtractBase =
match(
GEP->getPointerOperand(),
1101 unsigned IdxWidth =
DL->getIndexTypeSizeInBits(
GEP->getType());
1102 APInt BaseByteOffset =
1103 ExtractBase ? BaseOffset->
sextOrTrunc(IdxWidth) : APInt(IdxWidth, 0);
1107 if (
GEP->hasAllConstantIndices() && !ExtractBase)
1110 bool Changed = canonicalizeArrayIndicesToIndexSize(
GEP);
1112 bool NeedsExtraction, OffsetOverflow;
1113 APInt NonBaseByteOffset =
1114 accumulateByteOffset(
GEP, NeedsExtraction, OffsetOverflow);
1116 APInt AccumulativeByteOffset =
1120 TargetTransformInfo &
TTI = GetTTI(*
GEP->getFunction());
1122 if (!NeedsExtraction && !ExtractBase) {
1135 unsigned AddrSpace =
GEP->getPointerAddressSpace();
1137 GEP->getResultElementType(),
1139 true, 0, AddrSpace)) {
1145 ExtractBase =
false;
1146 BaseByteOffset = APInt(IdxWidth, 0);
1147 AccumulativeByteOffset = NonBaseByteOffset;
1149 GEP->getResultElementType(),
1151 true, 0, AddrSpace))
1154 NeedsExtraction =
true;
1159 bool AllOffsetsNonNegative =
1161 bool AllNUWPreserved =
GEP->hasNoUnsignedWrap();
1162 bool NewGEPInBounds =
GEP->isInBounds();
1163 bool NewGEPNUSW =
GEP->hasNoUnsignedSignedWrap();
1173 for (
unsigned I = 1,
E =
GEP->getNumOperands();
I !=
E; ++
I, ++GTI) {
1182 User *UserChainTail;
1184 Value *NewIdx = ConstantOffsetExtractor::Extract(Idx,
GEP, UserChainTail,
1186 if (NewIdx !=
nullptr) {
1188 GEP->setOperand(
I, NewIdx);
1194 AllNUWPreserved &= PreservesNUW;
1196 AllOffsetsNonNegative =
1202 AllNUWPreserved &=
Base->hasNoUnsignedWrap();
1203 NewGEPInBounds &=
Base->isInBounds();
1204 NewGEPNUSW &=
Base->hasNoUnsignedSignedWrap();
1207 GEP->setOperand(0, NewBase);
1233 bool CanPreserveInBoundsNUSW = AllOffsetsNonNegative;
1237 if (AllNUWPreserved) {
1245 CanPreserveInBoundsNUSW |= NewGEPNUSW;
1248 if (CanPreserveInBoundsNUSW) {
1251 else if (NewGEPNUSW)
1255 GEP->setNoWrapFlags(NewGEPFlags);
1259 lowerToSingleIndexGEPs(
GEP, AccumulativeByteOffset);
1264 if (AccumulativeByteOffset == 0)
1287 Type *PtrIdxTy =
DL->getIndexType(
GEP->getType());
1290 NewGEP, ConstantInt::get(PtrIdxTy, AccumulativeByteOffset),
1291 GEP->getName(), NewGEPFlags));
1294 GEP->replaceAllUsesWith(NewGEP);
1295 GEP->eraseFromParent();
1300bool SeparateConstOffsetFromGEPLegacyPass::runOnFunction(Function &
F) {
1301 if (skipFunction(
F))
1303 auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
1304 auto *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
1305 auto *TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(
F);
1306 auto GetTTI = [
this](
Function &
F) -> TargetTransformInfo & {
1307 return this->getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
F);
1309 SeparateConstOffsetFromGEP Impl(DT, LI, TLI, GetTTI, LowerGEP);
1313bool SeparateConstOffsetFromGEP::run(Function &
F) {
1317 DL = &
F.getDataLayout();
1320 ReversePostOrderTraversal<Function *> RPOT(&
F);
1321 for (BasicBlock *
B : RPOT) {
1335 verifyNoDeadCode(
F);
1340Instruction *SeparateConstOffsetFromGEP::findClosestMatchingDominator(
1341 ExprKey
Key, Instruction *Dominatee,
1342 DenseMap<ExprKey, SmallVector<Instruction *, 2>> &DominatingExprs) {
1343 auto Pos = DominatingExprs.find(
Key);
1344 if (Pos == DominatingExprs.end())
1347 auto &Candidates = Pos->second;
1352 while (!Candidates.empty()) {
1354 if (DT->
dominates(Candidate, Dominatee))
1356 Candidates.pop_back();
1361bool SeparateConstOffsetFromGEP::reuniteExts(Instruction *
I) {
1362 if (!
I->getType()->isIntOrIntVectorTy())
1372 ExprKey
Key = createNormalizedCommutablePair(
LHS,
RHS);
1373 if (
auto *Dom = findClosestMatchingDominator(
Key,
I, DominatingAdds)) {
1375 new SExtInst(Dom,
I->getType(),
"",
I->getIterator());
1377 I->replaceAllUsesWith(NewSExt);
1386 findClosestMatchingDominator({
LHS,
RHS},
I, DominatingSubs)) {
1388 new SExtInst(Dom,
I->getType(),
"",
I->getIterator());
1390 I->replaceAllUsesWith(NewSExt);
1401 ExprKey
Key = createNormalizedCommutablePair(
LHS,
RHS);
1402 DominatingAdds[
Key].push_back(
I);
1406 DominatingSubs[{
LHS,
RHS}].push_back(
I);
1411bool SeparateConstOffsetFromGEP::reuniteExts(Function &
F) {
1413 DominatingAdds.clear();
1414 DominatingSubs.clear();
1423void SeparateConstOffsetFromGEP::verifyNoDeadCode(Function &
F) {
1424 for (BasicBlock &
B :
F) {
1425 for (Instruction &
I :
B) {
1427 std::string ErrMessage;
1428 raw_string_ostream RSO(ErrMessage);
1429 RSO <<
"Dead instruction detected!\n" <<
I <<
"\n";
1436bool SeparateConstOffsetFromGEP::isLegalToSwapOperand(
1437 GetElementPtrInst *FirstGEP, GetElementPtrInst *SecondGEP, Loop *CurLoop) {
1438 if (!FirstGEP || !FirstGEP->
hasOneUse())
1444 if (FirstGEP == SecondGEP)
1450 if (FirstNum != SecondNum || FirstNum != 2)
1475 if (FirstOffsetDef && FirstOffsetDef->
isShift() &&
1484 if ((opc == Instruction::Add || opc == Instruction::Sub) &&
1492bool SeparateConstOffsetFromGEP::hasMoreThanOneUseInLoop(
Value *V, Loop *L) {
1499 for (User *U :
V->users()) {
1501 if (
L->contains(User))
1502 if (++UsesInLoop > 1)
1508void SeparateConstOffsetFromGEP::swapGEPOperand(GetElementPtrInst *
First,
1509 GetElementPtrInst *Second) {
1512 First->setOperand(1, Offset2);
1516 const DataLayout &DAL =
First->getDataLayout();
1522 uint64_t ObjectSize;
1524 Offset.ugt(ObjectSize)) {
1529 First->setIsInBounds(
true);
1550 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
Function Alias Analysis false
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)
static bool canReorderAddSextToGEP(const GetElementPtrInst *GEP, const Value *Idx, const BinaryOperator *Add, const DataLayout &DL)
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 zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
LLVM_ABI APInt sadd_ov(const APInt &RHS, bool &Overflow) const
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
LLVM_ABI APInt sextOrTrunc(unsigned width) const
Sign extend or truncate to width.
unsigned logBase2() const
LLVM_ABI APInt smul_ov(const APInt &RHS, bool &Overflow) 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.
This is the shared class of boolean and integer constants.
const APInt & getValue() const
Return the constant as an APInt value reference.
A parsed version of the target data layout string in and methods for querying it.
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.
constexpr ScalarTy getFixedValue() const
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
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)
auto 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.
Value * GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset, const DataLayout &DL, bool AllowNonInbounds=true)
Analyze the specified pointer to see if it can be expressed as a base pointer plus a constant offset.
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)
std::enable_if_t< std::is_signed_v< T >, T > AddOverflow(T X, T Y, T &Result)
Add two signed integers, computing the two's complement truncated result, returning true if overflow ...
iterator_range< df_iterator< T > > depth_first(const T &G)
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
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.