return Changed;
}
-static bool lowerObjCCall(Function &F, const char *NewFn) {
+static bool lowerObjCCall(Function &F, const char *NewFn,
+ bool setNonLazyBind = false) {
if (F.use_empty())
return false;
// program already contains a function with this name.
Module *M = F.getParent();
Constant* FCache = M->getOrInsertFunction(NewFn, F.getFunctionType());
+
+ // If we have Native ARC, set nonlazybind attribute for these APIs for
+ // performance.
+ if (setNonLazyBind)
+ if (Function* Fn = dyn_cast<Function>(FCache))
+ Fn->addFnAttr(Attribute::NonLazyBind);
for (auto I = F.use_begin(), E = F.use_end(); I != E;) {
auto *CI = dyn_cast<CallInst>(I->getUser());
Changed |= lowerObjCCall(F, "objc_moveWeak");
break;
case Intrinsic::objc_release:
- Changed |= lowerObjCCall(F, "objc_release");
+ Changed |= lowerObjCCall(F, "objc_release", true);
break;
case Intrinsic::objc_retain:
- Changed |= lowerObjCCall(F, "objc_retain");
+ Changed |= lowerObjCCall(F, "objc_retain", true);
break;
case Intrinsic::objc_retainAutorelease:
Changed |= lowerObjCCall(F, "objc_retainAutorelease");
declare i8* @llvm.objc.retain.autorelease(i8*)
declare i32 @llvm.objc.sync.enter(i8*)
declare i32 @llvm.objc.sync.exit(i8*)
+
+; CHECK: declare void @objc_release(i8*) [[NLB:#[0-9]+]]
+; CHECK: declare i8* @objc_retain(i8*) [[NLB]]
+
+; CHECK: attributes [[NLB]] = { nonlazybind }