aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Transforms/ObjCARC/ObjCARCOpts.cpp')
-rw-r--r--lib/Transforms/ObjCARC/ObjCARCOpts.cpp240
1 files changed, 120 insertions, 120 deletions
diff --git a/lib/Transforms/ObjCARC/ObjCARCOpts.cpp b/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
index 95c6674..f55b77f 100644
--- a/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
+++ b/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
@@ -144,7 +144,7 @@ namespace {
/// \defgroup ARCUtilities Utility declarations/definitions specific to ARC.
/// @{
-/// \brief This is similar to StripPointerCastsAndObjCCalls but it stops as soon
+/// \brief This is similar to GetRCIdentityRoot but it stops as soon
/// as it finds a value with multiple uses.
static const Value *FindSingleUseIdentifiedObject(const Value *Arg) {
if (Arg->hasOneUse()) {
@@ -153,7 +153,7 @@ static const Value *FindSingleUseIdentifiedObject(const Value *Arg) {
if (const GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Arg))
if (GEP->hasAllZeroIndices())
return FindSingleUseIdentifiedObject(GEP->getPointerOperand());
- if (IsForwarding(GetBasicInstructionClass(Arg)))
+ if (IsForwarding(GetBasicARCInstKind(Arg)))
return FindSingleUseIdentifiedObject(
cast<CallInst>(Arg)->getArgOperand(0));
if (!IsObjCIdentifiedObject(Arg))
@@ -165,7 +165,7 @@ static const Value *FindSingleUseIdentifiedObject(const Value *Arg) {
// trivial uses, we can still consider this to be a single-use value.
if (IsObjCIdentifiedObject(Arg)) {
for (const User *U : Arg->users())
- if (!U->use_empty() || StripPointerCastsAndObjCCalls(U) != Arg)
+ if (!U->use_empty() || GetRCIdentityRoot(U) != Arg)
return nullptr;
return Arg;
@@ -880,11 +880,9 @@ static void AppendMDNodeToInstForPtr(unsigned NodeId,
Sequence OldSeq,
Sequence NewSeq) {
MDNode *Node = nullptr;
- Value *tmp[3] = {PtrSourceMDNodeID,
- SequenceToMDString(Inst->getContext(),
- OldSeq),
- SequenceToMDString(Inst->getContext(),
- NewSeq)};
+ Metadata *tmp[3] = {PtrSourceMDNodeID,
+ SequenceToMDString(Inst->getContext(), OldSeq),
+ SequenceToMDString(Inst->getContext(), NewSeq)};
Node = MDNode::get(Inst->getContext(), tmp);
Inst->setMetadata(NodeId, Node);
@@ -1098,7 +1096,7 @@ namespace {
bool OptimizeRetainRVCall(Function &F, Instruction *RetainRV);
void OptimizeAutoreleaseRVCall(Function &F, Instruction *AutoreleaseRV,
- InstructionClass &Class);
+ ARCInstKind &Class);
void OptimizeIndividualCalls(Function &F);
void CheckForCFGHazards(const BasicBlock *BB,
@@ -1193,7 +1191,7 @@ void ObjCARCOpt::getAnalysisUsage(AnalysisUsage &AU) const {
bool
ObjCARCOpt::OptimizeRetainRVCall(Function &F, Instruction *RetainRV) {
// Check for the argument being from an immediately preceding call or invoke.
- const Value *Arg = GetObjCArg(RetainRV);
+ const Value *Arg = GetArgRCIdentityRoot(RetainRV);
ImmutableCallSite CS(Arg);
if (const Instruction *Call = CS.getInstruction()) {
if (Call->getParent() == RetainRV->getParent()) {
@@ -1218,8 +1216,8 @@ ObjCARCOpt::OptimizeRetainRVCall(Function &F, Instruction *RetainRV) {
BasicBlock::iterator I = RetainRV, Begin = RetainRV->getParent()->begin();
if (I != Begin) {
do --I; while (I != Begin && IsNoopInstruction(I));
- if (GetBasicInstructionClass(I) == IC_AutoreleaseRV &&
- GetObjCArg(I) == Arg) {
+ if (GetBasicARCInstKind(I) == ARCInstKind::AutoreleaseRV &&
+ GetArgRCIdentityRoot(I) == Arg) {
Changed = true;
++NumPeeps;
@@ -1250,17 +1248,17 @@ ObjCARCOpt::OptimizeRetainRVCall(Function &F, Instruction *RetainRV) {
/// Turn objc_autoreleaseReturnValue into objc_autorelease if the result is not
/// used as a return value.
-void
-ObjCARCOpt::OptimizeAutoreleaseRVCall(Function &F, Instruction *AutoreleaseRV,
- InstructionClass &Class) {
+void ObjCARCOpt::OptimizeAutoreleaseRVCall(Function &F,
+ Instruction *AutoreleaseRV,
+ ARCInstKind &Class) {
// Check for a return of the pointer value.
- const Value *Ptr = GetObjCArg(AutoreleaseRV);
+ const Value *Ptr = GetArgRCIdentityRoot(AutoreleaseRV);
SmallVector<const Value *, 2> Users;
Users.push_back(Ptr);
do {
Ptr = Users.pop_back_val();
for (const User *U : Ptr->users()) {
- if (isa<ReturnInst>(U) || GetBasicInstructionClass(U) == IC_RetainRV)
+ if (isa<ReturnInst>(U) || GetBasicARCInstKind(U) == ARCInstKind::RetainRV)
return;
if (isa<BitCastInst>(U))
Users.push_back(U);
@@ -1279,7 +1277,7 @@ ObjCARCOpt::OptimizeAutoreleaseRVCall(Function &F, Instruction *AutoreleaseRV,
Constant *NewDecl = EP.get(ARCRuntimeEntryPoints::EPT_Autorelease);
AutoreleaseRVCI->setCalledFunction(NewDecl);
AutoreleaseRVCI->setTailCall(false); // Never tail call objc_autorelease.
- Class = IC_Autorelease;
+ Class = ARCInstKind::Autorelease;
DEBUG(dbgs() << "New: " << *AutoreleaseRV << "\n");
@@ -1296,7 +1294,7 @@ void ObjCARCOpt::OptimizeIndividualCalls(Function &F) {
for (inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E; ) {
Instruction *Inst = &*I++;
- InstructionClass Class = GetBasicInstructionClass(Inst);
+ ARCInstKind Class = GetBasicARCInstKind(Inst);
DEBUG(dbgs() << "Visiting: Class: " << Class << "; " << *Inst << "\n");
@@ -1311,7 +1309,7 @@ void ObjCARCOpt::OptimizeIndividualCalls(Function &F) {
// There are gray areas here, as the ability to cast reference-counted
// pointers to raw void* and back allows code to break ARC assumptions,
// however these are currently considered to be unimportant.
- case IC_NoopCast:
+ case ARCInstKind::NoopCast:
Changed = true;
++NumNoops;
DEBUG(dbgs() << "Erasing no-op cast: " << *Inst << "\n");
@@ -1319,11 +1317,11 @@ void ObjCARCOpt::OptimizeIndividualCalls(Function &F) {
continue;
// If the pointer-to-weak-pointer is null, it's undefined behavior.
- case IC_StoreWeak:
- case IC_LoadWeak:
- case IC_LoadWeakRetained:
- case IC_InitWeak:
- case IC_DestroyWeak: {
+ case ARCInstKind::StoreWeak:
+ case ARCInstKind::LoadWeak:
+ case ARCInstKind::LoadWeakRetained:
+ case ARCInstKind::InitWeak:
+ case ARCInstKind::DestroyWeak: {
CallInst *CI = cast<CallInst>(Inst);
if (IsNullOrUndef(CI->getArgOperand(0))) {
Changed = true;
@@ -1340,8 +1338,8 @@ void ObjCARCOpt::OptimizeIndividualCalls(Function &F) {
}
break;
}
- case IC_CopyWeak:
- case IC_MoveWeak: {
+ case ARCInstKind::CopyWeak:
+ case ARCInstKind::MoveWeak: {
CallInst *CI = cast<CallInst>(Inst);
if (IsNullOrUndef(CI->getArgOperand(0)) ||
IsNullOrUndef(CI->getArgOperand(1))) {
@@ -1361,11 +1359,11 @@ void ObjCARCOpt::OptimizeIndividualCalls(Function &F) {
}
break;
}
- case IC_RetainRV:
+ case ARCInstKind::RetainRV:
if (OptimizeRetainRVCall(F, Inst))
continue;
break;
- case IC_AutoreleaseRV:
+ case ARCInstKind::AutoreleaseRV:
OptimizeAutoreleaseRVCall(F, Inst, Class);
break;
}
@@ -1393,7 +1391,7 @@ void ObjCARCOpt::OptimizeIndividualCalls(Function &F) {
EraseInstruction(Call);
Inst = NewCall;
- Class = IC_Release;
+ Class = ARCInstKind::Release;
}
}
@@ -1424,11 +1422,11 @@ void ObjCARCOpt::OptimizeIndividualCalls(Function &F) {
}
if (!IsNoopOnNull(Class)) {
- UsedInThisFunction |= 1 << Class;
+ UsedInThisFunction |= 1 << unsigned(Class);
continue;
}
- const Value *Arg = GetObjCArg(Inst);
+ const Value *Arg = GetArgRCIdentityRoot(Inst);
// ARC calls with null are no-ops. Delete them.
if (IsNullOrUndef(Arg)) {
@@ -1442,7 +1440,7 @@ void ObjCARCOpt::OptimizeIndividualCalls(Function &F) {
// Keep track of which of retain, release, autorelease, and retain_block
// are actually present in this function.
- UsedInThisFunction |= 1 << Class;
+ UsedInThisFunction |= 1 << unsigned(Class);
// If Arg is a PHI, and one or more incoming values to the
// PHI are null, and the call is control-equivalent to the PHI, and there
@@ -1465,7 +1463,7 @@ void ObjCARCOpt::OptimizeIndividualCalls(Function &F) {
bool HasCriticalEdges = false;
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
Value *Incoming =
- StripPointerCastsAndObjCCalls(PN->getIncomingValue(i));
+ GetRCIdentityRoot(PN->getIncomingValue(i));
if (IsNullOrUndef(Incoming))
HasNull = true;
else if (cast<TerminatorInst>(PN->getIncomingBlock(i)->back())
@@ -1482,25 +1480,25 @@ void ObjCARCOpt::OptimizeIndividualCalls(Function &F) {
// Check that there is nothing that cares about the reference
// count between the call and the phi.
switch (Class) {
- case IC_Retain:
- case IC_RetainBlock:
+ case ARCInstKind::Retain:
+ case ARCInstKind::RetainBlock:
// These can always be moved up.
break;
- case IC_Release:
+ case ARCInstKind::Release:
// These can't be moved across things that care about the retain
// count.
FindDependencies(NeedsPositiveRetainCount, Arg,
Inst->getParent(), Inst,
DependingInstructions, Visited, PA);
break;
- case IC_Autorelease:
+ case ARCInstKind::Autorelease:
// These can't be moved across autorelease pool scope boundaries.
FindDependencies(AutoreleasePoolBoundary, Arg,
Inst->getParent(), Inst,
DependingInstructions, Visited, PA);
break;
- case IC_RetainRV:
- case IC_AutoreleaseRV:
+ case ARCInstKind::RetainRV:
+ case ARCInstKind::AutoreleaseRV:
// Don't move these; the RV optimization depends on the autoreleaseRV
// being tail called, and the retainRV being immediately after a call
// (which might still happen if we get lucky with codegen layout, but
@@ -1519,7 +1517,7 @@ void ObjCARCOpt::OptimizeIndividualCalls(Function &F) {
Type *ParamTy = CInst->getArgOperand(0)->getType();
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
Value *Incoming =
- StripPointerCastsAndObjCCalls(PN->getIncomingValue(i));
+ GetRCIdentityRoot(PN->getIncomingValue(i));
if (!IsNullOrUndef(Incoming)) {
CallInst *Clone = cast<CallInst>(CInst->clone());
Value *Op = PN->getIncomingValue(i);
@@ -1713,14 +1711,14 @@ ObjCARCOpt::VisitInstructionBottomUp(Instruction *Inst,
MapVector<Value *, RRInfo> &Retains,
BBState &MyStates) {
bool NestingDetected = false;
- InstructionClass Class = GetInstructionClass(Inst);
+ ARCInstKind Class = GetARCInstKind(Inst);
const Value *Arg = nullptr;
DEBUG(dbgs() << "Class: " << Class << "\n");
switch (Class) {
- case IC_Release: {
- Arg = GetObjCArg(Inst);
+ case ARCInstKind::Release: {
+ Arg = GetArgRCIdentityRoot(Inst);
PtrState &S = MyStates.getPtrBottomUpState(Arg);
@@ -1747,14 +1745,14 @@ ObjCARCOpt::VisitInstructionBottomUp(Instruction *Inst,
S.SetKnownPositiveRefCount();
break;
}
- case IC_RetainBlock:
+ case ARCInstKind::RetainBlock:
// In OptimizeIndividualCalls, we have strength reduced all optimizable
// objc_retainBlocks to objc_retains. Thus at this point any
// objc_retainBlocks that we see are not optimizable.
break;
- case IC_Retain:
- case IC_RetainRV: {
- Arg = GetObjCArg(Inst);
+ case ARCInstKind::Retain:
+ case ARCInstKind::RetainRV: {
+ Arg = GetArgRCIdentityRoot(Inst);
PtrState &S = MyStates.getPtrBottomUpState(Arg);
S.SetKnownPositiveRefCount();
@@ -1771,9 +1769,10 @@ ObjCARCOpt::VisitInstructionBottomUp(Instruction *Inst,
S.ClearReverseInsertPts();
// FALL THROUGH
case S_CanRelease:
- // Don't do retain+release tracking for IC_RetainRV, because it's
+ // Don't do retain+release tracking for ARCInstKind::RetainRV,
+ // because it's
// better to let it remain as the first instruction after a call.
- if (Class != IC_RetainRV)
+ if (Class != ARCInstKind::RetainRV)
Retains[Inst] = S.GetRRInfo();
S.ClearSequenceProgress();
break;
@@ -1786,15 +1785,15 @@ ObjCARCOpt::VisitInstructionBottomUp(Instruction *Inst,
// A retain moving bottom up can be a use.
break;
}
- case IC_AutoreleasepoolPop:
+ case ARCInstKind::AutoreleasepoolPop:
// Conservatively, clear MyStates for all known pointers.
MyStates.clearBottomUpPointers();
return NestingDetected;
- case IC_AutoreleasepoolPush:
- case IC_None:
+ case ARCInstKind::AutoreleasepoolPush:
+ case ARCInstKind::None:
// These are irrelevant.
return NestingDetected;
- case IC_User:
+ case ARCInstKind::User:
// If we have a store into an alloca of a pointer we are tracking, the
// pointer has multiple owners implying that we must be more conservative.
//
@@ -1810,7 +1809,7 @@ ObjCARCOpt::VisitInstructionBottomUp(Instruction *Inst,
if (StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
if (AreAnyUnderlyingObjectsAnAlloca(SI->getPointerOperand())) {
BBState::ptr_iterator I = MyStates.findPtrBottomUpState(
- StripPointerCastsAndObjCCalls(SI->getValueOperand()));
+ GetRCIdentityRoot(SI->getValueOperand()));
if (I != MyStates.bottom_up_ptr_end())
MultiOwnersSet.insert(I->first);
}
@@ -1969,24 +1968,25 @@ ObjCARCOpt::VisitInstructionTopDown(Instruction *Inst,
DenseMap<Value *, RRInfo> &Releases,
BBState &MyStates) {
bool NestingDetected = false;
- InstructionClass Class = GetInstructionClass(Inst);
+ ARCInstKind Class = GetARCInstKind(Inst);
const Value *Arg = nullptr;
switch (Class) {
- case IC_RetainBlock:
+ case ARCInstKind::RetainBlock:
// In OptimizeIndividualCalls, we have strength reduced all optimizable
// objc_retainBlocks to objc_retains. Thus at this point any
// objc_retainBlocks that we see are not optimizable.
break;
- case IC_Retain:
- case IC_RetainRV: {
- Arg = GetObjCArg(Inst);
+ case ARCInstKind::Retain:
+ case ARCInstKind::RetainRV: {
+ Arg = GetArgRCIdentityRoot(Inst);
PtrState &S = MyStates.getPtrTopDownState(Arg);
- // Don't do retain+release tracking for IC_RetainRV, because it's
+ // Don't do retain+release tracking for ARCInstKind::RetainRV, because
+ // it's
// better to let it remain as the first instruction after a call.
- if (Class != IC_RetainRV) {
+ if (Class != ARCInstKind::RetainRV) {
// If we see two retains in a row on the same pointer. If so, make
// a note, and we'll cicle back to revisit it after we've
// hopefully eliminated the second retain, which may allow us to
@@ -2009,8 +2009,8 @@ ObjCARCOpt::VisitInstructionTopDown(Instruction *Inst,
// code below.
break;
}
- case IC_Release: {
- Arg = GetObjCArg(Inst);
+ case ARCInstKind::Release: {
+ Arg = GetArgRCIdentityRoot(Inst);
PtrState &S = MyStates.getPtrTopDownState(Arg);
S.ClearKnownPositiveRefCount();
@@ -2041,12 +2041,12 @@ ObjCARCOpt::VisitInstructionTopDown(Instruction *Inst,
}
break;
}
- case IC_AutoreleasepoolPop:
+ case ARCInstKind::AutoreleasepoolPop:
// Conservatively, clear MyStates for all known pointers.
MyStates.clearTopDownPointers();
return NestingDetected;
- case IC_AutoreleasepoolPush:
- case IC_None:
+ case ARCInstKind::AutoreleasepoolPush:
+ case ARCInstKind::None:
// These are irrelevant.
return NestingDetected;
default:
@@ -2374,7 +2374,7 @@ ObjCARCOpt::ConnectTDBUTraversals(DenseMap<const BasicBlock *, BBState>
const RRInfo &NewRetainRRI = It->second;
KnownSafeTD &= NewRetainRRI.KnownSafe;
MultipleOwners =
- MultipleOwners || MultiOwnersSet.count(GetObjCArg(NewRetain));
+ MultipleOwners || MultiOwnersSet.count(GetArgRCIdentityRoot(NewRetain));
for (Instruction *NewRetainRelease : NewRetainRRI.Calls) {
DenseMap<Value *, RRInfo>::const_iterator Jt =
Releases.find(NewRetainRelease);
@@ -2583,7 +2583,7 @@ ObjCARCOpt::PerformCodePlacement(DenseMap<const BasicBlock *, BBState>
DEBUG(dbgs() << "Visiting: " << *Retain << "\n");
- Value *Arg = GetObjCArg(Retain);
+ Value *Arg = GetArgRCIdentityRoot(Retain);
// If the object being released is in static or stack storage, we know it's
// not being managed by ObjC reference counting, so we can delete pairs
@@ -2595,7 +2595,7 @@ ObjCARCOpt::PerformCodePlacement(DenseMap<const BasicBlock *, BBState>
if (const LoadInst *LI = dyn_cast<LoadInst>(Arg))
if (const GlobalVariable *GV =
dyn_cast<GlobalVariable>(
- StripPointerCastsAndObjCCalls(LI->getPointerOperand())))
+ GetRCIdentityRoot(LI->getPointerOperand())))
if (GV->isConstant())
KnownSafe = true;
@@ -2642,12 +2642,13 @@ void ObjCARCOpt::OptimizeWeakCalls(Function &F) {
DEBUG(dbgs() << "Visiting: " << *Inst << "\n");
- InstructionClass Class = GetBasicInstructionClass(Inst);
- if (Class != IC_LoadWeak && Class != IC_LoadWeakRetained)
+ ARCInstKind Class = GetBasicARCInstKind(Inst);
+ if (Class != ARCInstKind::LoadWeak &&
+ Class != ARCInstKind::LoadWeakRetained)
continue;
// Delete objc_loadWeak calls with no users.
- if (Class == IC_LoadWeak && Inst->use_empty()) {
+ if (Class == ARCInstKind::LoadWeak && Inst->use_empty()) {
Inst->eraseFromParent();
continue;
}
@@ -2662,10 +2663,10 @@ void ObjCARCOpt::OptimizeWeakCalls(Function &F) {
J = Current.getInstructionIterator();
J != B; --J) {
Instruction *EarlierInst = &*std::prev(J);
- InstructionClass EarlierClass = GetInstructionClass(EarlierInst);
+ ARCInstKind EarlierClass = GetARCInstKind(EarlierInst);
switch (EarlierClass) {
- case IC_LoadWeak:
- case IC_LoadWeakRetained: {
+ case ARCInstKind::LoadWeak:
+ case ARCInstKind::LoadWeakRetained: {
// If this is loading from the same pointer, replace this load's value
// with that one.
CallInst *Call = cast<CallInst>(Inst);
@@ -2676,7 +2677,7 @@ void ObjCARCOpt::OptimizeWeakCalls(Function &F) {
case AliasAnalysis::MustAlias:
Changed = true;
// If the load has a builtin retain, insert a plain retain for it.
- if (Class == IC_LoadWeakRetained) {
+ if (Class == ARCInstKind::LoadWeakRetained) {
Constant *Decl = EP.get(ARCRuntimeEntryPoints::EPT_Retain);
CallInst *CI = CallInst::Create(Decl, EarlierCall, "", Call);
CI->setTailCall();
@@ -2693,8 +2694,8 @@ void ObjCARCOpt::OptimizeWeakCalls(Function &F) {
}
break;
}
- case IC_StoreWeak:
- case IC_InitWeak: {
+ case ARCInstKind::StoreWeak:
+ case ARCInstKind::InitWeak: {
// If this is storing to the same pointer and has the same size etc.
// replace this load's value with the stored value.
CallInst *Call = cast<CallInst>(Inst);
@@ -2705,7 +2706,7 @@ void ObjCARCOpt::OptimizeWeakCalls(Function &F) {
case AliasAnalysis::MustAlias:
Changed = true;
// If the load has a builtin retain, insert a plain retain for it.
- if (Class == IC_LoadWeakRetained) {
+ if (Class == ARCInstKind::LoadWeakRetained) {
Constant *Decl = EP.get(ARCRuntimeEntryPoints::EPT_Retain);
CallInst *CI = CallInst::Create(Decl, EarlierCall, "", Call);
CI->setTailCall();
@@ -2722,14 +2723,14 @@ void ObjCARCOpt::OptimizeWeakCalls(Function &F) {
}
break;
}
- case IC_MoveWeak:
- case IC_CopyWeak:
+ case ARCInstKind::MoveWeak:
+ case ARCInstKind::CopyWeak:
// TOOD: Grab the copied value.
goto clobbered;
- case IC_AutoreleasepoolPush:
- case IC_None:
- case IC_IntrinsicUser:
- case IC_User:
+ case ARCInstKind::AutoreleasepoolPush:
+ case ARCInstKind::None:
+ case ARCInstKind::IntrinsicUser:
+ case ARCInstKind::User:
// Weak pointers are only modified through the weak entry points
// (and arbitrary calls, which could call the weak entry points).
break;
@@ -2745,8 +2746,8 @@ void ObjCARCOpt::OptimizeWeakCalls(Function &F) {
// the alloca and all its users can be zapped.
for (inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E; ) {
Instruction *Inst = &*I++;
- InstructionClass Class = GetBasicInstructionClass(Inst);
- if (Class != IC_DestroyWeak)
+ ARCInstKind Class = GetBasicARCInstKind(Inst);
+ if (Class != ARCInstKind::DestroyWeak)
continue;
CallInst *Call = cast<CallInst>(Inst);
@@ -2754,10 +2755,10 @@ void ObjCARCOpt::OptimizeWeakCalls(Function &F) {
if (AllocaInst *Alloca = dyn_cast<AllocaInst>(Arg)) {
for (User *U : Alloca->users()) {
const Instruction *UserInst = cast<Instruction>(U);
- switch (GetBasicInstructionClass(UserInst)) {
- case IC_InitWeak:
- case IC_StoreWeak:
- case IC_DestroyWeak:
+ switch (GetBasicARCInstKind(UserInst)) {
+ case ARCInstKind::InitWeak:
+ case ARCInstKind::StoreWeak:
+ case ARCInstKind::DestroyWeak:
continue;
default:
goto done;
@@ -2766,13 +2767,13 @@ void ObjCARCOpt::OptimizeWeakCalls(Function &F) {
Changed = true;
for (auto UI = Alloca->user_begin(), UE = Alloca->user_end(); UI != UE;) {
CallInst *UserInst = cast<CallInst>(*UI++);
- switch (GetBasicInstructionClass(UserInst)) {
- case IC_InitWeak:
- case IC_StoreWeak:
+ switch (GetBasicARCInstKind(UserInst)) {
+ case ARCInstKind::InitWeak:
+ case ARCInstKind::StoreWeak:
// These functions return their second argument.
UserInst->replaceAllUsesWith(UserInst->getArgOperand(1));
break;
- case IC_DestroyWeak:
+ case ARCInstKind::DestroyWeak:
// No return value.
break;
default:
@@ -2835,8 +2836,8 @@ HasSafePathToPredecessorCall(const Value *Arg, Instruction *Retain,
return false;
// Check that the call is a regular call.
- InstructionClass Class = GetBasicInstructionClass(Call);
- if (Class != IC_CallOrUser && Class != IC_Call)
+ ARCInstKind Class = GetBasicARCInstKind(Call);
+ if (Class != ARCInstKind::CallOrUser && Class != ARCInstKind::Call)
return false;
return true;
@@ -2860,9 +2861,8 @@ FindPredecessorRetainWithSafePath(const Value *Arg, BasicBlock *BB,
dyn_cast_or_null<CallInst>(*DepInsts.begin());
// Check that we found a retain with the same argument.
- if (!Retain ||
- !IsRetain(GetBasicInstructionClass(Retain)) ||
- GetObjCArg(Retain) != Arg) {
+ if (!Retain || !IsRetain(GetBasicARCInstKind(Retain)) ||
+ GetArgRCIdentityRoot(Retain) != Arg) {
return nullptr;
}
@@ -2887,10 +2887,10 @@ FindPredecessorAutoreleaseWithSafePath(const Value *Arg, BasicBlock *BB,
dyn_cast_or_null<CallInst>(*DepInsts.begin());
if (!Autorelease)
return nullptr;
- InstructionClass AutoreleaseClass = GetBasicInstructionClass(Autorelease);
+ ARCInstKind AutoreleaseClass = GetBasicARCInstKind(Autorelease);
if (!IsAutorelease(AutoreleaseClass))
return nullptr;
- if (GetObjCArg(Autorelease) != Arg)
+ if (GetArgRCIdentityRoot(Autorelease) != Arg)
return nullptr;
return Autorelease;
@@ -2921,7 +2921,7 @@ void ObjCARCOpt::OptimizeReturns(Function &F) {
if (!Ret)
continue;
- const Value *Arg = StripPointerCastsAndObjCCalls(Ret->getOperand(0));
+ const Value *Arg = GetRCIdentityRoot(Ret->getOperand(0));
// Look for an ``autorelease'' instruction that is a predecessor of Ret and
// dependent on Arg such that there are no instructions dependent on Arg
@@ -2976,13 +2976,13 @@ ObjCARCOpt::GatherStatistics(Function &F, bool AfterOptimization) {
for (inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E; ) {
Instruction *Inst = &*I++;
- switch (GetBasicInstructionClass(Inst)) {
+ switch (GetBasicARCInstKind(Inst)) {
default:
break;
- case IC_Retain:
+ case ARCInstKind::Retain:
++NumRetains;
break;
- case IC_Release:
+ case ARCInstKind::Release:
++NumReleases;
break;
}
@@ -3054,27 +3054,27 @@ bool ObjCARCOpt::runOnFunction(Function &F) {
OptimizeIndividualCalls(F);
// Optimizations for weak pointers.
- if (UsedInThisFunction & ((1 << IC_LoadWeak) |
- (1 << IC_LoadWeakRetained) |
- (1 << IC_StoreWeak) |
- (1 << IC_InitWeak) |
- (1 << IC_CopyWeak) |
- (1 << IC_MoveWeak) |
- (1 << IC_DestroyWeak)))
+ if (UsedInThisFunction & ((1 << unsigned(ARCInstKind::LoadWeak)) |
+ (1 << unsigned(ARCInstKind::LoadWeakRetained)) |
+ (1 << unsigned(ARCInstKind::StoreWeak)) |
+ (1 << unsigned(ARCInstKind::InitWeak)) |
+ (1 << unsigned(ARCInstKind::CopyWeak)) |
+ (1 << unsigned(ARCInstKind::MoveWeak)) |
+ (1 << unsigned(ARCInstKind::DestroyWeak))))
OptimizeWeakCalls(F);
// Optimizations for retain+release pairs.
- if (UsedInThisFunction & ((1 << IC_Retain) |
- (1 << IC_RetainRV) |
- (1 << IC_RetainBlock)))
- if (UsedInThisFunction & (1 << IC_Release))
+ if (UsedInThisFunction & ((1 << unsigned(ARCInstKind::Retain)) |
+ (1 << unsigned(ARCInstKind::RetainRV)) |
+ (1 << unsigned(ARCInstKind::RetainBlock))))
+ if (UsedInThisFunction & (1 << unsigned(ARCInstKind::Release)))
// Run OptimizeSequences until it either stops making changes or
// no retain+release pair nesting is detected.
while (OptimizeSequences(F)) {}
// Optimizations if objc_autorelease is used.
- if (UsedInThisFunction & ((1 << IC_Autorelease) |
- (1 << IC_AutoreleaseRV)))
+ if (UsedInThisFunction & ((1 << unsigned(ARCInstKind::Autorelease)) |
+ (1 << unsigned(ARCInstKind::AutoreleaseRV))))
OptimizeReturns(F);
// Gather statistics after optimization.