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;
60 for (
const Use &U : VPtr->
uses()) {
62 if (isa<BitCastInst>(
User)) {
64 }
else if (isa<LoadInst>(
User)) {
66 }
else if (
auto GEP = dyn_cast<GetElementPtrInst>(
User)) {
68 if (VPtr ==
GEP->getPointerOperand() &&
GEP->hasAllConstantIndices()) {
70 int64_t GEPOffset = M->getDataLayout().getIndexedOffsetInType(
71 GEP->getSourceElementType(), Indices);
75 }
else if (
auto *Call = dyn_cast<CallInst>(
User)) {
76 if (Call->getIntrinsicID() == llvm::Intrinsic::load_relative) {
77 if (
auto *LoadOffset = dyn_cast<ConstantInt>(Call->getOperand(1))) {
79 Offset + LoadOffset->getSExtValue(), CI,
93 Intrinsic::public_type_test);
98 for (
const Use &CIU : CI->
uses())
99 if (
auto *Assume = dyn_cast<AssumeInst>(CIU.getUser()))
104 if (!Assumes.
empty())
115 Intrinsic::type_checked_load ||
117 Intrinsic::type_checked_load_relative);
121 HasNonCallUses =
true;
125 for (
const Use &U : CI->
uses()) {
126 auto CIU = U.getUser();
127 if (
auto EVI = dyn_cast<ExtractValueInst>(CIU)) {
128 if (EVI->getNumIndices() == 1 && EVI->getIndices()[0] == 0) {
132 if (EVI->getNumIndices() == 1 && EVI->getIndices()[0] == 1) {
137 HasNonCallUses =
true;
140 for (
Value *LoadedPtr : LoadedPtrs)
142 Offset->getZExtValue(), CI, DT);
150 if (
auto *Equiv = dyn_cast<DSOLocalEquivalent>(
I))
151 I = Equiv->getGlobalValue();
153 if (
I->getType()->isPointerTy()) {
161 if (
auto *
C = dyn_cast<ConstantStruct>(
I)) {
171 if (
auto *
C = dyn_cast<ConstantArray>(
I)) {
176 if (
Op >=
C->getNumOperands())
180 Offset % ElemSize, M, TopLevelGlobal);
184 if (
auto *CI = dyn_cast<ConstantInt>(
I)) {
185 if (
Offset == 0 && CI->isZero()) {
189 if (
auto *
C = dyn_cast<ConstantExpr>(
I)) {
190 switch (
C->getOpcode()) {
191 case Instruction::Trunc:
192 case Instruction::PtrToInt:
195 case Instruction::Sub: {
196 auto *Operand0 = cast<Constant>(
C->getOperand(0));
197 auto *Operand1 = cast<Constant>(
C->getOperand(1));
200 auto *CE = dyn_cast<ConstantExpr>(
C);
203 if (CE->getOpcode() != Instruction::GetElementPtr)
205 return CE->getOperand(0);
211 if (Operand1TargetGlobal != TopLevelGlobal)
223std::pair<Function *, Constant *>
228 return std::pair<Function *, Constant *>(
nullptr,
nullptr);
230 auto C =
Ptr->stripPointerCasts();
232 auto Fn = dyn_cast<Function>(
C);
233 auto A = dyn_cast<GlobalAlias>(
C);
235 Fn = dyn_cast<Function>(
A->getAliasee());
238 return std::pair<Function *, Constant *>(
nullptr,
nullptr);
240 return std::pair<Function *, Constant *>(Fn,
C);
244 auto *PtrExpr = dyn_cast<ConstantExpr>(U);
245 if (!PtrExpr || PtrExpr->getOpcode() != Instruction::PtrToInt)
248 for (
auto *PtrToIntUser : PtrExpr->users()) {
249 auto *SubExpr = dyn_cast<ConstantExpr>(PtrToIntUser);
250 if (!SubExpr || SubExpr->getOpcode() != Instruction::Sub)
253 SubExpr->replaceNonMetadataUsesWith(
254 ConstantInt::get(SubExpr->getType(), 0));
259 for (
auto *U :
C->users()) {
260 if (
auto *Equiv = dyn_cast<DSOLocalEquivalent>(U))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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
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.
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.
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.
LLVM_ABI 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
LLVM_ABI 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.
bool hasUseList() const
Check if this Value has a use-list.
LLVM_ABI 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 ...