Skip to content

Commit 27132b4

Browse files
committed
make lto a build param
1 parent bd7b07c commit 27132b4

File tree

6 files changed

+85
-51
lines changed

6 files changed

+85
-51
lines changed

Sources/Build/BuildDescription/ClangTargetBuildDescription.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,17 @@ public final class ClangTargetBuildDescription {
293293
// User arguments (from -Xcxx) should follow generated arguments to allow user overrides
294294
args += self.buildParameters.flags.cxxCompilerFlags
295295
}
296+
297+
// Enable the correct lto mode if requested.
298+
switch self.buildParameters.linkTimeOptimizationMode {
299+
case nil:
300+
break
301+
case .full:
302+
args += ["-flto=full"]
303+
case .thin:
304+
args += ["-flto=thin"]
305+
}
306+
296307
return args
297308
}
298309

Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift

Lines changed: 35 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -74,54 +74,24 @@ public final class SwiftTargetBuildDescription {
7474
self.target.sources.paths + self.derivedSources.paths + self.pluginDerivedSources.paths
7575
}
7676

77-
/// The list of all source files in the target, including the derived ones.
78-
private var relativeSources: [RelativePath] {
79-
self.target.sources.relativePaths + self.derivedSources.relativePaths + self
80-
.pluginDerivedSources.relativePaths
81-
}
82-
8377
/// The list of all resource files in the target, including the derived ones.
8478
public var resources: [Resource] {
8579
self.target.underlyingTarget.resources + self.pluginDerivedResources
8680
}
8781

88-
private var producesBitcodeObjects: Bool {
89-
get throws {
90-
try self.compileArguments().contains {
91-
// Using -lto=x will result in bitcode generation.
92-
$0.hasPrefix("-lto=")
93-
// Using -embed-bitcode will result in bitcode generation.
94-
|| $0 == "-embed-bitcode"
95-
}
96-
}
97-
}
98-
9982
/// The objects in this target, containing either machine code or bitcode
100-
/// depending on the compiler flags used.
83+
/// depending on the build parameters used.
10184
public var objects: [AbsolutePath] {
10285
get throws {
103-
// Prefer bitcode objects over machine code objects if they are
104-
// produced.
105-
try self.producesBitcodeObjects
106-
? self.bitcodeObjects
107-
: self.machineCodeObjects
108-
}
109-
}
110-
111-
/// The machine code objects in this target.
112-
private var machineCodeObjects: [AbsolutePath] {
113-
get throws {
114-
try self.relativeSources.map {
115-
try AbsolutePath(validating: "\($0.pathString).o", relativeTo: tempsPath)
116-
}
117-
}
118-
}
119-
120-
/// The bitcode objects in this target.
121-
private var bitcodeObjects: [AbsolutePath] {
122-
get throws {
123-
try self.relativeSources.map {
124-
try AbsolutePath(validating: "\($0.pathString).bc", relativeTo: tempsPath)
86+
let relativeSources = self.target.sources.relativePaths
87+
+ self.derivedSources.relativePaths
88+
+ self.pluginDerivedSources.relativePaths
89+
let ltoEnabled = self.buildParameters.linkTimeOptimizationMode != nil
90+
let objectFileExtension = ltoEnabled ? "bc" : "o"
91+
return try relativeSources.map {
92+
try AbsolutePath(
93+
validating: "\($0.pathString).\(objectFileExtension)",
94+
relativeTo: self.tempsPath)
12595
}
12696
}
12797
}
@@ -548,6 +518,16 @@ public final class SwiftTargetBuildDescription {
548518
// // User arguments (from -Xcxx) should follow generated arguments to allow user overrides
549519
// args += self.buildParameters.flags.cxxCompilerFlags.asSwiftcCXXCompilerFlags()
550520

521+
// Enable the correct lto mode if requested.
522+
switch self.buildParameters.linkTimeOptimizationMode {
523+
case nil:
524+
break
525+
case .full:
526+
args += ["-lto=llvm-full"]
527+
case .thin:
528+
args += ["-lto=llvm-thin"]
529+
}
530+
551531
// suppress warnings if the package is remote
552532
if self.package.isRemote {
553533
args += ["-suppress-warnings"]
@@ -716,6 +696,16 @@ public final class SwiftTargetBuildDescription {
716696
// // User arguments (from -Xcxx) should follow generated arguments to allow user overrides
717697
// result += self.buildParameters.flags.cxxCompilerFlags.asSwiftcCXXCompilerFlags()
718698

699+
// Enable the correct lto mode if requested.
700+
switch self.buildParameters.linkTimeOptimizationMode {
701+
case nil:
702+
break
703+
case .full:
704+
result += ["-lto=llvm-full"]
705+
case .thin:
706+
result += ["-lto=llvm-thin"]
707+
}
708+
719709
result += try self.macroArguments()
720710
return result
721711
}
@@ -766,13 +756,13 @@ public final class SwiftTargetBuildDescription {
766756

767757
// Write out the entries for each source file.
768758
let sources = self.sources
769-
let machineCodeObjects = try self.machineCodeObjects
770-
let bitcodeObjects = try self.bitcodeObjects
759+
let objects = try self.objects
760+
let ltoEnabled = self.buildParameters.linkTimeOptimizationMode != nil
761+
let objectKey = ltoEnabled ? "llvm-bc" : "object"
771762

772763
for idx in 0..<sources.count {
773764
let source = sources[idx]
774-
let machineCodeObject = machineCodeObjects[idx]
775-
let bitcodeObject = bitcodeObjects[idx]
765+
let object = objects[idx]
776766

777767
let sourceFileName = source.basenameWithoutExt
778768
let partialModulePath = self.tempsPath.appending(component: sourceFileName + "~partial.swiftmodule")
@@ -794,11 +784,9 @@ public final class SwiftTargetBuildDescription {
794784
// FIXME: Need to record this deps file for processing it later.
795785
}
796786

797-
798787
content +=
799788
#"""
800-
"object": "\#(machineCodeObject._nativePathString(escaped: true))",
801-
"llvm-bc": "\#(bitcodeObject._nativePathString(escaped: true))",
789+
"\#(objectKey)": "\#(object._nativePathString(escaped: true))",
802790
"swiftmodule": "\#(partialModulePath._nativePathString(escaped: true))",
803791
"swift-dependencies": "\#(swiftDepsPath._nativePathString(escaped: true))"
804792
}\#((idx + 1) < sources.count ? "," : "")

Sources/CoreCommands/Options.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,13 @@ public struct BuildOptions: ParsableArguments {
470470
)
471471
public var testEntryPointPath: AbsolutePath?
472472

473+
/// The lto mode to use if any.
474+
@Option(
475+
name: .customLong("experimental-lto-mode"),
476+
help: .hidden
477+
)
478+
public var linkTimeOptimizationMode: LinkTimeOptimizationMode?
479+
473480
// @Flag works best when there is a default value present
474481
// if true, false aren't enough and a third state is needed
475482
// nil should not be the goto. Instead create an enum
@@ -484,6 +491,11 @@ public struct BuildOptions: ParsableArguments {
484491
case warn
485492
case error
486493
}
494+
495+
public enum LinkTimeOptimizationMode: String, Codable, ExpressibleByArgument {
496+
case full
497+
case thin
498+
}
487499
}
488500

489501
public struct LinkerOptions: ParsableArguments {

Sources/CoreCommands/SwiftTool.swift

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -703,7 +703,8 @@ public final class SwiftTool {
703703
testEntryPointPath: options.build.testEntryPointPath,
704704
explicitTargetDependencyImportCheckingMode: options.build.explicitTargetDependencyImportCheck.modeParameter,
705705
linkerDeadStrip: options.linker.linkerDeadStrip,
706-
verboseOutput: self.logLevel <= .info
706+
verboseOutput: self.logLevel <= .info,
707+
linkTimeOptimizationMode: options.build.linkTimeOptimizationMode?.buildParameter
707708
)
708709
})
709710
}()
@@ -966,6 +967,17 @@ extension BuildOptions.TargetDependencyImportCheckingMode {
966967
}
967968
}
968969

