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);
106 HasNonCallUses =
true;
110 for (
const Use &U : CI->
uses()) {
111 auto CIU = U.getUser();
112 if (
auto EVI = dyn_cast<ExtractValueInst>(CIU)) {
113 if (EVI->getNumIndices() == 1 && EVI->getIndices()[0] == 0) {
117 if (EVI->getNumIndices() == 1 && EVI->getIndices()[0] == 1) {
122 HasNonCallUses =
true;
125 for (
Value *LoadedPtr : LoadedPtrs)
127 Offset->getZExtValue(), CI, DT);
132 if (
I->getType()->isPointerTy()) {
140 if (
auto *
C = dyn_cast<ConstantStruct>(
I)) {
150 if (
auto *
C = dyn_cast<ConstantArray>(
I)) {
154 unsigned Op =
Offset / ElemSize;
155 if (Op >=
C->getNumOperands())
159 Offset % ElemSize, M, TopLevelGlobal);
163 if (
auto *CI = dyn_cast<ConstantInt>(
I)) {
164 if (
Offset == 0 && CI->isZero()) {
168 if (
auto *
C = dyn_cast<ConstantExpr>(
I)) {
169 switch (
C->getOpcode()) {
170 case Instruction::Trunc:
171 case Instruction::PtrToInt:
174 case Instruction::Sub: {
175 auto *Operand0 = cast<Constant>(
C->getOperand(0));
176 auto *Operand1 = cast<Constant>(
C->getOperand(1));
179 auto *CE = dyn_cast<ConstantExpr>(
C);
182 if (CE->getOpcode() != Instruction::GetElementPtr)
184 return CE->getOperand(0);
190 if (Operand1TargetGlobal != TopLevelGlobal)
203 for (
auto *U :
F->users()) {
204 auto *PtrExpr = dyn_cast<ConstantExpr>(U);
205 if (!PtrExpr || PtrExpr->getOpcode() != Instruction::PtrToInt)
208 for (
auto *PtrToIntUser : PtrExpr->users()) {
209 auto *SubExpr = dyn_cast<ConstantExpr>(PtrToIntUser);
210 if (!SubExpr || SubExpr->getOpcode() != Instruction::Sub)
213 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.
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...