diff --git a/lld/MachO/Config.h b/lld/MachO/Config.h --- a/lld/MachO/Config.h +++ b/lld/MachO/Config.h @@ -47,6 +47,7 @@ bool implicitDylibs = false; bool isPic = false; bool headerPadMaxInstallNames = false; + bool ltoNewPassManager = LLVM_ENABLE_NEW_PASS_MANAGER; bool printEachFile = false; bool printWhyLoad = false; bool searchDylibsFirst = false; diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -733,6 +733,9 @@ config->printWhyLoad = args.hasArg(OPT_why_load); config->outputType = getOutputType(args); config->ltoObjPath = args.getLastArgValue(OPT_object_path_lto); + config->ltoNewPassManager = + args.hasFlag(OPT_no_lto_legacy_pass_manager, OPT_lto_legacy_pass_manager, + LLVM_ENABLE_NEW_PASS_MANAGER); config->runtimePaths = args::getStrings(args, OPT_rpath); config->allLoad = args.hasArg(OPT_all_load); config->forceLoadObjC = args.hasArg(OPT_ObjC); diff --git a/lld/MachO/LTO.cpp b/lld/MachO/LTO.cpp --- a/lld/MachO/LTO.cpp +++ b/lld/MachO/LTO.cpp @@ -18,6 +18,7 @@ #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Transforms/ObjCARC.h" using namespace lld; using namespace lld::macho; @@ -30,6 +31,10 @@ c.CodeModel = getCodeModelFromCMModel(); c.CPU = getCPUStr(); c.MAttrs = getMAttrs(); + c.UseNewPM = config->ltoNewPassManager; + c.PreCodeGenPassesHook = [](legacy::PassManager &pm) { + pm.add(createObjCARCContractPass()); + }; return c; } diff --git a/lld/MachO/Options.td b/lld/MachO/Options.td --- a/lld/MachO/Options.td +++ b/lld/MachO/Options.td @@ -29,6 +29,12 @@ def version: Flag<["--"], "version">, HelpText<"Display the version number and exit">, Group; +def lto_legacy_pass_manager: Flag<["--"], "lto-legacy-pass-manager">, + HelpText<"Use the legacy pass manager in LLVM">, + Group; +def no_lto_legacy_pass_manager : Flag<["--"], "no-lto-legacy-pass-manager">, + HelpText<"Use the new pass manager in LLVM">, + Group; // This is a complete Options.td compiled from Apple's ld(1) manpage diff --git a/lld/test/MachO/objc-arc-contract.ll b/lld/test/MachO/objc-arc-contract.ll new file mode 100644 --- /dev/null +++ b/lld/test/MachO/objc-arc-contract.ll @@ -0,0 +1,30 @@ +; REQUIRES: x86 + +;; Verify that we run the ObjCARCContractPass during LTO. Without that, the +;; objc.clang.arc.use intrinsic will get passed to the instruction selector, +;; which doesn't know how to handle it. + +; RUN: llvm-as %s -o %t.o +; RUN: %lld -dylib -lSystem %t.o -o %t --lto-legacy-pass-manager +; RUN: llvm-objdump -d %t | FileCheck %s +; RUN: %lld -dylib -lSystem %t.o -o %t --no-lto-legacy-pass-manager +; RUN: llvm-objdump -d %t | FileCheck %s + +; RUN: opt -module-summary %s -o %t.o +; RUN: %lld -dylib -lSystem %t.o -o %t --lto-legacy-pass-manager +; RUN: llvm-objdump -d %t | FileCheck %s +; RUN: %lld -dylib -lSystem %t.o -o %t --no-lto-legacy-pass-manager +; RUN: llvm-objdump -d %t | FileCheck %s + +; CHECK: <_foo>: +; CHECK-NEXT: retq + +target triple = "x86_64-apple-darwin" +target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + +define void @foo(i8* %a, i8* %b) { + call void (...) @llvm.objc.clang.arc.use(i8* %a, i8* %b) nounwind + ret void +} + +declare void @llvm.objc.clang.arc.use(...) nounwind diff --git a/llvm/include/llvm/LTO/Config.h b/llvm/include/llvm/LTO/Config.h --- a/llvm/include/llvm/LTO/Config.h +++ b/llvm/include/llvm/LTO/Config.h @@ -19,6 +19,7 @@ #include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/GlobalValue.h" #include "llvm/IR/LLVMContext.h" +#include "llvm/IR/LegacyPassManager.h" #include "llvm/Passes/PassBuilder.h" #include "llvm/Support/CodeGen.h" #include "llvm/Target/TargetOptions.h" @@ -43,6 +44,8 @@ TargetOptions Options; std::vector MAttrs; std::vector PassPlugins; + /// For adding passes that run right before codegen. + std::function PreCodeGenPassesHook; Optional RelocModel = Reloc::PIC_; Optional CodeModel = None; CodeGenOpt::Level CGOptLevel = CodeGenOpt::Default; diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp --- a/llvm/lib/LTO/LTOBackend.cpp +++ b/llvm/lib/LTO/LTOBackend.cpp @@ -428,6 +428,8 @@ legacy::PassManager CodeGenPasses; CodeGenPasses.add( createImmutableModuleSummaryIndexWrapperPass(&CombinedIndex)); + if (Conf.PreCodeGenPassesHook) + Conf.PreCodeGenPassesHook(CodeGenPasses); if (TM->addPassesToEmitFile(CodeGenPasses, *Stream->OS, DwoOut ? &DwoOut->os() : nullptr, Conf.CGFileType))