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;
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);
#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;
c.CodeModel = getCodeModelFromCMModel();
c.CPU = getCPUStr();
c.MAttrs = getMAttrs();
+ c.UseNewPM = config->ltoNewPassManager;
+ c.PreCodeGenPassesHook = [](legacy::PassManager &pm) {
+ pm.add(createObjCARCContractPass());
+ };
return c;
}
def version: Flag<["--"], "version">,
HelpText<"Display the version number and exit">,
Group<grp_lld>;
+def lto_legacy_pass_manager: Flag<["--"], "lto-legacy-pass-manager">,
+ HelpText<"Use the legacy pass manager in LLVM">,
+ Group<grp_lld>;
+def no_lto_legacy_pass_manager : Flag<["--"], "no-lto-legacy-pass-manager">,
+ HelpText<"Use the new pass manager in LLVM">,
+ Group<grp_lld>;
// This is a complete Options.td compiled from Apple's ld(1) manpage
--- /dev/null
+; 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
#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"
TargetOptions Options;
std::vector<std::string> MAttrs;
std::vector<std::string> PassPlugins;
+ /// For adding passes that run right before codegen.
+ std::function<void(legacy::PassManager &)> PreCodeGenPassesHook;
Optional<Reloc::Model> RelocModel = Reloc::PIC_;
Optional<CodeModel::Model> CodeModel = None;
CodeGenOpt::Level CGOptLevel = CodeGenOpt::Default;
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))