970+
extension BuildOptions.LinkTimeOptimizationMode {
971+
fileprivate var buildParameter: BuildParameters.LinkTimeOptimizationMode? {
972+
switch self {
973+
case .full:
974+
return .full
975+
case .thin:
976+
return .thin
977+
}
978+
}
979+
}
980+
969981
extension Basics.Diagnostic {
970982
public static func mutuallyExclusiveArgumentsError(arguments: [String]) -> Self {
971983
.error(arguments.map { "'\($0)'" }.spm_localizedJoin(type: .conjunction) + " are mutually exclusive")

Sources/SPMBuildCore/BuildParameters.swift

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ public struct BuildParameters: Encodable {
2626
case auto
2727
}
2828

29+
public enum LinkTimeOptimizationMode: String, Encodable {
30+
case full = "llvm-full"
31+
case thin = "llvm-thin"
32+
}
33+
2934
/// Represents the debugging strategy.
3035
///
3136
/// Swift binaries requires the swiftmodule files in order for lldb to work.
@@ -219,6 +224,8 @@ public struct BuildParameters: Encodable {
219224

220225
public var verboseOutput: Bool
221226

227+
public var linkTimeOptimizationMode: LinkTimeOptimizationMode?
228+
222229
public init(
223230
dataPath: AbsolutePath,
224231
configuration: BuildConfiguration,
@@ -247,7 +254,8 @@ public struct BuildParameters: Encodable {
247254
explicitTargetDependencyImportCheckingMode: TargetDependencyImportCheckingMode = .none,
248255
linkerDeadStrip: Bool = true,
249256
colorizedOutput: Bool = false,
250-
verboseOutput: Bool = false
257+
verboseOutput: Bool = false,
258+
linkTimeOptimizationMode: LinkTimeOptimizationMode?
251259
) throws {
252260
let triple = try destinationTriple ?? .getHostTriple(usingSwiftCompiler: toolchain.swiftCompilerPath)
253261

@@ -288,6 +296,7 @@ public struct BuildParameters: Encodable {
288296
self.linkerDeadStrip = linkerDeadStrip
289297
self.colorizedOutput = colorizedOutput
290298
self.verboseOutput = verboseOutput
299+
self.linkTimeOptimizationMode = linkTimeOptimizationMode
291300
}
292301

293302
public func withDestination(_ destinationTriple: Triple) throws -> BuildParameters {
@@ -330,7 +339,8 @@ public struct BuildParameters: Encodable {
330339
explicitTargetDependencyImportCheckingMode: self.explicitTargetDependencyImportCheckingMode,
331340
linkerDeadStrip: self.linkerDeadStrip,
332341
colorizedOutput: self.colorizedOutput,
333-
verboseOutput: self.verboseOutput
342+
verboseOutput: self.verboseOutput,
343+
linkTimeOptimizationMode: self.linkTimeOptimizationMode
334344
)
335345
}
336346

Tests/BuildTests/MockBuildTestHelper.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ func mockBuildParameters(
8787
canRenameEntrypointFunctionName: canRenameEntrypointFunctionName,
8888
indexStoreMode: indexStoreMode,
8989
useExplicitModuleBuild: useExplicitModuleBuild,
90-
linkerDeadStrip: linkerDeadStrip
90+
linkerDeadStrip: linkerDeadStrip,
91+
linkTimeOptimizationMode: nil
9192
)
9293
}
9394

0 commit comments

Comments
 (0)