Skip to content

Commit 8cc8e5d

Browse files
NuriAmariNuri Amari
andauthored
Run ObjCContractPass in Default Codegen Pipeline (#92331)
Prior to this patch, when using -fthinlto-index= the ObjCARCContractPass isn't run prior to CodeGen, and instruction selection fails on IR containing arc intrinsics. This patch is motivated by that usecase. The pass was previously added in various places codegen is performed. This patch adds the pass to the default codegen pipepline, makes sure it bails immediately if no arc intrinsics are found, and removes the adhoc scheduling of the pass. Co-authored-by: Nuri Amari <[email protected]>
1 parent 910292c commit 8cc8e5d

File tree

20 files changed

+115
-37
lines changed

20 files changed

+115
-37
lines changed

clang/lib/CodeGen/BackendUtil.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -587,12 +587,6 @@ bool EmitAssemblyHelper::AddEmitPasses(legacy::PassManager &CodeGenPasses,
587587
// this also adds codegenerator level optimization passes.
588588
CodeGenFileType CGFT = getCodeGenFileType(Action);
589589

590-
// Add ObjC ARC final-cleanup optimizations. This is done as part of the
591-
// "codegen" passes so that it isn't run multiple times when there is
592-
// inlining happening.
593-
if (CodeGenOpts.OptimizationLevel > 0)
594-
CodeGenPasses.add(createObjCARCContractPass());
595-
596590
if (TM->addPassesToEmitFile(CodeGenPasses, OS, DwoOS, CGFT,
597591
/*DisableVerify=*/!CodeGenOpts.VerifyModule)) {
598592
Diags.Report(diag::err_fe_unable_to_interface_with_target);
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
; RUN: opt -thinlto-bc -o %t.o %s
2+
3+
; RUN: llvm-lto2 run -thinlto-distributed-indexes %t.o \
4+
; RUN: -o %t2.index \
5+
; RUN: -r=%t.o,_use_arc,px
6+
7+
; RUN: %clang_cc1 -triple x86_64-apple-darwin \
8+
; RUN: -emit-obj -fthinlto-index=%t.o.thinlto.bc \
9+
; RUN: -o %t.native.o -x ir %t.o
10+
11+
target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
12+
target triple = "x86_64-apple-darwin"
13+
14+
define void @use_arc(ptr %a, ptr %b) {
15+
call void (...) @llvm.objc.clang.arc.use(ptr %a, ptr %b) nounwind
16+
ret void
17+
}
18+
19+
declare void @llvm.objc.clang.arc.use(...) nounwind

lld/MachO/LTO.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,6 @@ static lto::Config createConfig() {
4848
c.CPU = getCPUStr();
4949
c.MAttrs = getMAttrs();
5050
c.DiagHandler = diagnosticHandler;
51-
c.PreCodeGenPassesHook = [](legacy::PassManager &pm) {
52-
pm.add(createObjCARCContractPass());
53-
};
5451

5552
c.AlwaysEmitRegularLTOObj = !config->ltoObjPath.empty();
5653

llvm/include/llvm/Analysis/ObjCARCAnalysisUtils.h

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -41,26 +41,26 @@ extern bool EnableARCOpts;
4141
/// Test if the given module looks interesting to run ARC optimization
4242
/// on.
4343
inline bool ModuleHasARC(const Module &M) {
44-
return
45-
M.getNamedValue("llvm.objc.retain") ||
46-
M.getNamedValue("llvm.objc.release") ||
47-
M.getNamedValue("llvm.objc.autorelease") ||
48-
M.getNamedValue("llvm.objc.retainAutoreleasedReturnValue") ||
49-
M.getNamedValue("llvm.objc.unsafeClaimAutoreleasedReturnValue") ||
50-
M.getNamedValue("llvm.objc.retainBlock") ||
51-
M.getNamedValue("llvm.objc.autoreleaseReturnValue") ||
52-
M.getNamedValue("llvm.objc.autoreleasePoolPush") ||
53-
M.getNamedValue("llvm.objc.loadWeakRetained") ||
54-
M.getNamedValue("llvm.objc.loadWeak") ||
55-
M.getNamedValue("llvm.objc.destroyWeak") ||
56-
M.getNamedValue("llvm.objc.storeWeak") ||
57-
M.getNamedValue("llvm.objc.initWeak") ||
58-
M.getNamedValue("llvm.objc.moveWeak") ||
59-
M.getNamedValue("llvm.objc.copyWeak") ||
60-
M.getNamedValue("llvm.objc.retainedObject") ||
61-
M.getNamedValue("llvm.objc.unretainedObject") ||
62-
M.getNamedValue("llvm.objc.unretainedPointer") ||
63-
M.getNamedValue("llvm.objc.clang.arc.use");
44+
return M.getNamedValue("llvm.objc.retain") ||
45+
M.getNamedValue("llvm.objc.release") ||
46+
M.getNamedValue("llvm.objc.autorelease") ||
47+
M.getNamedValue("llvm.objc.retainAutoreleasedReturnValue") ||
48+
M.getNamedValue("llvm.objc.unsafeClaimAutoreleasedReturnValue") ||
49+
M.getNamedValue("llvm.objc.retainBlock") ||
50+
M.getNamedValue("llvm.objc.autoreleaseReturnValue") ||
51+
M.getNamedValue("llvm.objc.autoreleasePoolPush") ||
52+
M.getNamedValue("llvm.objc.loadWeakRetained") ||
53+
M.getNamedValue("llvm.objc.loadWeak") ||
54+
M.getNamedValue("llvm.objc.destroyWeak") ||
55+
M.getNamedValue("llvm.objc.storeWeak") ||
56+
M.getNamedValue("llvm.objc.initWeak") ||
57+
M.getNamedValue("llvm.objc.moveWeak") ||
58+
M.getNamedValue("llvm.objc.copyWeak") ||
59+
M.getNamedValue("llvm.objc.retainedObject") ||
60+
M.getNamedValue("llvm.objc.unretainedObject") ||
61+
M.getNamedValue("llvm.objc.unretainedPointer") ||
62+
M.getNamedValue("llvm.objc.clang.arc.noop.use") ||
63+
M.getNamedValue("llvm.objc.clang.arc.use");
6464
}
6565

6666
/// This is a wrapper around getUnderlyingObject which also knows how to

llvm/lib/CodeGen/TargetPassConfig.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include "llvm/Support/WithColor.h"
4747
#include "llvm/Target/CGPassBuilderOption.h"
4848
#include "llvm/Target/TargetMachine.h"
49+
#include "llvm/Transforms/ObjCARC.h"
4950
#include "llvm/Transforms/Scalar.h"
5051
#include "llvm/Transforms/Utils.h"
5152
#include <cassert>
@@ -946,6 +947,8 @@ void TargetPassConfig::addCodeGenPrepare() {
946947
void TargetPassConfig::addISelPrepare() {
947948
addPreISel();
948949

950+
addPass(createObjCARCContractPass());
951+
949952
// Force codegen to run according to the callgraph.
950953
if (requiresCodeGenSCCOrder())
951954
addPass(new DummyCGSCCPass);

llvm/lib/LTO/LTOCodeGenerator.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,6 @@ LTOCodeGenerator::LTOCodeGenerator(LLVMContext &Context)
137137

138138
Config.CodeModel = std::nullopt;
139139
Config.StatsFile = LTOStatsFile;
140-
Config.PreCodeGenPassesHook = [](legacy::PassManager &PM) {
141-
PM.add(createObjCARCContractPass());
142-
};
143-
144140
Config.RunCSIRInstr = LTORunCSIRInstr;
145141
Config.CSIRProfile = LTOCSIRProfile;
146142
}

llvm/lib/LTO/ThinLTOCodeGenerator.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -334,10 +334,6 @@ std::unique_ptr<MemoryBuffer> codegenModule(Module &TheModule,
334334
raw_svector_ostream OS(OutputBuffer);
335335
legacy::PassManager PM;
336336

337-
// If the bitcode files contain ARC code and were compiled with optimization,
338-
// the ObjCARCContractPass must be run, so do it unconditionally here.
339-
PM.add(createObjCARCContractPass());
340-
341337
// Setup the codegen now.
342338
if (TM.addPassesToEmitFile(PM, OS, nullptr, CodeGenFileType::ObjectFile,
343339
/* DisableVerify */ true))

llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ class ObjCARCContract {
7171
ARCRuntimeEntryPoints EP;
7272
BundledRetainClaimRVs *BundledInsts = nullptr;
7373

74+
/// A flag indicating whether this optimization pass should run.
75+
bool Run;
76+
7477
/// The inline asm string to insert between calls and RetainRV calls to make
7578
/// the optimization work on targets which need it.
7679
const MDString *RVInstMarker;
@@ -527,6 +530,10 @@ bool ObjCARCContract::tryToPeepholeInstruction(
527530
//===----------------------------------------------------------------------===//
528531

529532
bool ObjCARCContract::init(Module &M) {
533+
Run = ModuleHasARC(M);
534+
if (!Run)
535+
return false;
536+
530537
EP.init(&M);
531538

532539
// Initialize RVInstMarker.
@@ -539,6 +546,9 @@ bool ObjCARCContract::run(Function &F, AAResults *A, DominatorTree *D) {
539546
if (!EnableARCOpts)
540547
return false;
541548

549+
if (!Run)
550+
return false;
551+
542552
Changed = CFGChanged = false;
543553
AA = A;
544554
DT = D;

llvm/test/CodeGen/AArch64/O0-pipeline.ll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@
3131
; CHECK-NEXT: AArch64 Stack Tagging
3232
; CHECK-NEXT: SME ABI Pass
3333
; CHECK-NEXT: Exception handling preparation
34+
; CHECK-NEXT: Dominator Tree Construction
35+
; CHECK-NEXT: Basic Alias Analysis (stateless AA impl)
36+
; CHECK-NEXT: Function Alias Analysis Results
37+
; CHECK-NEXT: ObjC ARC contraction
3438
; CHECK-NEXT: Prepare callbr
3539
; CHECK-NEXT: Safe Stack instrumentation pass
3640
; CHECK-NEXT: Insert stack protectors

llvm/test/CodeGen/AArch64/O3-pipeline.ll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@
103103
; CHECK-NEXT: Dominator Tree Construction
104104
; CHECK-NEXT: FunctionPass Manager
105105
; CHECK-NEXT: Merge internal globals
106+
; CHECK-NEXT: Dominator Tree Construction
107+
; CHECK-NEXT: Basic Alias Analysis (stateless AA impl)
108+
; CHECK-NEXT: Function Alias Analysis Results
109+
; CHECK-NEXT: ObjC ARC contraction
106110
; CHECK-NEXT: Prepare callbr
107111
; CHECK-NEXT: Safe Stack instrumentation pass
108112
; CHECK-NEXT: Insert stack protectors

0 commit comments

Comments
 (0)