Skip to content

Commit ba58cfd

Browse files
committed
Expand printActions to match C++ drivers more complex cases
Fixes: Driver/actions.swift Driver/actions-dsym.swift
1 parent 6bede3a commit ba58cfd

File tree

1 file changed

+64
-9
lines changed

1 file changed

+64
-9
lines changed

Sources/SwiftDriver/Driver/Driver.swift

Lines changed: 64 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -825,7 +825,7 @@ extension Driver {
825825
// Print actions using the same style as the old C++ driver
826826
// This is mostly for testing purposes. We should print semantically
827827
// equivalent actions as the old driver.
828-
Driver.printActions(jobs)
828+
Driver.printActions(jobs, inputs: inputFiles)
829829
return
830830
}
831831

@@ -915,7 +915,12 @@ extension Driver {
915915
stdoutStream.flush()
916916
}
917917

918-
private static func printActions(_ jobs: [Job]) {
918+
/// This handles -driver-print-actions flag. The C++ driver has a concept of actions
919+
/// which it builds up a list of actions before then creating them into jobs.
920+
/// The swift-driver doesn't have actions, so the logic here takes the jobs and tries
921+
/// to mimic the actions that would be created by the C++ driver and
922+
/// prints them in *hopefully* the same order.
923+
private static func printActions(_ jobs: [Job], inputs allInputs: [TypedVirtualPath]) {
919924
defer {
920925
stdoutStream.flush()
921926
}
@@ -927,25 +932,66 @@ extension Driver {
927932
for job in jobs {
928933
// All input action IDs for this action.
929934
var inputIds = Set<UInt>()
930-
// Collect input job IDs.
935+
// Collect input job IDs and parsed inputs.
936+
var inputsToFind = Set<TypedVirtualPath>()
937+
var foundInputFromPreviousJobOutput = false
931938
for input in job.displayInputs.isEmpty ? job.inputs : job.displayInputs {
939+
if let id = inputIdMap[input] {
940+
inputIds.insert(id)
941+
continue
942+
}
932943
var foundInput = false
933944
for (prevJob, id) in jobIdMap {
934945
if prevJob.outputs.contains(input) {
935946
foundInput = true
947+
foundInputFromPreviousJobOutput = true
936948
inputIds.insert(id)
949+
break
937950
}
938951
}
939952
if (!foundInput) {
940-
if inputIdMap[input] == nil {
941-
stdoutStream <<< nextId <<< ": " <<< "input, "
942-
stdoutStream <<< "\"" <<< input.file <<< "\", " <<< input.type <<< "\n"
943-
inputIdMap[input] = nextId
944-
nextId += 1
953+
inputsToFind.insert(input)
954+
}
955+
}
956+
// Print inputs until we have found enough to satisfy the job
957+
// Additionally if this job contains inputs that were outputs of previous job
958+
// finish printing all the inputs. The C++ will print all inputs before printing
959+
// actions that depend on non-input actions.
960+
// --
961+
// Example of driver printing inputs in order even if they aren't needed until later.
962+
// Here 0 isn't needed until 6, but it's still printed first.
963+
// swiftc -driver-print-actions a.o b.swift c.o d.swift
964+
// 0: input, "a.o", object
965+
// 1: input, "b.swift", swift
966+
// 2: compile, {1}, object
967+
// 3: input, "c.o", object
968+
// 4: input, "d.swift", swift
969+
// 5: compile, {4}, object
970+
// 6: link, {0, 2, 3, 5}, image
971+
// --
972+
// Example of driver printing inputs before actions that depend on non-input actions.
973+
// If we just printed in job order, 6 would be inserted after 1.
974+
// swiftc -driver-print-actions c.swift a.o b.o a.swiftmodule b.swiftmodule -o main
975+
// 0: input, "c.swift", swift
976+
// 1: compile, {0}, object
977+
// 2: input, "a.o", object
978+
// 3: input, "b.o", object
979+
// 4: input, "a.swiftmodule", swiftmodule
980+
// 5: input, "b.swiftmodule", swiftmodule
981+
// 6: merge-module, {1}, swiftmodule
982+
// 7: link, {1, 2, 3, 4, 5, 6}, image
983+
// 8: generate-dSYM, {7}, dSYM
984+
if !inputsToFind.isEmpty || foundInputFromPreviousJobOutput {
985+
for input in allInputs {
986+
if inputsToFind.isEmpty, !foundInputFromPreviousJobOutput { break }
987+
// If inputsToFind contained input, add the id to the list for the job
988+
if inputsToFind.remove(input) != nil {
989+
inputIds.insert(nextId)
945990
}
946-
inputIds.insert(inputIdMap[input]!)
991+
printInputIfNew(input, inputIdMap: &inputIdMap, nextId: &nextId)
947992
}
948993
}
994+
949995
// Print current Job
950996
stdoutStream <<< nextId <<< ": " <<< job.kind.rawValue <<< ", {"
951997
stdoutStream <<< inputIds.sorted().map({ $0.description })
@@ -960,6 +1006,15 @@ extension Driver {
9601006
}
9611007
}
9621008

1009+
private static func printInputIfNew(_ input: TypedVirtualPath, inputIdMap: inout [TypedVirtualPath: UInt], nextId: inout UInt) {
1010+
if inputIdMap[input] == nil {
1011+
stdoutStream <<< nextId <<< ": " <<< "input, "
1012+
stdoutStream <<< "\"" <<< input.file <<< "\", " <<< input.type <<< "\n"
1013+
inputIdMap[input] = nextId
1014+
nextId += 1
1015+
}
1016+
}
1017+
9631018
private func printVersion<S: OutputByteStream>(outputStream: inout S) throws {
9641019
outputStream <<< frontendTargetInfo.compilerVersion <<< "\n"
9651020
outputStream <<< "Target: \(frontendTargetInfo.target.triple.triple)\n"

0 commit comments

Comments
 (0)