40 auto CI = dyn_cast<CallInst>(U.getUser());
41 if (!CI || CI->getCalledOperand() != &
F)
46 B.CreateGEP(Int8Ty, CI->getArgOperand(0), CI->getArgOperand(1));
47 Value *OffsetPtrI32 =
B.CreateBitCast(OffsetPtr, Int32PtrTy);
50 Value *ResultPtr =
B.CreateGEP(Int8Ty, CI->getArgOperand(0), OffsetI32);
52 CI->replaceAllUsesWith(ResultPtr);
53 CI->eraseFromParent();
74 "Pre-ISel intrinsics do lower into regular function calls");
81 FunctionCallee FCache = M->getOrInsertFunction(NewFn,
F.getFunctionType());
84 Fn->setLinkage(
F.getLinkage());
88 Fn->addFnAttr(Attribute::NonLazyBind);
95 auto *CB = cast<CallBase>(U.getUser());
97 if (CB->getCalledFunction() != &
F) {
100 assert((Kind == objcarc::ARCInstKind::RetainRV ||
101 Kind == objcarc::ARCInstKind::UnsafeClaimRV) &&
102 "use expected to be the argument of operand bundle "
103 "\"clang.arc.attachedcall\"");
108 auto *CI = cast<CallInst>(CB);
109 assert(CI->getCalledFunction() &&
"Cannot lower an indirect call!");
114 CI->getOperandBundlesAsDefs(BundleList);
128 if (!CI->use_empty())
129 CI->replaceAllUsesWith(NewCI);
130 CI->eraseFromParent();
137 bool Changed =
false;
139 if (
F.getName().startswith(
"llvm.load.relative.")) {
143 switch (
F.getIntrinsicID()) {
146 case Intrinsic::objc_autorelease:
149 case Intrinsic::objc_autoreleasePoolPop:
152 case Intrinsic::objc_autoreleasePoolPush:
155 case Intrinsic::objc_autoreleaseReturnValue:
158 case Intrinsic::objc_copyWeak:
161 case Intrinsic::objc_destroyWeak:
164 case Intrinsic::objc_initWeak:
167 case Intrinsic::objc_loadWeak:
170 case Intrinsic::objc_loadWeakRetained:
173 case Intrinsic::objc_moveWeak:
176 case Intrinsic::objc_release:
179 case Intrinsic::objc_retain:
182 case Intrinsic::objc_retainAutorelease:
185 case Intrinsic::objc_retainAutoreleaseReturnValue:
188 case Intrinsic::objc_retainAutoreleasedReturnValue:
189 Changed |=
lowerObjCCall(
F,
"objc_retainAutoreleasedReturnValue");
191 case Intrinsic::objc_retainBlock:
194 case Intrinsic::objc_storeStrong:
197 case Intrinsic::objc_storeWeak:
200 case Intrinsic::objc_unsafeClaimAutoreleasedReturnValue:
201 Changed |=
lowerObjCCall(
F,
"objc_unsafeClaimAutoreleasedReturnValue");
203 case Intrinsic::objc_retainedObject:
206 case Intrinsic::objc_unretainedObject:
209 case Intrinsic::objc_unretainedPointer:
212 case Intrinsic::objc_retain_autorelease:
215 case Intrinsic::objc_sync_enter:
218 case Intrinsic::objc_sync_exit:
228class PreISelIntrinsicLoweringLegacyPass :
public ModulePass {
232 PreISelIntrinsicLoweringLegacyPass() :
ModulePass(
ID) {}
239char PreISelIntrinsicLoweringLegacyPass::ID;
242 "pre-isel-intrinsic-lowering",
"Pre-ISel Intrinsic Lowering",
246 return new PreISelIntrinsicLoweringLegacyPass;
static bool setNonLazyBind(Function &F)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Module.h This file contains the declarations for the Module class.
This file defines ARC utility functions which are used by various parts of the compiler.
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
static bool lowerIntrinsics(Module &M)
static bool lowerObjCCall(Function &F, const char *NewFn, bool setNonLazyBind=false)
static CallInst::TailCallKind getOverridingTailCallKind(const Function &F)
static bool lowerLoadRelative(Function &F)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A container for analyses that lazily runs them and caches their results.
This class represents a function call, abstracting a target machine's calling convention.
void setTailCallKind(TailCallKind TCK)
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
static bool mayLowerToFunctionCall(Intrinsic::ID IID)
Check if the intrinsic might lower into a regular function call in the course of IR transformations.
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
virtual bool runOnModule(Module &M)=0
runOnModule - Virtual method overriden by subclasses to process the module being operated on.
A Module instance is used to store all the information related to an LLVM module.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
The instances of the Type class are immutable: once they are created, they are never changed.
PointerType * getPointerTo(unsigned AddrSpace=0) const
Return a pointer to the current type.
static IntegerType * getInt8Ty(LLVMContext &C)
static IntegerType * getInt32Ty(LLVMContext &C)
A Use represents the edge between a Value definition and its users.
LLVM Value Representation.
void setName(const Twine &Name)
Change the name of the value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
ARCInstKind getAttachedARCFunctionKind(const CallBase *CB)
This function returns the ARCInstKind of the function attached to operand bundle clang_arc_attachedca...
bool IsNeverTail(ARCInstKind Class)
Test if the given class represents instructions which are never safe to mark with the "tail" keyword.
bool IsAlwaysTail(ARCInstKind Class)
Test if the given class represents instructions which are always safe to mark with the "tail" keyword...
ARCInstKind
Equivalence classes of instructions in the ARC Model.
ARCInstKind GetFunctionClass(const Function *F)
Determine if F is one of the special known Functions.
This is an optimization pass for GlobalISel generic memory operations.
ModulePass * createPreISelIntrinsicLoweringPass()
This pass lowers the @llvm.load.relative and @llvm.objc.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
This struct is a compact representation of a valid (non-zero power of two) alignment.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)