https://github.com/NuriAmari updated https://github.com/llvm/llvm-project/pull/92331
>From 66ddf609c0e77867ec48c17136fb80d1e482041d Mon Sep 17 00:00:00 2001 From: Nuri Amari <nuriam...@fb.com> Date: Wed, 15 May 2024 16:33:03 -0700 Subject: [PATCH 1/3] Run ObjCContractPass in Distributed Thin-LTO Pipeline Prior to this patch, when using -fthinlto-index= the ObjCARCContractPass isn't run prior to CodeGen, and instruction selection fails on IR containing arc intrinstics. --- clang/lib/CodeGen/BackendUtil.cpp | 3 +++ .../thinlto-distributed-objc-contract-pass.ll | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 clang/test/CodeGen/thinlto-distributed-objc-contract-pass.ll diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 90985c08fe7f8..03dd1df281d80 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -1289,6 +1289,9 @@ static void runThinLTOBackend( }; break; default: + Conf.PreCodeGenPassesHook = [](legacy::PassManager &Pm) { + Pm.add(createObjCARCContractPass()); + }; Conf.CGFileType = getCodeGenFileType(Action); break; } diff --git a/clang/test/CodeGen/thinlto-distributed-objc-contract-pass.ll b/clang/test/CodeGen/thinlto-distributed-objc-contract-pass.ll new file mode 100644 index 0000000000000..7d0247555b5c8 --- /dev/null +++ b/clang/test/CodeGen/thinlto-distributed-objc-contract-pass.ll @@ -0,0 +1,19 @@ +; RUN: opt -thinlto-bc -o %t.o %s + +; RUN: llvm-lto2 run -thinlto-distributed-indexes %t.o \ +; RUN: -o %t2.index \ +; RUN: -r=%t.o,_use_arc,px + +; RUN: %clang_cc1 -triple x86_64-apple-darwin \ +; RUN: -emit-obj -fthinlto-index=%t.o.thinlto.bc \ +; RUN: -o %t.native.o -x ir %t.o + +target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-apple-darwin" + +define void @use_arc(ptr %a, ptr %b) { + call void (...) @llvm.objc.clang.arc.use(i8* %a, i8* %b) nounwind + ret void +} + +declare void @llvm.objc.clang.arc.use(...) nounwind >From 142174dff7b12827f7af187e4ff08b3e75486923 Mon Sep 17 00:00:00 2001 From: Nuri Amari <nuriam...@fb.com> Date: Fri, 17 May 2024 11:38:16 -0700 Subject: [PATCH 2/3] Address PR Feedback - Adjust test - Unconditionally include ARC pass in ThinLTO pipeline --- clang/lib/CodeGen/BackendUtil.cpp | 3 --- clang/test/CodeGen/thinlto-distributed-objc-contract-pass.ll | 2 +- lld/MachO/LTO.cpp | 3 --- llvm/lib/LTO/LTOBackend.cpp | 2 ++ 4 files changed, 3 insertions(+), 7 deletions(-) diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 03dd1df281d80..90985c08fe7f8 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -1289,9 +1289,6 @@ static void runThinLTOBackend( }; break; default: - Conf.PreCodeGenPassesHook = [](legacy::PassManager &Pm) { - Pm.add(createObjCARCContractPass()); - }; Conf.CGFileType = getCodeGenFileType(Action); break; } diff --git a/clang/test/CodeGen/thinlto-distributed-objc-contract-pass.ll b/clang/test/CodeGen/thinlto-distributed-objc-contract-pass.ll index 7d0247555b5c8..a2a7b62cb7f93 100644 --- a/clang/test/CodeGen/thinlto-distributed-objc-contract-pass.ll +++ b/clang/test/CodeGen/thinlto-distributed-objc-contract-pass.ll @@ -12,7 +12,7 @@ target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16 target triple = "x86_64-apple-darwin" define void @use_arc(ptr %a, ptr %b) { - call void (...) @llvm.objc.clang.arc.use(i8* %a, i8* %b) nounwind + call void (...) @llvm.objc.clang.arc.use(ptr %a, ptr %b) nounwind ret void } diff --git a/lld/MachO/LTO.cpp b/lld/MachO/LTO.cpp index 7a9a9223a0322..6527cbb68f249 100644 --- a/lld/MachO/LTO.cpp +++ b/lld/MachO/LTO.cpp @@ -48,9 +48,6 @@ static lto::Config createConfig() { c.CPU = getCPUStr(); c.MAttrs = getMAttrs(); c.DiagHandler = diagnosticHandler; - c.PreCodeGenPassesHook = [](legacy::PassManager &pm) { - pm.add(createObjCARCContractPass()); - }; c.AlwaysEmitRegularLTOObj = !config->ltoObjPath.empty(); diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp index d4b89ede2d713..aef3a7575dfdf 100644 --- a/llvm/lib/LTO/LTOBackend.cpp +++ b/llvm/lib/LTO/LTOBackend.cpp @@ -42,6 +42,7 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/TargetParser/SubtargetFeature.h" #include "llvm/Transforms/IPO/WholeProgramDevirt.h" +#include "llvm/Transforms/ObjCARC.h" #include "llvm/Transforms/Scalar/LoopPassManager.h" #include "llvm/Transforms/Utils/FunctionImportUtils.h" #include "llvm/Transforms/Utils/SplitModule.h" @@ -415,6 +416,7 @@ static void codegen(const Config &Conf, TargetMachine *TM, CodeGenPasses.add(new TargetLibraryInfoWrapperPass(TLII)); CodeGenPasses.add( createImmutableModuleSummaryIndexWrapperPass(&CombinedIndex)); + CodeGenPasses.add(createObjCARCContractPass()); if (Conf.PreCodeGenPassesHook) Conf.PreCodeGenPassesHook(CodeGenPasses); if (TM->addPassesToEmitFile(CodeGenPasses, *Stream->OS, >From 336c4709d44b4d5b716ecc12033a410dfea3d364 Mon Sep 17 00:00:00 2001 From: Nuri Amari <nuriam...@fb.com> Date: Mon, 20 May 2024 14:44:16 -0700 Subject: [PATCH 3/3] PR Feedback #2 - Include Pass in default codegen pipeline - Delete all other places the pass is added - Bail early if no arc Intrinsics are found in the module --- clang/lib/CodeGen/BackendUtil.cpp | 6 ------ llvm/include/llvm/IR/Intrinsics.h | 10 ++++++++++ llvm/lib/CodeGen/TargetPassConfig.cpp | 3 +++ llvm/lib/IR/Function.cpp | 5 +++++ llvm/lib/LTO/LTOBackend.cpp | 1 - llvm/lib/LTO/LTOCodeGenerator.cpp | 4 ---- llvm/lib/LTO/ThinLTOCodeGenerator.cpp | 4 ---- llvm/lib/Transforms/ObjCARC/ARCRuntimeEntryPoints.h | 13 +++++++++++++ llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp | 9 +++++++++ 9 files changed, 40 insertions(+), 15 deletions(-) diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 90985c08fe7f8..1f778099a48c1 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -587,12 +587,6 @@ bool EmitAssemblyHelper::AddEmitPasses(legacy::PassManager &CodeGenPasses, // this also adds codegenerator level optimization passes. CodeGenFileType CGFT = getCodeGenFileType(Action); - // Add ObjC ARC final-cleanup optimizations. This is done as part of the - // "codegen" passes so that it isn't run multiple times when there is - // inlining happening. - if (CodeGenOpts.OptimizationLevel > 0) - CodeGenPasses.add(createObjCARCContractPass()); - if (TM->addPassesToEmitFile(CodeGenPasses, OS, DwoOS, CGFT, /*DisableVerify=*/!CodeGenOpts.VerifyModule)) { Diags.Report(diag::err_fe_unable_to_interface_with_target); diff --git a/llvm/include/llvm/IR/Intrinsics.h b/llvm/include/llvm/IR/Intrinsics.h index f79df522dc805..c4131c7671088 100644 --- a/llvm/include/llvm/IR/Intrinsics.h +++ b/llvm/include/llvm/IR/Intrinsics.h @@ -82,6 +82,16 @@ namespace Intrinsic { /// Return the attributes for an intrinsic. AttributeList getAttributes(LLVMContext &C, ID id); + /// Lookup a LLVM Function declaration for an intrinsic, returning it if + /// found in Module M. + /// + /// The Tys parameter is for intrinsics with overloaded types (e.g., those + /// using iAny, fAny, vAny, or iPTRAny). For a declaration of an overloaded + /// intrinsic, Tys must provide exactly one type for each overloaded type in + /// the intrinsic. + Function *lookupDeclaration(Module *M, ID id, + ArrayRef<Type *> Tys = std::nullopt); + /// Create or insert an LLVM Function declaration for an intrinsic, and return /// it. /// diff --git a/llvm/lib/CodeGen/TargetPassConfig.cpp b/llvm/lib/CodeGen/TargetPassConfig.cpp index 8832b51333d91..bc868d468ac50 100644 --- a/llvm/lib/CodeGen/TargetPassConfig.cpp +++ b/llvm/lib/CodeGen/TargetPassConfig.cpp @@ -46,6 +46,7 @@ #include "llvm/Support/WithColor.h" #include "llvm/Target/CGPassBuilderOption.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/Transforms/ObjCARC.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils.h" #include <cassert> @@ -946,6 +947,8 @@ void TargetPassConfig::addCodeGenPrepare() { void TargetPassConfig::addISelPrepare() { addPreISel(); + addPass(createObjCARCContractPass()); + // Force codegen to run according to the callgraph. if (requiresCodeGenSCCOrder()) addPass(new DummyCGSCCPass); diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp index bd06ff82a15a5..7feb352176b2c 100644 --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -1466,6 +1466,11 @@ bool Intrinsic::isOverloaded(ID id) { #include "llvm/IR/IntrinsicImpl.inc" #undef GET_INTRINSIC_ATTRIBUTES +Function *Intrinsic::lookupDeclaration(Module *M, ID id, ArrayRef<Type *> Tys) { + auto *FT = getType(M->getContext(), id, Tys); + return M->getFunction(Tys.empty() ? getName(id) : getName(id, Tys, M, FT)); +} + Function *Intrinsic::getDeclaration(Module *M, ID id, ArrayRef<Type*> Tys) { // There can never be multiple globals with the same name of different types, // because intrinsics must be a specific type. diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp index aef3a7575dfdf..3beb8acf9bede 100644 --- a/llvm/lib/LTO/LTOBackend.cpp +++ b/llvm/lib/LTO/LTOBackend.cpp @@ -416,7 +416,6 @@ static void codegen(const Config &Conf, TargetMachine *TM, CodeGenPasses.add(new TargetLibraryInfoWrapperPass(TLII)); CodeGenPasses.add( createImmutableModuleSummaryIndexWrapperPass(&CombinedIndex)); - CodeGenPasses.add(createObjCARCContractPass()); if (Conf.PreCodeGenPassesHook) Conf.PreCodeGenPassesHook(CodeGenPasses); if (TM->addPassesToEmitFile(CodeGenPasses, *Stream->OS, diff --git a/llvm/lib/LTO/LTOCodeGenerator.cpp b/llvm/lib/LTO/LTOCodeGenerator.cpp index 0611099c4690d..4e928ae5cc303 100644 --- a/llvm/lib/LTO/LTOCodeGenerator.cpp +++ b/llvm/lib/LTO/LTOCodeGenerator.cpp @@ -137,10 +137,6 @@ LTOCodeGenerator::LTOCodeGenerator(LLVMContext &Context) Config.CodeModel = std::nullopt; Config.StatsFile = LTOStatsFile; - Config.PreCodeGenPassesHook = [](legacy::PassManager &PM) { - PM.add(createObjCARCContractPass()); - }; - Config.RunCSIRInstr = LTORunCSIRInstr; Config.CSIRProfile = LTOCSIRProfile; } diff --git a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp index 8f517eb50dc76..1bf23bf665c86 100644 --- a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp +++ b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp @@ -334,10 +334,6 @@ std::unique_ptr<MemoryBuffer> codegenModule(Module &TheModule, raw_svector_ostream OS(OutputBuffer); legacy::PassManager PM; - // If the bitcode files contain ARC code and were compiled with optimization, - // the ObjCARCContractPass must be run, so do it unconditionally here. - PM.add(createObjCARCContractPass()); - // Setup the codegen now. if (TM.addPassesToEmitFile(PM, OS, nullptr, CodeGenFileType::ObjectFile, /* DisableVerify */ true)) diff --git a/llvm/lib/Transforms/ObjCARC/ARCRuntimeEntryPoints.h b/llvm/lib/Transforms/ObjCARC/ARCRuntimeEntryPoints.h index c11691c613ac7..aa3167eaa1105 100644 --- a/llvm/lib/Transforms/ObjCARC/ARCRuntimeEntryPoints.h +++ b/llvm/lib/Transforms/ObjCARC/ARCRuntimeEntryPoints.h @@ -101,6 +101,19 @@ class ARCRuntimeEntryPoints { llvm_unreachable("Switch should be a covered switch."); } + bool moduleContainsARCEntryPoints() { + assert(TheModule != nullptr && "Not initialized."); + + for (auto ARCInstricID : + enum_seq_inclusive(Intrinsic::objc_arc_annotation_bottomup_bbend, + Intrinsic::objc_unsafeClaimAutoreleasedReturnValue, + force_iteration_on_noniterable_enum)) { + if (Intrinsic::lookupDeclaration(TheModule, ARCInstricID)) + return true; + } + return false; + } + private: /// Cached reference to the module which we will insert declarations into. Module *TheModule = nullptr; diff --git a/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp b/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp index 0d0f5c72928ab..01f3fa06ecbdd 100644 --- a/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp +++ b/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp @@ -97,6 +97,7 @@ class ObjCARCContract { public: bool init(Module &M); + bool moduleUsesARCIntrinsics(); bool run(Function &F, AAResults *AA, DominatorTree *DT); bool hasCFGChanged() const { return CFGChanged; } }; @@ -535,6 +536,10 @@ bool ObjCARCContract::init(Module &M) { return false; } +bool ObjCARCContract::moduleUsesARCIntrinsics() { + return EP.moduleContainsARCEntryPoints(); +} + bool ObjCARCContract::run(Function &F, AAResults *A, DominatorTree *D) { if (!EnableARCOpts) return false; @@ -739,6 +744,8 @@ Pass *llvm::createObjCARCContractPass() { bool ObjCARCContractLegacyPass::runOnFunction(Function &F) { ObjCARCContract OCARCC; OCARCC.init(*F.getParent()); + if (!OCARCC.moduleUsesARCIntrinsics()) + return false; auto *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults(); auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); return OCARCC.run(F, AA, DT); @@ -748,6 +755,8 @@ PreservedAnalyses ObjCARCContractPass::run(Function &F, FunctionAnalysisManager &AM) { ObjCARCContract OCAC; OCAC.init(*F.getParent()); + if (!OCAC.moduleUsesARCIntrinsics()) + return PreservedAnalyses::all(); bool Changed = OCAC.run(F, &AM.getResult<AAManager>(F), &AM.getResult<DominatorTreeAnalysis>(F)); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits