28 for (
const Use &U : FPtr->
uses()) {
40 if (isa<BitCastInst>(
User)) {
43 }
else if (
auto *CI = dyn_cast<CallInst>(
User)) {
45 }
else if (
auto *
II = dyn_cast<InvokeInst>(
User)) {
47 }
else if (HasNonCallUses) {
48 *HasNonCallUses =
true;
57 for (
const Use &U : VPtr->
uses()) {
59 if (isa<BitCastInst>(
User)) {
61 }
else if (isa<LoadInst>(
User)) {
63 }
else if (
auto GEP = dyn_cast<GetElementPtrInst>(
User)) {
65 if (VPtr ==
GEP->getPointerOperand() &&
GEP->hasAllConstantIndices()) {
67 int64_t GEPOffset = M->getDataLayout().getIndexedOffsetInType(
68 GEP->getSourceElementType(), Indices);
72 }
else if (
auto *Call = dyn_cast<CallInst>(
User)) {
73 if (Call->getIntrinsicID() == llvm::Intrinsic::load_relative) {
74 if (
auto *LoadOffset = dyn_cast<ConstantInt>(Call->getOperand(1))) {
76 Offset + LoadOffset->getSExtValue(), CI,
90 Intrinsic::public_type_test);
95 for (
const Use &CIU : CI->
uses())
96 if (
auto *Assume = dyn_cast<AssumeInst>(CIU.getUser()))
101 if (!Assumes.
empty())
112 Intrinsic::type_checked_load ||
114 Intrinsic::type_checked_load_relative);
118 HasNonCallUses =
true;
122 for (
const Use &U : CI->
uses()) {
123 auto CIU = U.getUser();
124 if (
auto EVI = dyn_cast<ExtractValueInst>(CIU)) {
125 if (EVI->getNumIndices() == 1 && EVI->getIndices()[0] == 0) {
129 if (EVI->getNumIndices() == 1 && EVI->getIndices()[0] == 1) {
134 HasNonCallUses =
true;
137 for (
Value *LoadedPtr : LoadedPtrs)
139 Offset->getZExtValue(), CI, DT);
147 if (
auto *Equiv = dyn_cast<DSOLocalEquivalent>(
I))
148 I = Equiv->getGlobalValue();
150 if (
I->getType()->isPointerTy()) {
158 if (
auto *
C = dyn_cast<ConstantStruct>(
I)) {
168 if (
auto *
C = dyn_cast<ConstantArray>(
I)) {
173 if (
Op >=
C->getNumOperands())
177 Offset % ElemSize, M, TopLevelGlobal);
181 if (
auto *CI = dyn_cast<ConstantInt>(
I)) {
182 if (
Offset == 0 && CI->isZero()) {
186 if (
auto *
C = dyn_cast<ConstantExpr>(
I)) {
187 switch (
C->getOpcode()) {
188 case Instruction::Trunc:
189 case Instruction::PtrToInt:
192 case Instruction::Sub: {
193 auto *Operand0 = cast<Constant>(
C->getOperand(0));
194 auto *Operand1 = cast<Constant>(
C->getOperand(1));
197 auto *CE = dyn_cast<ConstantExpr>(
C);
200 if (CE->getOpcode() != Instruction::GetElementPtr)
202 return CE->getOperand(0);
208 if (Operand1TargetGlobal != TopLevelGlobal)
220std::pair<Function *, Constant *>
225 return std::pair<Function *, Constant *>(
nullptr,
nullptr);
227 auto C =
Ptr->stripPointerCasts();
229 auto Fn = dyn_cast<Function>(
C);
230 auto A = dyn_cast<GlobalAlias>(
C);
232 Fn = dyn_cast<Function>(
A->getAliasee());
235 return std::pair<Function *, Constant *>(
nullptr,
nullptr);
237 return std::pair<Function *, Constant *>(Fn,
C);
241 auto *PtrExpr = dyn_cast<ConstantExpr>(U);
242 if (!PtrExpr || PtrExpr->getOpcode() != Instruction::PtrToInt)
245 for (
auto *PtrToIntUser : PtrExpr->users()) {
246 auto *SubExpr = dyn_cast<ConstantExpr>(PtrToIntUser);
247 if (!SubExpr || SubExpr->getOpcode() != Instruction::Sub)
250 SubExpr->replaceNonMetadataUsesWith(
251 ConstantInt::get(SubExpr->getType(), 0));
256 for (
auto *U :
C->users()) {
257 if (
auto *Equiv = dyn_cast<DSOLocalEquivalent>(U))
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
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.
uint64_t IntrinsicInst * II
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Class to represent array types.
Type * getElementType() const
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.
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...
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
const Function * getFunction() const
Return the function this instruction belongs to.
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()
const ParentTy * getParent() const
@ 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 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 replaceRelativePointerUsersWithZero(Constant *C)
Finds the same "relative pointer" pattern as described above, where the target is C,...
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...
std::pair< Function *, Constant * > getFunctionAtVTableOffset(GlobalVariable *GV, uint64_t Offset, Module &M)
Given a vtable and a specified offset, returns the function and the trivial pointer at the specified ...