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);
114 HasNonCallUses =
true;
118 for (
const Use &U : CI->
uses()) {
119 auto CIU = U.getUser();
120 if (
auto EVI = dyn_cast<ExtractValueInst>(CIU)) {
121 if (EVI->getNumIndices() == 1 && EVI->getIndices()[0] == 0) {
125 if (EVI->getNumIndices() == 1 && EVI->getIndices()[0] == 1) {
130 HasNonCallUses =
true;
133 for (
Value *LoadedPtr : LoadedPtrs)
135 Offset->getZExtValue(), CI, DT);
143 if (
auto *Equiv = dyn_cast<DSOLocalEquivalent>(
I))
144 I = Equiv->getGlobalValue();
146 if (
I->getType()->isPointerTy()) {
154 if (
auto *
C = dyn_cast<ConstantStruct>(
I)) {
164 if (
auto *
C = dyn_cast<ConstantArray>(
I)) {
168 unsigned Op =
Offset / ElemSize;
169 if (Op >=
C->getNumOperands())
173 Offset % ElemSize, M, TopLevelGlobal);
177 if (
auto *CI = dyn_cast<ConstantInt>(
I)) {
178 if (
Offset == 0 && CI->getZExtValue() == 0) {
182 if (
auto *
C = dyn_cast<ConstantExpr>(
I)) {
183 switch (
C->getOpcode()) {
184 case Instruction::Trunc:
185 case Instruction::PtrToInt:
188 case Instruction::Sub: {
189 auto *Operand0 = cast<Constant>(
C->getOperand(0));
190 auto *Operand1 = cast<Constant>(
C->getOperand(1));
193 auto *CE = dyn_cast<ConstantExpr>(
C);
196 if (CE->getOpcode() != Instruction::GetElementPtr)
198 return CE->getOperand(0);
204 if (Operand1TargetGlobal != TopLevelGlobal)
217 auto *PtrExpr = dyn_cast<ConstantExpr>(U);
218 if (!PtrExpr || PtrExpr->getOpcode() != Instruction::PtrToInt)
221 for (
auto *PtrToIntUser : PtrExpr->users()) {
222 auto *SubExpr = dyn_cast<ConstantExpr>(PtrToIntUser);
223 if (!SubExpr || SubExpr->getOpcode() != Instruction::Sub)
226 SubExpr->replaceNonMetadataUsesWith(
232 for (
auto *U :
C->users()) {
233 if (
auto *Equiv = dyn_cast<DSOLocalEquivalent>(U))
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.
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...
uint64_t getSizeInBytes() const
uint64_t getElementOffset(unsigned Idx) const
unsigned getElementContainingOffset(uint64_t Offset) const
Given a valid byte offset into the structure, returns the structure index that contains it.
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 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...