This matches the actual runtime function more closely.
I considered also renaming both RetainRV/UnsafeClaimRV to end with
"ARV", for AutoreleasedReturnValue, but there's less potential
for confusion there.
enum class ARCInstKind {
Retain, ///< objc_retain
RetainRV, ///< objc_retainAutoreleasedReturnValue
- ClaimRV, ///< objc_unsafeClaimAutoreleasedReturnValue
+ UnsafeClaimRV, ///< objc_unsafeClaimAutoreleasedReturnValue
RetainBlock, ///< objc_retainBlock
Release, ///< objc_release
Autorelease, ///< objc_autorelease
return cast<Function>(B->Inputs[0]);
}
-/// Check whether the function is retainRV/claimRV.
+/// Check whether the function is retainRV/unsafeClaimRV.
inline bool isRetainOrClaimRV(ARCInstKind Kind) {
- return Kind == ARCInstKind::RetainRV || Kind == ARCInstKind::ClaimRV;
+ return Kind == ARCInstKind::RetainRV || Kind == ARCInstKind::UnsafeClaimRV;
}
/// This function returns the ARCInstKind of the function attached to operand
/// bundle clang_arc_attachedcall. It returns None if the call doesn't have the
/// operand bundle or the operand is null. Otherwise it returns either RetainRV
-/// or ClaimRV.
+/// or UnsafeClaimRV.
inline ARCInstKind getAttachedARCFunctionKind(const CallBase *CB) {
Optional<Function *> Fn = getAttachedARCFunction(CB);
if (!Fn.hasValue())
return OS << "ARCInstKind::Retain";
case ARCInstKind::RetainRV:
return OS << "ARCInstKind::RetainRV";
- case ARCInstKind::ClaimRV:
- return OS << "ARCInstKind::ClaimRV";
+ case ARCInstKind::UnsafeClaimRV:
+ return OS << "ARCInstKind::UnsafeClaimRV";
case ARCInstKind::RetainBlock:
return OS << "ARCInstKind::RetainBlock";
case ARCInstKind::Release:
case Intrinsic::objc_clang_arc_use:
return ARCInstKind::IntrinsicUser;
case Intrinsic::objc_unsafeClaimAutoreleasedReturnValue:
- return ARCInstKind::ClaimRV;
+ return ARCInstKind::UnsafeClaimRV;
case Intrinsic::objc_retainedObject:
return ARCInstKind::NoopCast;
case Intrinsic::objc_unretainedObject:
case ARCInstKind::StoreStrong:
case ARCInstKind::Call:
case ARCInstKind::None:
- case ARCInstKind::ClaimRV:
+ case ARCInstKind::UnsafeClaimRV:
return false;
}
llvm_unreachable("covered switch isn't covered?");
case ARCInstKind::Call:
case ARCInstKind::User:
case ARCInstKind::None:
- case ARCInstKind::ClaimRV:
+ case ARCInstKind::UnsafeClaimRV:
return false;
}
llvm_unreachable("covered switch isn't covered?");
return true;
case ARCInstKind::Retain:
case ARCInstKind::RetainRV:
- case ARCInstKind::ClaimRV:
+ case ARCInstKind::UnsafeClaimRV:
case ARCInstKind::RetainBlock:
case ARCInstKind::Release:
case ARCInstKind::AutoreleasepoolPush:
switch (Class) {
case ARCInstKind::Retain:
case ARCInstKind::RetainRV:
- case ARCInstKind::ClaimRV:
+ case ARCInstKind::UnsafeClaimRV:
case ARCInstKind::Autorelease:
case ARCInstKind::AutoreleaseRV:
case ARCInstKind::NoopCast:
switch (Class) {
case ARCInstKind::Retain:
case ARCInstKind::RetainRV:
- case ARCInstKind::ClaimRV:
+ case ARCInstKind::UnsafeClaimRV:
case ARCInstKind::Release:
case ARCInstKind::Autorelease:
case ARCInstKind::AutoreleaseRV:
switch (Class) {
case ARCInstKind::Retain:
case ARCInstKind::RetainRV:
- case ARCInstKind::ClaimRV:
+ case ARCInstKind::UnsafeClaimRV:
case ARCInstKind::Release:
case ARCInstKind::Autorelease:
case ARCInstKind::AutoreleaseRV:
switch (Class) {
case ARCInstKind::Retain:
case ARCInstKind::RetainRV:
- case ARCInstKind::ClaimRV:
+ case ARCInstKind::UnsafeClaimRV:
case ARCInstKind::AutoreleaseRV:
return true;
case ARCInstKind::Release:
return true;
case ARCInstKind::Retain:
case ARCInstKind::RetainRV:
- case ARCInstKind::ClaimRV:
+ case ARCInstKind::UnsafeClaimRV:
case ARCInstKind::AutoreleaseRV:
case ARCInstKind::Release:
case ARCInstKind::RetainBlock:
switch (Class) {
case ARCInstKind::Retain:
case ARCInstKind::RetainRV:
- case ARCInstKind::ClaimRV:
+ case ARCInstKind::UnsafeClaimRV:
case ARCInstKind::Release:
case ARCInstKind::Autorelease:
case ARCInstKind::AutoreleaseRV:
return true;
case ARCInstKind::Retain:
case ARCInstKind::RetainRV:
- case ARCInstKind::ClaimRV:
+ case ARCInstKind::UnsafeClaimRV:
case ARCInstKind::Release:
case ARCInstKind::AutoreleasepoolPush:
case ARCInstKind::RetainBlock:
case ARCInstKind::StoreStrong:
case ARCInstKind::CallOrUser:
case ARCInstKind::Call:
- case ARCInstKind::ClaimRV:
+ case ARCInstKind::UnsafeClaimRV:
return true;
}
objcarc::ARCInstKind Kind = objcarc::getAttachedARCFunctionKind(CB);
(void)Kind;
assert((Kind == objcarc::ARCInstKind::RetainRV ||
- Kind == objcarc::ARCInstKind::ClaimRV) &&
+ Kind == objcarc::ARCInstKind::UnsafeClaimRV) &&
"use expected to be the argument of operand bundle "
"\"clang.arc.attachedcall\"");
U.set(FCache.getCallee());
Autorelease,
StoreStrong,
RetainRV,
- ClaimRV,
+ UnsafeClaimRV,
RetainAutorelease,
RetainAutoreleaseRV,
};
Autorelease = nullptr;
StoreStrong = nullptr;
RetainRV = nullptr;
- ClaimRV = nullptr;
+ UnsafeClaimRV = nullptr;
RetainAutorelease = nullptr;
RetainAutoreleaseRV = nullptr;
}
case ARCRuntimeEntryPointKind::RetainRV:
return getIntrinsicEntryPoint(RetainRV,
Intrinsic::objc_retainAutoreleasedReturnValue);
- case ARCRuntimeEntryPointKind::ClaimRV:
+ case ARCRuntimeEntryPointKind::UnsafeClaimRV:
return getIntrinsicEntryPoint(
- ClaimRV, Intrinsic::objc_unsafeClaimAutoreleasedReturnValue);
+ UnsafeClaimRV, Intrinsic::objc_unsafeClaimAutoreleasedReturnValue);
case ARCRuntimeEntryPointKind::RetainAutorelease:
return getIntrinsicEntryPoint(RetainAutorelease,
Intrinsic::objc_retainAutorelease);
Function *RetainRV = nullptr;
/// Declaration for objc_unsafeClaimAutoreleasedReturnValue().
- Function *ClaimRV = nullptr;
+ Function *UnsafeClaimRV = nullptr;
/// Declaration for objc_retainAutorelease().
Function *RetainAutorelease = nullptr;
// If we succeed in our optimization, fall through.
LLVM_FALLTHROUGH;
case ARCInstKind::RetainRV:
- case ARCInstKind::ClaimRV: {
+ case ARCInstKind::UnsafeClaimRV: {
bool IsInstContainedInBundle = BundledInsts->contains(Inst);
// Return now if the target doesn't need a special inline-asm marker. Return
Function &F, DenseMap<BasicBlock *, ColorVector> &BlockColors,
Instruction *Inst, ARCInstKind Class, const Value *Arg);
- /// Try to optimize an AutoreleaseRV with a RetainRV or ClaimRV. If the
+ /// Try to optimize an AutoreleaseRV with a RetainRV or UnsafeClaimRV. If the
/// optimization occurs, returns true to indicate that the caller should
/// assume the instructions are dead.
bool OptimizeInlinedAutoreleaseRVCall(
return true;
}
- // ClaimRV is a frontend peephole for RetainRV + Release. Since the
- // AutoreleaseRV and RetainRV cancel out, replace the ClaimRV with a Release.
- assert(Class == ARCInstKind::ClaimRV);
+ // UnsafeClaimRV is a frontend peephole for RetainRV + Release. Since the
+ // AutoreleaseRV and RetainRV cancel out, replace UnsafeClaimRV with Release.
+ assert(Class == ARCInstKind::UnsafeClaimRV);
Value *CallArg = cast<CallInst>(Inst)->getArgOperand(0);
CallInst *Release = CallInst::Create(
EP.get(ARCRuntimeEntryPointKind::Release), CallArg, "", Inst);
- assert(IsAlwaysTail(ARCInstKind::ClaimRV) &&
- "Expected ClaimRV to be safe to tail call");
+ assert(IsAlwaysTail(ARCInstKind::UnsafeClaimRV) &&
+ "Expected UnsafeClaimRV to be safe to tail call");
Release->setTailCall();
Inst->replaceAllUsesWith(CallArg);
EraseInstruction(Inst);
BlockColors = colorEHFunclets(F);
// Store any delayed AutoreleaseRV intrinsics, so they can be easily paired
- // with RetainRV and ClaimRV.
+ // with RetainRV and UnsafeClaimRV.
Instruction *DelayedAutoreleaseRV = nullptr;
const Value *DelayedAutoreleaseRVArg = nullptr;
auto setDelayedAutoreleaseRV = [&](Instruction *AutoreleaseRV) {
return false;
// Given the frontend rules for emitting AutoreleaseRV, RetainRV, and
- // ClaimRV, it's probably safe to skip over even opaque function calls
+ // UnsafeClaimRV, it's probably safe to skip over even opaque function calls
// here since OptimizeInlinedAutoreleaseRVCall will confirm that they
// have the same RCIdentityRoot. However, what really matters is
// skipping instructions or intrinsics that the inliner could leave behind;
setDelayedAutoreleaseRV(Inst);
continue;
case ARCInstKind::RetainRV:
- case ARCInstKind::ClaimRV:
+ case ARCInstKind::UnsafeClaimRV:
if (DelayedAutoreleaseRV) {
// We have a potential RV pair. Check if they cancel out.
if (OptimizeInlinedAutoreleaseRVCall(F, BlockColors, Inst, Arg, Class,
DepInst = findSingleDependency(AutoreleasePoolBoundary, Arg,
Inst->getParent(), Inst, PA);
break;
- case ARCInstKind::ClaimRV:
+ case ARCInstKind::UnsafeClaimRV:
case ARCInstKind::RetainRV:
case ARCInstKind::AutoreleaseRV:
// Don't move these; the RV optimization depends on the autoreleaseRV
Module *Mod = CB.getModule();
assert(objcarc::isRetainOrClaimRV(RVCallKind) && "unexpected ARC function");
bool IsRetainRV = RVCallKind == objcarc::ARCInstKind::RetainRV,
- IsClaimRV = !IsRetainRV;
+ IsUnsafeClaimRV = !IsRetainRV;
for (auto *RI : Returns) {
Value *RetOpnd = objcarc::GetRCIdentityRoot(RI->getOperand(0));
// and erase the autoreleaseRV call.
// - If retainRV is attached to the call, just erase the autoreleaseRV
// call.
- if (IsClaimRV) {
+ if (IsUnsafeClaimRV) {
Builder.SetInsertPoint(II);
Function *IFn =
Intrinsic::getDeclaration(Mod, Intrinsic::objc_release);