Index: lld/MachO/Config.h =================================================================== --- lld/MachO/Config.h +++ lld/MachO/Config.h @@ -126,6 +126,7 @@ llvm::StringRef outputFile; llvm::StringRef ltoObjPath; llvm::StringRef thinLTOJobs; + uint32_t ltoo = 2; bool deadStripDylibs = false; bool demangle = false; bool deadStrip = false; Index: lld/MachO/Driver.cpp =================================================================== --- lld/MachO/Driver.cpp +++ lld/MachO/Driver.cpp @@ -1068,6 +1068,9 @@ config->ltoNewPassManager = args.hasFlag(OPT_no_lto_legacy_pass_manager, OPT_lto_legacy_pass_manager, LLVM_ENABLE_NEW_PASS_MANAGER); + config->ltoo = args::getInteger(args, OPT_lto_O, 2); + if (config->ltoo > 3) + error("--lto-O: invalid optimization level: " + Twine(config->ltoo)); config->runtimePaths = args::getStrings(args, OPT_rpath); config->allLoad = args.hasArg(OPT_all_load); config->forceLoadObjC = args.hasArg(OPT_ObjC); Index: lld/MachO/LTO.cpp =================================================================== --- lld/MachO/LTO.cpp +++ lld/MachO/LTO.cpp @@ -13,6 +13,7 @@ #include "Symbols.h" #include "Target.h" +#include "lld/Common/Args.h" #include "lld/Common/ErrorHandler.h" #include "lld/Common/Strings.h" #include "lld/Common/TargetOptionsCommandFlags.h" @@ -40,6 +41,8 @@ }; c.TimeTraceEnabled = config->timeTraceEnabled; c.TimeTraceGranularity = config->timeTraceGranularity; + c.OptLevel = config->ltoo; + c.CGOptLevel = args::getCGOptLevel(config->ltoo); if (config->saveTemps) checkError(c.addSaveTemps(config->outputFile.str() + ".", /*UseInputModulePath=*/true)); Index: lld/MachO/Options.td =================================================================== --- lld/MachO/Options.td +++ lld/MachO/Options.td @@ -64,6 +64,10 @@ HelpText<"Set level for identical code folding (default: none)">, MetaVarName<"[none,safe,all]">, Group; +def lto_O: Joined<["--"], "lto-O">, + HelpText<"Set optimization level for LTO (default: 2)">, + MetaVarName<"">, + Group; // This is a complete Options.td compiled from Apple's ld(1) manpage // dated 2018-03-07 and cross checked with ld64 source code in repo Index: lld/test/MachO/lto-opt-level.ll =================================================================== --- /dev/null +++ lld/test/MachO/lto-opt-level.ll @@ -0,0 +1,28 @@ +; REQUIRES: x86 + +; RUN: rm -rf %t; mkdir %t +; RUN: llvm-as %s -o %t/test.o + +; RUN: %lld %t/test.o --lto-O0 -o %t/test +; RUN: llvm-nm -pa %t/test | FileCheck %s --check-prefixes=CHECK-O0 + +; RUN: %lld %t/test.o --lto-O2 -o %t/test +; RUN: llvm-nm -pa %t/test | FileCheck %s --check-prefixes=CHECK-O2 + +; RUN: %lld %t/test.o -o %t/test +; RUN: llvm-nm -pa %t/test | FileCheck %s --check-prefixes=CHECK-O2 + +; CHECK-O0: foo +; CHECK-O2-NOT: foo + +target triple = "x86_64-apple-macosx10.15.0" +target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + +define internal void @foo() { + ret void +} + +define void @main() { + call void @foo() + ret void +}