Skip to content

Commit 8f65324

Browse files
committed
Explicitly tell the frontend to enable default cross-module-optimization
So far, the swift-frontend decided by itself if CMO can be enabled. This caused problems when used with an old driver, which doesn't consider CMO. Now, the driver decides when to use default CMO.
1 parent ecdc811 commit 8f65324

File tree

4 files changed

+27
-16
lines changed

4 files changed

+27
-16
lines changed

Sources/SwiftDriver/Jobs/CompileJob.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,13 @@ extension Driver {
283283
try addCommonFrontendOptions(commandLine: &commandLine, inputs: &inputs)
284284
// FIXME: MSVC runtime flags
285285

286-
addDisableCMOOption(commandLine: &commandLine)
286+
if Driver.canDoCrossModuleOptimization(parsedOptions: &parsedOptions) &&
287+
// For historical reasons, -cross-module-optimization turns on "aggressive" CMO
288+
// which is different from "default" CMO.
289+
!parsedOptions.hasArgument(.CrossModuleOptimization) {
290+
assert(!emitModuleSeparately, "Cannot emit module separately with cross-module-optimization")
291+
commandLine.appendFlag("-enable-default-cmo")
292+
}
287293

288294
if parsedOptions.hasArgument(.parseAsLibrary, .emitLibrary) {
289295
commandLine.appendFlag(.parseAsLibrary)

Sources/SwiftDriver/Jobs/EmitModuleJob.swift

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,6 @@ extension Driver {
9999

100100
addCommonModuleOptions(commandLine: &commandLine, outputs: &outputs, isMergeModule: false)
101101

102-
addDisableCMOOption(commandLine: &commandLine)
103-
104102
try commandLine.appendLast(.emitSymbolGraph, from: &parsedOptions)
105103
try commandLine.appendLast(.emitSymbolGraphDir, from: &parsedOptions)
106104
try commandLine.appendLast(.includeSpiSymbols, from: &parsedOptions)
@@ -147,10 +145,9 @@ extension Driver {
147145
default: true)
148146

149147
case .singleCompile:
150-
// Non library-evolution builds require a single job, because cross-module-optimization is enabled by default.
151-
if !parsedOptions.hasArgument(.enableLibraryEvolution),
152-
!parsedOptions.hasArgument(.disableCrossModuleOptimization),
153-
let opt = parsedOptions.getLast(in: .O), opt.option != .Onone {
148+
// If cross-module-optimization is done, the module must be emitted in the same
149+
// swift-frontend invocation which also produces the binary.
150+
if canDoCrossModuleOptimization(parsedOptions: &parsedOptions) {
154151
return false
155152
}
156153

@@ -163,4 +160,13 @@ extension Driver {
163160
return false
164161
}
165162
}
163+
164+
static func canDoCrossModuleOptimization(parsedOptions: inout ParsedOptions) -> Bool {
165+
if !parsedOptions.hasArgument(.enableLibraryEvolution),
166+
!parsedOptions.hasArgument(.disableCrossModuleOptimization),
167+
let opt = parsedOptions.getLast(in: .O), opt.option != .Onone {
168+
return true
169+
}
170+
return false
171+
}
166172
}

Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -315,14 +315,6 @@ extension Driver {
315315
driver: self)
316316
}
317317

318-
/// Add options to disable cross-module-optimization.
319-
mutating func addDisableCMOOption(commandLine: inout [Job.ArgTemplate]) {
320-
if parsedOptions.hasArgument(.disableCrossModuleOptimization) {
321-
commandLine.appendFlag(.Xllvm)
322-
commandLine.appendFlag("-sil-disable-pass=cmo")
323-
}
324-
}
325-
326318
mutating func addFrontendSupplementaryOutputArguments(commandLine: inout [Job.ArgTemplate],
327319
primaryInputs: [TypedVirtualPath],
328320
inputsGeneratingCodeCount: Int,

Tests/SwiftDriverTests/SwiftDriverTests.swift

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2976,31 +2976,38 @@ final class SwiftDriverTests: XCTestCase {
29762976
var driver = try Driver(args: ["swiftc", "foo.swift", "bar.swift", "-module-name", "Test", "-emit-module-path", rebase("Test.swiftmodule", at: root), "-c", "-o", rebase("test.o", at: root), "-wmo", "-O" ])
29772977
let plannedJobs = try driver.planBuild()
29782978
XCTAssertEqual(plannedJobs.count, 1 + autoLinkExtractJob)
2979+
XCTAssertTrue(plannedJobs[0].commandLine.contains(.flag("-enable-default-cmo")))
29792980
}
29802981

29812982
do {
29822983
// library-evolution builds can emit the module in a separate job.
29832984
var driver = try Driver(args: ["swiftc", "foo.swift", "bar.swift", "-module-name", "Test", "-emit-module-path", rebase("Test.swiftmodule", at: root), "-c", "-o", rebase("test.o", at: root), "-wmo", "-O", "-enable-library-evolution" ])
29842985
let plannedJobs = try driver.planBuild()
29852986
XCTAssertEqual(plannedJobs.count, 2 + autoLinkExtractJob)
2987+
XCTAssertFalse(plannedJobs[0].commandLine.contains(.flag("-enable-default-cmo")))
2988+
XCTAssertFalse(plannedJobs[1].commandLine.contains(.flag("-enable-default-cmo")))
29862989
}
29872990

29882991
do {
29892992
// When disabling cross-module-optimization, the module can be emitted in a separate job.
29902993
var driver = try Driver(args: ["swiftc", "foo.swift", "bar.swift", "-module-name", "Test", "-emit-module-path", rebase("Test.swiftmodule", at: root), "-c", "-o", rebase("test.o", at: root), "-wmo", "-O", "-disable-cmo" ])
29912994
let plannedJobs = try driver.planBuild()
29922995
XCTAssertEqual(plannedJobs.count, 2 + autoLinkExtractJob)
2996+
XCTAssertFalse(plannedJobs[0].commandLine.contains(.flag("-enable-default-cmo")))
2997+
XCTAssertFalse(plannedJobs[1].commandLine.contains(.flag("-enable-default-cmo")))
29932998
}
29942999

29953000
do {
29963001
// non optimized builds can emit the module in a separate job.
29973002
var driver = try Driver(args: ["swiftc", "foo.swift", "bar.swift", "-module-name", "Test", "-emit-module-path", rebase("Test.swiftmodule", at: root), "-c", "-o", rebase("test.o", at: root), "-wmo" ])
29983003
let plannedJobs = try driver.planBuild()
29993004
XCTAssertEqual(plannedJobs.count, 2 + autoLinkExtractJob)
3005+
XCTAssertFalse(plannedJobs[0].commandLine.contains(.flag("-enable-default-cmo")))
3006+
XCTAssertFalse(plannedJobs[1].commandLine.contains(.flag("-enable-default-cmo")))
30003007
}
30013008

30023009
do {
3003-
// Don't use emit-module-separetely as a linker.
3010+
// Don't use emit-module-separetely as a linker.
30043011
var driver = try Driver(args: ["swiftc", "foo.sil", "bar.sil", "-module-name", "Test", "-emit-module-path", "/foo/bar/Test.swiftmodule", "-emit-library", "-target", "x86_64-apple-macosx10.15", "-wmo", "-emit-module-separately-wmo"],
30053012
env: envVars)
30063013
let plannedJobs = try driver.planBuild()

0 commit comments

Comments
 (0)