39 for (
auto I =
F.use_begin(),
E =
F.use_end();
I !=
E;) {
40 auto CI = dyn_cast<CallInst>(
I->getUser());
42 if (!CI || CI->getCalledOperand() != &
F)
47 B.CreateGEP(Int8Ty, CI->getArgOperand(0), CI->getArgOperand(1));
48 Value *OffsetPtrI32 =
B.CreateBitCast(OffsetPtr, Int32PtrTy);
51 Value *ResultPtr =
B.CreateGEP(Int8Ty, CI->getArgOperand(0), OffsetI32);
53 CI->replaceAllUsesWith(ResultPtr);
54 CI->eraseFromParent();
80 FunctionCallee FCache = M->getOrInsertFunction(NewFn,
F.getFunctionType());
83 Fn->setLinkage(
F.getLinkage());
87 Fn->addFnAttr(Attribute::NonLazyBind);
93 for (
auto I =
F.use_begin(),
E =
F.use_end();
I !=
E;) {
94 auto *CI = cast<CallInst>(
I->getUser());
95 assert(CI->getCalledFunction() &&
"Cannot lower an indirect call!");
101 NewCI->setName(CI->getName());
111 NewCI->setTailCallKind(
std::max(TCK, OverridingTCK));
113 if (!CI->use_empty())
114 CI->replaceAllUsesWith(NewCI);
115 CI->eraseFromParent();
122 bool Changed =
false;
124 if (
F.getName().startswith(
"llvm.load.relative.")) {
128 switch (
F.getIntrinsicID()) {
131 case Intrinsic::objc_autorelease:
134 case Intrinsic::objc_autoreleasePoolPop:
137 case Intrinsic::objc_autoreleasePoolPush:
140 case Intrinsic::objc_autoreleaseReturnValue:
143 case Intrinsic::objc_copyWeak:
146 case Intrinsic::objc_destroyWeak:
149 case Intrinsic::objc_initWeak:
152 case Intrinsic::objc_loadWeak:
155 case Intrinsic::objc_loadWeakRetained:
158 case Intrinsic::objc_moveWeak:
161 case Intrinsic::objc_release:
164 case Intrinsic::objc_retain:
167 case Intrinsic::objc_retainAutorelease:
170 case Intrinsic::objc_retainAutoreleaseReturnValue:
173 case Intrinsic::objc_retainAutoreleasedReturnValue:
174 Changed |=
lowerObjCCall(
F,
"objc_retainAutoreleasedReturnValue");
176 case Intrinsic::objc_retainBlock:
179 case Intrinsic::objc_storeStrong:
182 case Intrinsic::objc_storeWeak:
185 case Intrinsic::objc_unsafeClaimAutoreleasedReturnValue:
186 Changed |=
lowerObjCCall(
F,
"objc_unsafeClaimAutoreleasedReturnValue");
188 case Intrinsic::objc_retainedObject:
191 case Intrinsic::objc_unretainedObject:
194 case Intrinsic::objc_unretainedPointer:
197 case Intrinsic::objc_retain_autorelease:
200 case Intrinsic::objc_sync_enter:
203 case Intrinsic::objc_sync_exit:
213 class PreISelIntrinsicLoweringLegacyPass :
public ModulePass {
217 PreISelIntrinsicLoweringLegacyPass() :
ModulePass(
ID) {}
227 "pre-isel-intrinsic-lowering",
"Pre-ISel Intrinsic Lowering",
231 return new PreISelIntrinsicLoweringLegacyPass;
This class represents lattice values for constants.
A Module instance is used to store all the information related to an LLVM module.
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
This class represents a function call, abstracting a target machine's calling convention.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
static bool setNonLazyBind(Function &F)
PointerType * getPointerTo(unsigned AddrSpace=0) const
Return a pointer to the current type.
static bool lowerLoadRelative(Function &F)
bool IsAlwaysTail(ARCInstKind Class)
Test if the given class represents instructions which are always safe to mark with the "tail" keyword...
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
A set of analyses that are preserved following a run of a transformation pass.
The instances of the Type class are immutable: once they are created, they are never changed.
INITIALIZE_PASS(PreISelIntrinsicLoweringLegacyPass, "pre-isel-intrinsic-lowering", "Pre-ISel Intrinsic Lowering", false, false) ModulePass *llvm
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static bool lowerObjCCall(Function &F, const char *NewFn, bool setNonLazyBind=false)
ARCInstKind GetFunctionClass(const Function *F)
Determine if F is one of the special known Functions.
static CallInst::TailCallKind getOverridingTailCallKind(const Function &F)
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Align max(MaybeAlign Lhs, Align Rhs)
ARCInstKind
Equivalence classes of instructions in the ARC Model.
Module.h This file contains the declarations for the Module class.
static IntegerType * getInt32Ty(LLVMContext &C)
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
ModulePass * createPreISelIntrinsicLoweringPass()
This pass lowers the @llvm.load.relative and @llvm.objc.
A container for analyses that lazily runs them and caches their results.
static bool lowerIntrinsics(Module &M)
static IntegerType * getInt8Ty(LLVMContext &C)
bool IsNeverTail(ARCInstKind Class)
Test if the given class represents instructions which are never safe to mark with the "tail" keyword.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.