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);
70 }
else if (
auto *Call = dyn_cast<CallInst>(
User)) {
71 if (Call->getIntrinsicID() == llvm::Intrinsic::load_relative) {
72 if (
auto *LoadOffset = dyn_cast<ConstantInt>(Call->getOperand(1))) {
74 Offset + LoadOffset->getSExtValue(), CI,
88 Intrinsic::public_type_test);
93 for (
const Use &CIU : CI->
uses())
94 if (
auto *Assume = dyn_cast<AssumeInst>(CIU.getUser()))
110 Intrinsic::type_checked_load ||
112 Intrinsic::type_checked_load_relative);
116 HasNonCallUses =
true;
120 for (
const Use &U : CI->
uses()) {
121 auto CIU = U.getUser();
122 if (
auto EVI = dyn_cast<ExtractValueInst>(CIU)) {
123 if (EVI->getNumIndices() == 1 && EVI->getIndices()[0] == 0) {
127 if (EVI->getNumIndices() == 1 && EVI->getIndices()[0] == 1) {
132 HasNonCallUses =
true;
135 for (
Value *LoadedPtr : LoadedPtrs)
137 Offset->getZExtValue(), CI, DT);
145 if (
auto *Equiv = dyn_cast<DSOLocalEquivalent>(
I))
146 I = Equiv->getGlobalValue();
148 if (
I->getType()->isPointerTy()) {
156 if (
auto *
C = dyn_cast<ConstantStruct>(
I)) {
166 if (
auto *
C = dyn_cast<ConstantArray>(
I)) {
171 if (
Op >=
C->getNumOperands())
175 Offset % ElemSize, M, TopLevelGlobal);
179 if (
auto *CI = dyn_cast<ConstantInt>(
I)) {
180 if (
Offset == 0 && CI->isZero()) {
184 if (
auto *
C = dyn_cast<ConstantExpr>(
I)) {
185 switch (
C->getOpcode()) {
186 case Instruction::Trunc:
187 case Instruction::PtrToInt:
190 case Instruction::Sub: {
191 auto *Operand0 = cast<Constant>(
C->getOperand(0));
192 auto *Operand1 = cast<Constant>(
C->getOperand(1));
195 auto *CE = dyn_cast<ConstantExpr>(
C);
198 if (CE->getOpcode() != Instruction::GetElementPtr)
200 return CE->getOperand(0);
206 if (Operand1TargetGlobal != TopLevelGlobal)
218std::pair<Function *, Constant *>
223 return std::pair<Function *, Constant *>(
nullptr,
nullptr);
225 auto C =
Ptr->stripPointerCasts();
227 auto Fn = dyn_cast<Function>(
C);
228 auto A = dyn_cast<GlobalAlias>(
C);
230 Fn = dyn_cast<Function>(
A->getAliasee());
233 return std::pair<Function *, Constant *>(
nullptr,
nullptr);
235 return std::pair<Function *, Constant *>(Fn,
C);
239 auto *PtrExpr = dyn_cast<ConstantExpr>(U);
240 if (!PtrExpr || PtrExpr->getOpcode() != Instruction::PtrToInt)
243 for (
auto *PtrToIntUser : PtrExpr->users()) {
244 auto *SubExpr = dyn_cast<ConstantExpr>(PtrToIntUser);
245 if (!SubExpr || SubExpr->getOpcode() != Instruction::Sub)
248 SubExpr->replaceNonMetadataUsesWith(
249 ConstantInt::get(SubExpr->getType(), 0));
254 for (
auto *U :
C->users()) {
255 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.
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 ...