28 for (
const Use &U : FPtr->
uses()) {
38 if (isa<BitCastInst>(
User)) {
41 }
else if (
auto *CI = dyn_cast<CallInst>(
User)) {
43 }
else if (
auto *II = dyn_cast<InvokeInst>(
User)) {
45 }
else if (HasNonCallUses) {
46 *HasNonCallUses =
true;
55 for (
const Use &U : VPtr->
uses()) {
57 if (isa<BitCastInst>(
User)) {
59 }
else if (isa<LoadInst>(
User)) {
61 }
else if (
auto GEP = dyn_cast<GetElementPtrInst>(
User)) {
63 if (VPtr ==
GEP->getPointerOperand() &&
GEP->hasAllConstantIndices()) {
65 int64_t GEPOffset = M->getDataLayout().getIndexedOffsetInType(
66 GEP->getSourceElementType(), Indices);
80 Intrinsic::public_type_test);
85 for (
const Use &CIU : CI->
uses())
86 if (
auto *Assume = dyn_cast<AssumeInst>(CIU.getUser()))
102 Intrinsic::type_checked_load ||
104 Intrinsic::type_checked_load_relative);
108 HasNonCallUses =
true;
112 for (
const Use &U : CI->
uses()) {
113 auto CIU = U.getUser();
114 if (
auto EVI = dyn_cast<ExtractValueInst>(CIU)) {
115 if (EVI->getNumIndices() == 1 && EVI->getIndices()[0] == 0) {
119 if (EVI->getNumIndices() == 1 && EVI->getIndices()[0] == 1) {
124 HasNonCallUses =
true;
127 for (
Value *LoadedPtr : LoadedPtrs)
129 Offset->getZExtValue(), CI, DT);
134 if (
I->getType()->isPointerTy()) {
142 if (
auto *
C = dyn_cast<ConstantStruct>(
I)) {
152 if (
auto *
C = dyn_cast<ConstantArray>(
I)) {
157 if (
Op >=
C->getNumOperands())
161 Offset % ElemSize, M, TopLevelGlobal);
165 if (
auto *CI = dyn_cast<ConstantInt>(
I)) {
166 if (
Offset == 0 && CI->isZero()) {
170 if (
auto *
C = dyn_cast<ConstantExpr>(
I)) {
171 switch (
C->getOpcode()) {
172 case Instruction::Trunc:
173 case Instruction::PtrToInt:
176 case Instruction::Sub: {
177 auto *Operand0 = cast<Constant>(
C->getOperand(0));
178 auto *Operand1 = cast<Constant>(
C->getOperand(1));
181 auto *CE = dyn_cast<ConstantExpr>(
C);
184 if (CE->getOpcode() != Instruction::GetElementPtr)
186 return CE->getOperand(0);
192 if (Operand1TargetGlobal != TopLevelGlobal)
205 for (
auto *U :
F->users()) {
206 auto *PtrExpr = dyn_cast<ConstantExpr>(U);
207 if (!PtrExpr || PtrExpr->getOpcode() != Instruction::PtrToInt)
210 for (
auto *PtrToIntUser : PtrExpr->users()) {
211 auto *SubExpr = dyn_cast<ConstantExpr>(PtrToIntUser);
212 if (!SubExpr || SubExpr->getOpcode() != Instruction::Sub)
215 SubExpr->replaceNonMetadataUsesWith(
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Module.h This file contains the declarations for the Module class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Class to represent array types.
Type * getElementType() const
const Function * getParent() const
Return the enclosing method, or null if none.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
Value * getArgOperand(unsigned i) const
This class represents a function call, abstracting a target machine's calling convention.
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
This is an important base class in LLVM.
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
Intrinsic::ID getIntrinsicID() const LLVM_READONLY
getIntrinsicID - This method returns the ID number of the specified function, or Intrinsic::not_intri...
Module * getParent()
Get the module that this global value is contained inside of...
const BasicBlock * getParent() const
A Module instance is used to store all the information related to an LLVM module.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Used to lazily calculate structure layout information for a target machine, based on the DataLayout s...
TypeSize getSizeInBytes() const
unsigned getElementContainingOffset(uint64_t FixedOffset) const
Given a valid byte offset into the structure, returns the structure index that contains it.
TypeSize getElementOffset(unsigned Idx) const
A Use represents the edge between a Value definition and its users.
LLVM Value Representation.
const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
iterator_range< use_iterator > uses()
@ C
The default llvm calling convention, compatible with C.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
void replaceRelativePointerUsersWithZero(Function *F)
Finds the same "relative pointer" pattern as described above, where the target is F,...
void findDevirtualizableCallsForTypeCheckedLoad(SmallVectorImpl< DevirtCallSite > &DevirtCalls, SmallVectorImpl< Instruction * > &LoadedPtrs, SmallVectorImpl< Instruction * > &Preds, bool &HasNonCallUses, const CallInst *CI, DominatorTree &DT)
Given a call to the intrinsic @llvm.type.checked.load, find all devirtualizable call sites based on t...
void findDevirtualizableCallsForTypeTest(SmallVectorImpl< DevirtCallSite > &DevirtCalls, SmallVectorImpl< CallInst * > &Assumes, const CallInst *CI, DominatorTree &DT)
Given a call to the intrinsic @llvm.type.test, find all devirtualizable call sites based on the call ...
Constant * getPointerAtOffset(Constant *I, uint64_t Offset, Module &M, Constant *TopLevelGlobal=nullptr)
Processes a Constant recursively looking into elements of arrays, structs and expressions to find a t...