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);
392 APInt accumulateByteOffset(GetElementPtrInst *
GEP,
bool &NeedsExtraction);
409 bool canonicalizeArrayIndicesToIndexSize(GetElementPtrInst *
GEP);
420 bool reuniteExts(Function &
F);
423 bool reuniteExts(Instruction *
I);
427 ExprKey
Key, Instruction *Dominatee,
428 DenseMap<ExprKey, SmallVector<Instruction *, 2>> &DominatingExprs);
431 void verifyNoDeadCode(Function &
F);
433 bool hasMoreThanOneUseInLoop(
Value *v, Loop *L);
436 void swapGEPOperand(GetElementPtrInst *
First, GetElementPtrInst *Second);
439 bool isLegalToSwapOperand(GetElementPtrInst *
First, GetElementPtrInst *Second,
442 const DataLayout *DL =
nullptr;
443 DominatorTree *DT =
nullptr;
445 TargetLibraryInfo *TLI;
447 function_ref<TargetTransformInfo &(
Function &)> GetTTI;
453 DenseMap<ExprKey, SmallVector<Instruction *, 2>> DominatingAdds;
454 DenseMap<ExprKey, SmallVector<Instruction *, 2>> DominatingSubs;
459char SeparateConstOffsetFromGEPLegacyPass::ID = 0;
462 SeparateConstOffsetFromGEPLegacyPass,
"separate-const-offset-from-gep",
463 "Split GEPs to a variadic base and a constant offset for better CSE",
false,
471 SeparateConstOffsetFromGEPLegacyPass,
"separate-const-offset-from-gep",
472 "Split GEPs to a variadic base and a constant offset for better CSE",
false,
476 return new SeparateConstOffsetFromGEPLegacyPass(LowerGEP);
515 if (!
GEP->isInBounds())
518 const Value *Ptr =
GEP->getPointerOperand();
532 unsigned N =
Add->getType()->getIntegerBitWidth();
533 TypeSize ElemSize =
DL.getTypeAllocSize(
GEP->getSourceElementType());
573 if (
auto AllocSize = AI->getAllocationSize(
DL))
574 if (!AllocSize->isScalable())
575 ObjSize = AllocSize->getFixedValue();
577 TypeSize GVSize =
DL.getTypeAllocSize(GV->getValueType());
581 if (ObjSize > 0 &&
APInt(128, ObjSize).ult(Threshold))
587bool ConstantOffsetExtractor::canTraceInto(
bool SignExtended,
bool ZeroExtended,
593 if (BO->
getOpcode() != Instruction::Add &&
601 if (BO->
getOpcode() == Instruction::Or &&
608 if (ZeroExtended && !SignExtended && BO->
getOpcode() == Instruction::Sub)
622 if (BO->
getOpcode() == Instruction::Add && !ZeroExtended &&
GEP) {
637 bool GEPInboundsNUW =
639 if (BO->
getOpcode() == Instruction::Add && SignExtended && !ZeroExtended &&
645 if (BO->
getOpcode() == Instruction::Add ||
656APInt ConstantOffsetExtractor::findInEitherOperand(BinaryOperator *BO,
660 size_t ChainLength = UserChain.size();
663 APInt ConstantOffset =
664 find(BO->
getOperand(0),
nullptr,
nullptr, SignExtended, ZeroExtended);
670 if (ConstantOffset != 0)
return ConstantOffset;
674 UserChain.resize(ChainLength);
677 find(BO->
getOperand(1),
nullptr,
nullptr, SignExtended, ZeroExtended);
681 ConstantOffset = -ConstantOffset;
684 if (ConstantOffset == 0)
685 UserChain.resize(ChainLength);
687 return ConstantOffset;
690APInt ConstantOffsetExtractor::find(
Value *V, GetElementPtrInst *
GEP,
691 Value *Idx,
bool SignExtended,
700 if (U ==
nullptr)
return APInt(
BitWidth, 0);
705 ConstantOffset = CI->getValue();
708 if (canTraceInto(SignExtended, ZeroExtended, BO,
GEP, Idx))
709 ConstantOffset = findInEitherOperand(BO, SignExtended, ZeroExtended);
712 find(
U->getOperand(0),
GEP, Idx, SignExtended, ZeroExtended)
716 find(
U->getOperand(0),
GEP, Idx,
true, ZeroExtended)
721 ConstantOffset =
find(
U->getOperand(0),
GEP, Idx,
false,
729 if (ConstantOffset != 0)
730 UserChain.push_back(U);
731 return ConstantOffset;
734Value *ConstantOffsetExtractor::applyCasts(
Value *V) {
761Value *ConstantOffsetExtractor::rebuildWithoutConstOffset() {
762 distributeCastsAndCloneChain(UserChain.size() - 1);
764 unsigned NewSize = 0;
765 for (User *
I : UserChain) {
767 UserChain[NewSize] =
I;
771 UserChain.resize(NewSize);
772 return removeConstOffset(UserChain.size() - 1);
776ConstantOffsetExtractor::distributeCastsAndCloneChain(
unsigned ChainIndex) {
777 User *
U = UserChain[ChainIndex];
778 if (ChainIndex == 0) {
787 "Only following instructions can be traced: sext, zext & trunc");
788 CastInsts.push_back(Cast);
789 UserChain[ChainIndex] =
nullptr;
790 return distributeCastsAndCloneChain(ChainIndex - 1);
796 unsigned OpNo = (BO->
getOperand(0) == UserChain[ChainIndex - 1] ? 0 : 1);
798 Value *NextInChain = distributeCastsAndCloneChain(ChainIndex - 1);
800 BinaryOperator *NewBO =
nullptr;
808 return UserChain[ChainIndex] = NewBO;
811Value *ConstantOffsetExtractor::removeConstOffset(
unsigned ChainIndex) {
812 if (ChainIndex == 0) {
814 return ConstantInt::getNullValue(UserChain[ChainIndex]->
getType());
819 "distributeCastsAndCloneChain clones each BinaryOperator in "
820 "UserChain, so no one should be used more than "
823 unsigned OpNo = (BO->
getOperand(0) == UserChain[ChainIndex - 1] ? 0 : 1);
825 Value *NextInChain = removeConstOffset(ChainIndex - 1);
831 if (CI->isZero() && !(BO->
getOpcode() == Instruction::Sub && OpNo == 0))
835 BinaryOperator::BinaryOps NewOp = BO->
getOpcode();
836 if (BO->
getOpcode() == Instruction::Or) {
850 NewOp = Instruction::Add;
853 BinaryOperator *NewBO;
869 if (Opcode == BinaryOperator::Or) {
882 return TI->hasNoUnsignedWrap();
887Value *ConstantOffsetExtractor::Extract(
Value *Idx, GetElementPtrInst *
GEP,
888 User *&UserChainTail,
889 bool &PreservesNUW) {
890 ConstantOffsetExtractor Extractor(
GEP->getIterator());
892 APInt ConstantOffset = Extractor.find(Idx,
GEP, Idx,
false,
894 if (ConstantOffset == 0) {
895 UserChainTail =
nullptr;
903 Value *IdxWithoutConstOffset = Extractor.rebuildWithoutConstOffset();
904 UserChainTail = Extractor.UserChain.back();
905 return IdxWithoutConstOffset;
908APInt ConstantOffsetExtractor::Find(
Value *Idx, GetElementPtrInst *
GEP) {
909 return ConstantOffsetExtractor(
GEP->getIterator())
910 .find(Idx,
GEP, Idx,
false,
false);
913bool SeparateConstOffsetFromGEP::canonicalizeArrayIndicesToIndexSize(
914 GetElementPtrInst *
GEP) {
916 Type *PtrIdxTy =
DL->getIndexType(
GEP->getType());
919 I !=
E; ++
I, ++GTI) {
922 if ((*I)->getType() != PtrIdxTy) {
932APInt SeparateConstOffsetFromGEP::accumulateByteOffset(GetElementPtrInst *
GEP,
933 bool &NeedsExtraction) {
934 NeedsExtraction =
false;
935 unsigned IdxWidth =
DL->getIndexTypeSizeInBits(
GEP->getType());
936 APInt AccumulativeByteOffset(IdxWidth, 0);
938 for (
unsigned I = 1,
E =
GEP->getNumOperands();
I !=
E; ++
I, ++GTI) {
945 APInt ConstantOffset =
946 ConstantOffsetExtractor::Find(
GEP->getOperand(
I),
GEP)
948 if (ConstantOffset != 0) {
949 NeedsExtraction =
true;
953 AccumulativeByteOffset +=
954 ConstantOffset * APInt(IdxWidth,
958 }
else if (LowerGEP) {
963 NeedsExtraction =
true;
964 AccumulativeByteOffset +=
965 APInt(IdxWidth,
DL->getStructLayout(StTy)->getElementOffset(
Field),
970 return AccumulativeByteOffset;
973void SeparateConstOffsetFromGEP::lowerToSingleIndexGEPs(
974 GetElementPtrInst *Variadic,
const APInt &AccumulativeByteOffset) {
981 bool isSwapCandidate =
982 L &&
L->isLoopInvariant(ResultPtr) &&
983 !hasMoreThanOneUseInLoop(ResultPtr, L);
984 Value *FirstResult =
nullptr;
989 for (
unsigned I = 1,
E =
Variadic->getNumOperands();
I !=
E; ++
I, ++GTI) {
1000 if (ElementSize != 1) {
1002 Idx = Builder.CreateShl(
1003 Idx, ConstantInt::get(PtrIndexTy, ElementSize.
logBase2()));
1006 Builder.CreateMul(Idx, ConstantInt::get(PtrIndexTy, ElementSize));
1010 ResultPtr = Builder.CreatePtrAdd(ResultPtr, Idx,
"uglygep");
1011 if (FirstResult ==
nullptr)
1012 FirstResult = ResultPtr;
1017 if (AccumulativeByteOffset != 0) {
1018 Value *
Offset = ConstantInt::get(PtrIndexTy, AccumulativeByteOffset);
1019 ResultPtr = Builder.CreatePtrAdd(ResultPtr,
Offset,
"uglygep");
1021 isSwapCandidate =
false;
1028 if (isSwapCandidate && isLegalToSwapOperand(FirstGEP, SecondGEP, L))
1029 swapGEPOperand(FirstGEP, SecondGEP);
1031 Variadic->replaceAllUsesWith(ResultPtr);
1035bool SeparateConstOffsetFromGEP::reorderGEP(GetElementPtrInst *
GEP,
1036 TargetTransformInfo &
TTI) {
1041 bool NestedNeedsExtraction;
1042 APInt NestedByteOffset = accumulateByteOffset(PtrGEP, NestedNeedsExtraction);
1043 if (!NestedNeedsExtraction)
1046 unsigned AddrSpace = PtrGEP->getPointerAddressSpace();
1050 true, 0, AddrSpace))
1053 bool GEPInBounds =
GEP->isInBounds();
1054 bool PtrGEPInBounds = PtrGEP->isInBounds();
1055 bool IsChainInBounds = GEPInBounds && PtrGEPInBounds;
1056 if (IsChainInBounds) {
1057 auto IsKnownNonNegative = [
this](
Value *
V) {
1060 IsChainInBounds &=
all_of(
GEP->indices(), IsKnownNonNegative);
1061 if (IsChainInBounds)
1062 IsChainInBounds &=
all_of(PtrGEP->indices(), IsKnownNonNegative);
1067 Value *NewSrc = Builder.CreateGEP(
1068 GEP->getSourceElementType(), PtrGEP->getPointerOperand(),
1069 SmallVector<Value *, 4>(
GEP->indices()),
"", IsChainInBounds);
1070 Value *NewGEP = Builder.CreateGEP(PtrGEP->getSourceElementType(), NewSrc,
1071 SmallVector<Value *, 4>(PtrGEP->indices()),
1072 "", IsChainInBounds);
1073 GEP->replaceAllUsesWith(NewGEP);
1078bool SeparateConstOffsetFromGEP::splitGEP(GetElementPtrInst *
GEP) {
1080 if (
GEP->getType()->isVectorTy())
1087 const APInt *BaseOffset;
1088 bool ExtractBase =
match(
GEP->getPointerOperand(),
1091 unsigned IdxWidth =
DL->getIndexTypeSizeInBits(
GEP->getType());
1092 APInt BaseByteOffset =
1093 ExtractBase ? BaseOffset->
sextOrTrunc(IdxWidth) : APInt(IdxWidth, 0);
1097 if (
GEP->hasAllConstantIndices() && !ExtractBase)
1100 bool Changed = canonicalizeArrayIndicesToIndexSize(
GEP);
1102 bool NeedsExtraction;
1103 APInt NonBaseByteOffset = accumulateByteOffset(
GEP, NeedsExtraction);
1104 APInt AccumulativeByteOffset = BaseByteOffset + NonBaseByteOffset;
1106 TargetTransformInfo &
TTI = GetTTI(*
GEP->getFunction());
1108 if (!NeedsExtraction && !ExtractBase) {
1121 unsigned AddrSpace =
GEP->getPointerAddressSpace();
1123 GEP->getResultElementType(),
1125 true, 0, AddrSpace)) {
1131 ExtractBase =
false;
1132 BaseByteOffset = APInt(IdxWidth, 0);
1133 AccumulativeByteOffset = NonBaseByteOffset;
1135 GEP->getResultElementType(),
1137 true, 0, AddrSpace))
1140 NeedsExtraction =
true;
1145 bool AllOffsetsNonNegative = AccumulativeByteOffset.
isNonNegative();
1146 bool AllNUWPreserved =
GEP->hasNoUnsignedWrap();
1147 bool NewGEPInBounds =
GEP->isInBounds();
1148 bool NewGEPNUSW =
GEP->hasNoUnsignedSignedWrap();
1158 for (
unsigned I = 1,
E =
GEP->getNumOperands();
I !=
E; ++
I, ++GTI) {
1167 User *UserChainTail;
1169 Value *NewIdx = ConstantOffsetExtractor::Extract(Idx,
GEP, UserChainTail,
1171 if (NewIdx !=
nullptr) {
1173 GEP->setOperand(
I, NewIdx);
1179 AllNUWPreserved &= PreservesNUW;
1181 AllOffsetsNonNegative =
1187 AllNUWPreserved &=
Base->hasNoUnsignedWrap();
1188 NewGEPInBounds &=
Base->isInBounds();
1189 NewGEPNUSW &=
Base->hasNoUnsignedSignedWrap();
1192 GEP->setOperand(0, NewBase);
1218 bool CanPreserveInBoundsNUSW = AllOffsetsNonNegative;
1222 if (AllNUWPreserved) {
1230 CanPreserveInBoundsNUSW |= NewGEPNUSW;
1233 if (CanPreserveInBoundsNUSW) {
1236 else if (NewGEPNUSW)
1240 GEP->setNoWrapFlags(NewGEPFlags);
1244 lowerToSingleIndexGEPs(
GEP, AccumulativeByteOffset);
1249 if (AccumulativeByteOffset == 0)
1272 Type *PtrIdxTy =
DL->getIndexType(
GEP->getType());
1275 NewGEP, ConstantInt::get(PtrIdxTy, AccumulativeByteOffset),
1276 GEP->getName(), NewGEPFlags));
1279 GEP->replaceAllUsesWith(NewGEP);
1280 GEP->eraseFromParent();
1285bool SeparateConstOffsetFromGEPLegacyPass::runOnFunction(Function &
F) {
1286 if (skipFunction(
F))
1288 auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
1289 auto *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
1290 auto *TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(
F);
1291 auto GetTTI = [
this](
Function &
F) -> TargetTransformInfo & {
1292 return this->getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
F);
1294 SeparateConstOffsetFromGEP Impl(DT, LI, TLI, GetTTI, LowerGEP);
1298bool SeparateConstOffsetFromGEP::run(Function &
F) {
1302 DL = &
F.getDataLayout();
1305 ReversePostOrderTraversal<Function *> RPOT(&
F);
1306 for (BasicBlock *
B : RPOT) {
1320 verifyNoDeadCode(
F);
1325Instruction *SeparateConstOffsetFromGEP::findClosestMatchingDominator(
1326 ExprKey
Key, Instruction *Dominatee,
1327 DenseMap<ExprKey, SmallVector<Instruction *, 2>> &DominatingExprs) {
1328 auto Pos = DominatingExprs.find(
Key);
1329 if (Pos == DominatingExprs.end())
1332 auto &Candidates = Pos->second;
1337 while (!Candidates.empty()) {
1339 if (DT->
dominates(Candidate, Dominatee))
1341 Candidates.pop_back();
1346bool SeparateConstOffsetFromGEP::reuniteExts(Instruction *
I) {
1347 if (!
I->getType()->isIntOrIntVectorTy())
1357 ExprKey
Key = createNormalizedCommutablePair(
LHS,
RHS);
1358 if (
auto *Dom = findClosestMatchingDominator(
Key,
I, DominatingAdds)) {
1360 new SExtInst(Dom,
I->getType(),
"",
I->getIterator());
1362 I->replaceAllUsesWith(NewSExt);
1371 findClosestMatchingDominator({
LHS,
RHS},
I, DominatingSubs)) {
1373 new SExtInst(Dom,
I->getType(),
"",
I->getIterator());
1375 I->replaceAllUsesWith(NewSExt);
1386 ExprKey
Key = createNormalizedCommutablePair(
LHS,
RHS);
1387 DominatingAdds[
Key].push_back(
I);
1391 DominatingSubs[{
LHS,
RHS}].push_back(
I);
1396bool SeparateConstOffsetFromGEP::reuniteExts(Function &
F) {
1398 DominatingAdds.clear();
1399 DominatingSubs.clear();
1408void SeparateConstOffsetFromGEP::verifyNoDeadCode(Function &
F) {
1409 for (BasicBlock &
B :
F) {
1410 for (Instruction &
I :
B) {
1412 std::string ErrMessage;
1413 raw_string_ostream RSO(ErrMessage);
1414 RSO <<
"Dead instruction detected!\n" <<
I <<
"\n";
1421bool SeparateConstOffsetFromGEP::isLegalToSwapOperand(
1422 GetElementPtrInst *FirstGEP, GetElementPtrInst *SecondGEP, Loop *CurLoop) {
1423 if (!FirstGEP || !FirstGEP->
hasOneUse())
1429 if (FirstGEP == SecondGEP)
1435 if (FirstNum != SecondNum || FirstNum != 2)
1460 if (FirstOffsetDef && FirstOffsetDef->
isShift() &&
1469 if ((opc == Instruction::Add || opc == Instruction::Sub) &&
1477bool SeparateConstOffsetFromGEP::hasMoreThanOneUseInLoop(
Value *V, Loop *L) {
1484 for (User *U :
V->users()) {
1486 if (
L->contains(User))
1487 if (++UsesInLoop > 1)
1493void SeparateConstOffsetFromGEP::swapGEPOperand(GetElementPtrInst *
First,
1494 GetElementPtrInst *Second) {
1497 First->setOperand(1, Offset2);
1501 const DataLayout &DAL =
First->getDataLayout();
1507 uint64_t ObjectSize;
1509 Offset.ugt(ObjectSize)) {
1514 First->setIsInBounds(
true);
1535 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.
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
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)
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.
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)
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.