Skip to content

Commit 3e65883

Browse files
committed
Delete ObjCARCAPElim, as it is entirely superseded by ObjCARCOpts
The optimization can be completely superseded now
1 parent e63c64b commit 3e65883

File tree

9 files changed

+324
-170
lines changed

9 files changed

+324
-170
lines changed

clang/lib/CodeGen/BackendUtil.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,12 +1022,6 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
10221022
MPM.addPass(
10231023
createModuleToFunctionPassAdaptor(ObjCARCExpandPass()));
10241024
});
1025-
PB.registerPipelineEarlySimplificationEPCallback(
1026-
[](ModulePassManager &MPM, OptimizationLevel Level,
1027-
ThinOrFullLTOPhase) {
1028-
if (Level != OptimizationLevel::O0)
1029-
MPM.addPass(ObjCARCAPElimPass());
1030-
});
10311025
PB.registerScalarOptimizerLateEPCallback(
10321026
[](FunctionPassManager &FPM, OptimizationLevel Level) {
10331027
if (Level != OptimizationLevel::O0)

llvm/include/llvm/Transforms/ObjCARC.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,6 @@ struct ObjCARCContractPass : public PassInfoMixin<ObjCARCContractPass> {
3535
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
3636
};
3737

38-
struct ObjCARCAPElimPass : public PassInfoMixin<ObjCARCAPElimPass> {
39-
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
40-
};
41-
4238
struct ObjCARCExpandPass : public PassInfoMixin<ObjCARCExpandPass> {
4339
LLVM_ABI PreservedAnalyses run(Function &M, FunctionAnalysisManager &AM);
4440
};

llvm/lib/Passes/PassRegistry.def

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,6 @@ MODULE_PASS("module-inline", ModuleInlinerPass())
113113
MODULE_PASS("name-anon-globals", NameAnonGlobalPass())
114114
MODULE_PASS("no-op-module", NoOpModulePass())
115115
MODULE_PASS("nsan", NumericalStabilitySanitizerPass())
116-
MODULE_PASS("objc-arc-apelim", ObjCARCAPElimPass())
117116
MODULE_PASS("openmp-opt", OpenMPOptPass())
118117
MODULE_PASS("openmp-opt-postlink",
119118
OpenMPOptPass(ThinOrFullLTOPhase::FullLTOPostLink))

llvm/lib/Transforms/ObjCARC/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ add_llvm_component_library(LLVMObjCARCOpts
22
ObjCARC.cpp
33
ObjCARCOpts.cpp
44
ObjCARCExpand.cpp
5-
ObjCARCAPElim.cpp
65
ObjCARCContract.cpp
76
DependencyAnalysis.cpp
87
ProvenanceAnalysis.cpp

llvm/lib/Transforms/ObjCARC/ObjCARCAPElim.cpp

Lines changed: 0 additions & 156 deletions
This file was deleted.

llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2490,6 +2490,124 @@ bool ObjCARCOpt::run(Function &F, AAResults &AA) {
24902490
return Changed;
24912491
}
24922492

2493+
/// Interprocedurally determine if calls made by the given call site can
2494+
/// possibly produce autoreleases.
2495+
bool MayAutorelease(const CallBase &CB, unsigned Depth = 0) {
2496+
if (CB.onlyReadsMemory())
2497+
return false;
2498+
2499+
// This recursion depth limit is arbitrary. It's just great
2500+
// enough to cover known interesting testcases.
2501+
if (Depth > 5)
2502+
return true;
2503+
2504+
if (const Function *Callee = CB.getCalledFunction()) {
2505+
if (!Callee->hasExactDefinition())
2506+
return true;
2507+
for (const BasicBlock &BB : *Callee) {
2508+
// If we come across an autoreleasepool push and a pop in the same block,
2509+
// we can ignore the instructions between them.
2510+
// TODO: Can we check inter-block autorelease pool pairs?
2511+
// This would involve tracking autorelease pool state across blocks.
2512+
2513+
// First pass: find all push/pop pairs and their positions in this basic
2514+
// block
2515+
SmallVector<std::pair<unsigned, unsigned>, 4>
2516+
ShadowedRegions; // (push_pos, pop_pos)
2517+
SmallVector<std::pair<unsigned, const Instruction *>, 4>
2518+
PushStack; // (index, push_inst)
2519+
2520+
unsigned InstIndex = 0;
2521+
for (const Instruction &I : BB) {
2522+
if (GetBasicARCInstKind(&I) == ARCInstKind::AutoreleasepoolPush) {
2523+
PushStack.push_back({InstIndex, &I});
2524+
} else if (GetBasicARCInstKind(&I) == ARCInstKind::AutoreleasepoolPop) {
2525+
if (!PushStack.empty()) {
2526+
auto [PushIndex, PushInst] = PushStack.back();
2527+
// Verify this pop actually pops the corresponding push
2528+
const auto *PopCall = cast<CallInst>(&I);
2529+
if (PopCall->getArgOperand(0)->stripPointerCasts() == PushInst) {
2530+
// Valid push/pop pair - add to shadowed regions
2531+
ShadowedRegions.push_back({PushIndex, InstIndex});
2532+
PushStack.pop_back();
2533+
}
2534+
// If pop doesn't match the most recent push, it might be for an
2535+
// outer pool in a different basic block, so we leave the stack
2536+
// unchanged
2537+
}
2538+
}
2539+
InstIndex++;
2540+
}
2541+
2542+
// Second pass: check for autoreleases, ignoring shadowed regions
2543+
InstIndex = 0;
2544+
for (const Instruction &I : BB) {
2545+
// Check if this instruction is in a shadowed region (between inner
2546+
// push/pop pairs)
2547+
bool InShadowedRegion = false;
2548+
for (auto [PushIndex, PopIndex] : ShadowedRegions) {
2549+
if (InstIndex > PushIndex && InstIndex < PopIndex) {
2550+
InShadowedRegion = true;
2551+
break;
2552+
}
2553+
}
2554+
2555+
if (InShadowedRegion) {
2556+
InstIndex++;
2557+
continue; // Skip instructions in shadowed regions - they don't affect
2558+
// outer pools
2559+
}
2560+
2561+
ARCInstKind InstKind = GetBasicARCInstKind(&I);
2562+
switch (InstKind) {
2563+
case ARCInstKind::Autorelease:
2564+
case ARCInstKind::AutoreleaseRV:
2565+
case ARCInstKind::FusedRetainAutorelease:
2566+
case ARCInstKind::FusedRetainAutoreleaseRV:
2567+
case ARCInstKind::LoadWeak:
2568+
// These may produce autoreleases
2569+
return true;
2570+
2571+
case ARCInstKind::Retain:
2572+
case ARCInstKind::RetainRV:
2573+
case ARCInstKind::UnsafeClaimRV:
2574+
case ARCInstKind::RetainBlock:
2575+
case ARCInstKind::Release:
2576+
case ARCInstKind::NoopCast:
2577+
case ARCInstKind::LoadWeakRetained:
2578+
case ARCInstKind::StoreWeak:
2579+
case ARCInstKind::InitWeak:
2580+
case ARCInstKind::MoveWeak:
2581+
case ARCInstKind::CopyWeak:
2582+
case ARCInstKind::DestroyWeak:
2583+
case ARCInstKind::StoreStrong:
2584+
case ARCInstKind::AutoreleasepoolPush:
2585+
case ARCInstKind::AutoreleasepoolPop:
2586+
// These ObjC runtime functions don't produce autoreleases
2587+
break;
2588+
2589+
case ARCInstKind::CallOrUser:
2590+
case ARCInstKind::Call:
2591+
// For non-ObjC function calls, recursively analyze
2592+
if (MayAutorelease(cast<CallBase>(I), Depth + 1))
2593+
return true;
2594+
break;
2595+
2596+
case ARCInstKind::IntrinsicUser:
2597+
case ARCInstKind::User:
2598+
case ARCInstKind::None:
2599+
// These are not relevant for autorelease analysis
2600+
break;
2601+
}
2602+
InstIndex++;
2603+
}
2604+
}
2605+
return false;
2606+
}
2607+
2608+
return true;
2609+
}
2610+
24932611
/// Optimize autorelease pools by eliminating empty push/pop pairs.
24942612
void ObjCARCOpt::OptimizeAutoreleasePools(Function &F) {
24952613
LLVM_DEBUG(dbgs() << "\n== ObjCARCOpt::OptimizeAutoreleasePools ==\n");
@@ -2558,6 +2676,9 @@ void ObjCARCOpt::OptimizeAutoreleasePools(Function &F) {
25582676
}
25592677
case ARCInstKind::CallOrUser:
25602678
case ARCInstKind::Call:
2679+
if (!MayAutorelease(cast<CallBase>(Inst)))
2680+
break;
2681+
[[fallthrough]];
25612682
case ARCInstKind::Autorelease:
25622683
case ARCInstKind::AutoreleaseRV:
25632684
case ARCInstKind::FusedRetainAutorelease:

llvm/test/Transforms/ObjCARC/apelim.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; RUN: opt -S -passes=objc-arc-apelim < %s | FileCheck %s
1+
; RUN: opt -S -passes=objc-arc < %s | FileCheck %s
22
; rdar://10227311
33

44
@llvm.global_ctors = appending global [2 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @_GLOBAL__I_x, ptr null }, { i32, ptr, ptr } { i32 65535, ptr @_GLOBAL__I_y, ptr null }]

llvm/test/Transforms/ObjCARC/comdat-ipo.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; RUN: opt -S -passes=objc-arc-apelim < %s | FileCheck %s
1+
; RUN: opt -S -passes=objc-arc < %s | FileCheck %s
22

33
; See PR26774
44

0 commit comments

Comments
 (0)