Skip to content

Commit 65b901a

Browse files
committed
Refactor GlobalProductPlan construction into independent, nearly-functional passes
1 parent 0044699 commit 65b901a

File tree

6 files changed

+261
-208
lines changed

6 files changed

+261
-208
lines changed

Sources/SWBTaskConstruction/ProductPlanning/ProductPlan.swift

Lines changed: 240 additions & 187 deletions
Large diffs are not rendered by default.

Sources/SWBTaskConstruction/ProductPlanning/ProductPlanner.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ package struct ProductPlanner
4545
return await planRequest.buildRequestContext.keepAliveSettingsCache {
4646
// Construct the global product plan.
4747
let globalProductPlan = await GlobalProductPlan(planRequest: planRequest, delegate: delegate, nodeCreationDelegate: delegate)
48-
let targetTaskInfos = globalProductPlan.targetTaskInfos
48+
let targetTaskInfos = globalProductPlan.targetGateNodes
4949

5050
// Create the plans themselves in parallel.
5151
var productPlans = await globalProductPlan.allTargets.asyncMap { configuredTarget in
@@ -113,7 +113,7 @@ private struct ProductPlanBuilder
113113

114114

115115
/// Create the product plan.
116-
func createProductPlan(_ targetTaskInfo: TargetTaskInfo, _ globalProductPlan: GlobalProductPlan) async -> ProductPlan
116+
func createProductPlan(_ targetTaskInfo: TargetGateNodes, _ globalProductPlan: GlobalProductPlan) async -> ProductPlan
117117
{
118118
// Create the context object for the task producers.
119119
// FIXME: Either each task producer should get its own file path resolver, or the path resolver's caching logic needs to be thread-safe.

Sources/SWBTaskConstruction/TaskProducers/BuildPhaseTaskProducers/SourcesTaskProducer.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1337,7 +1337,7 @@ package final class SourcesTaskProducer: FilesBasedBuildPhaseTaskProducerBase, F
13371337
let dependencies = context.globalProductPlan.planRequest.buildGraph.dependencies(of: configuredTarget)
13381338
let moduleInputs = dependencies.compactMap { dependency -> (any PlannedNode)? in
13391339
guard dependency !== configuredTarget else { return nil }
1340-
let taskInfo = context.globalProductPlan.targetTaskInfos[dependency]!
1340+
let taskInfo = context.globalProductPlan.targetGateNodes[dependency]!
13411341
if context.globalProductPlan.targetsRequiredToBuildForIndexing.contains(dependency) {
13421342
return taskInfo.endNode
13431343
} else {

Sources/SWBTaskConstruction/TaskProducers/OtherTaskProducers/HeadermapTaskProducer.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ final class HeadermapTaskProducer: PhasedTaskProducer, TaskProducer {
376376

377377
/// Performance testing entry point to headermap construction.
378378
package func perfTestHeadermapProducer(planRequest: BuildPlanRequest, delegate: any TaskPlanningDelegate) async -> [String: [any PlannedTask]] {
379-
let targetTaskInfo = TargetTaskInfo(startNode: MakePlannedPathNode(Path("a")), endNode: MakePlannedPathNode(Path("b")), unsignedProductReadyNode: MakePlannedPathNode(Path("c")), willSignNode: MakePlannedPathNode(Path("d")))
379+
let targetTaskInfo = TargetGateNodes(startNode: MakePlannedPathNode(Path("a")), endNode: MakePlannedPathNode(Path("b")), unsignedProductReadyNode: MakePlannedPathNode(Path("c")), willSignNode: MakePlannedPathNode(Path("d")))
380380
let globalProductPlan = await GlobalProductPlan(planRequest: planRequest, delegate: delegate, nodeCreationDelegate: delegate)
381381
var result = [String: [any PlannedTask]]()
382382
for configuredTarget in planRequest.buildGraph.allTargets {

Sources/SWBTaskConstruction/TaskProducers/OtherTaskProducers/TargetOrderTaskProducer.swift

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import SWBMacro
1717
/// Wrapper for capturing the task information needed for the `TargetOrderTaskProducer`.
1818
///
1919
/// The `GlobalProductPlan` contains a map of `ConfiguredTarget`s to `TargetTaskInfo`s.
20-
final class TargetTaskInfo {
20+
final class TargetGateNodes {
2121
/// A virtual node representing the start of the overall target.
2222
///
2323
/// All tasks in the target depend on this node having been built.
@@ -100,18 +100,18 @@ final class TargetTaskInfo {
100100

101101
/// Task producer for the gate tasks for a single target that are used to enforce the ordering of tasks within and across targets.
102102
final class TargetOrderTaskProducer: StandardTaskProducer, TaskProducer {
103-
let targetTaskInfo: TargetTaskInfo
103+
let targetGateNodes: TargetGateNodes
104104

105105
let targetContext: TargetTaskProducerContext
106106

107-
init(_ context: TargetTaskProducerContext, targetTaskInfo: TargetTaskInfo) {
108-
self.targetTaskInfo = targetTaskInfo
107+
init(_ context: TargetTaskProducerContext, targetTaskInfo: TargetGateNodes) {
108+
self.targetGateNodes = targetTaskInfo
109109
self.targetContext = context
110110
super.init(context)
111111
}
112112

113113
func prepare() async {
114-
if let preparedForIndexModuleNode = targetTaskInfo.preparedForIndexModuleContentNode {
114+
if let preparedForIndexModuleNode = targetGateNodes.preparedForIndexModuleContentNode {
115115
precondition(context.preparedForIndexModuleContentTasks.isEmpty)
116116
await appendGeneratedTasks(&context.preparedForIndexModuleContentTasks) { delegate in
117117
let outputPath = preparedForIndexModuleNode.path
@@ -140,7 +140,7 @@ final class TargetOrderTaskProducer: StandardTaskProducer, TaskProducer {
140140
///
141141
/// It depends on the exit nodes of all targets the target depends on, and has the target's own start node as its output.
142142
private func createTargetBeginTask() -> any PlannedTask {
143-
return createStartTask(lookupTargetExitNode, output: targetTaskInfo.startNode)
143+
return createStartTask(lookupTargetExitNode, output: targetGateNodes.startNode)
144144
}
145145

146146
/// Creates the start-compiling task for the target, which all `compilation` tasks in the target are ordered after.
@@ -153,7 +153,7 @@ final class TargetOrderTaskProducer: StandardTaskProducer, TaskProducer {
153153
/// It has the target's own start-compiling node as its output.
154154
private func createStartCompilingTask() -> any PlannedTask {
155155
let lookup = allowEagerCompilation ? lookupModulesReadyNode : lookupTargetExitNode
156-
return createStartTask(lookup, output: targetTaskInfo.startCompilingNode)
156+
return createStartTask(lookup, output: targetGateNodes.startCompilingNode)
157157
}
158158

159159
/// Creates the start-linking task for the target, which all `linking` tasks in the target are ordered after.
@@ -166,11 +166,11 @@ final class TargetOrderTaskProducer: StandardTaskProducer, TaskProducer {
166166
/// It has the target's own start-compiling node as its output.
167167
private func createStartLinkingTask() -> any PlannedTask {
168168
let lookup = allowEagerLinking ? lookupLinkerInputsReadyNode : lookupTargetExitNode
169-
return createStartTask(lookup, output: targetTaskInfo.startLinkingNode)
169+
return createStartTask(lookup, output: targetGateNodes.startLinkingNode)
170170
}
171171

172172
private func createStartScanningTask() -> any PlannedTask {
173-
createStartTask(lookupScanningInputsReadyNode, output: targetTaskInfo.startScanningNode)
173+
createStartTask(lookupScanningInputsReadyNode, output: targetGateNodes.startScanningNode)
174174
}
175175

176176
/// Creates the start-immediate task for the target.
@@ -183,7 +183,7 @@ final class TargetOrderTaskProducer: StandardTaskProducer, TaskProducer {
183183
/// It has the target's own start-immediate node as its output.
184184
private func createStartImmediateTask() -> any PlannedTask {
185185
let lookup = allowEagerCompilation ? { (_, _) in nil } : lookupTargetExitNode
186-
return createStartTask(lookup, output: targetTaskInfo.startImmediateNode)
186+
return createStartTask(lookup, output: targetGateNodes.startImmediateNode)
187187
}
188188

189189
/// Utility method to create one of several kinds of start tasks for the target.
@@ -361,7 +361,7 @@ final class TargetOrderTaskProducer: StandardTaskProducer, TaskProducer {
361361

362362
/// Returns the end node for the given `dependency` which `target` depends on. This is often used to order the tasks of one target after a specific set of tasks of an earlier target.
363363
private func lookupTargetExitNode(_ dependency: ConfiguredTarget, _ target: ConfiguredTarget) -> any PlannedNode {
364-
let taskInfo = context.globalProductPlan.targetTaskInfos[dependency]!
364+
let taskInfo = context.globalProductPlan.targetGateNodes[dependency]!
365365
// If the dependency is the target which is hosting this target, then use its unsigned-product-ready node as the input.
366366
if let hostTarget = context.globalProductPlan.hostTargetForTargets[target], dependency === hostTarget {
367367
return taskInfo.unsignedProductReadyNode
@@ -372,7 +372,7 @@ final class TargetOrderTaskProducer: StandardTaskProducer, TaskProducer {
372372

373373
/// Returns the node before which are ordered all of the tasks needed to finish building the modules for the given `dependency`. This is used to order both the target's own compilation tasks after this node, and - when eager compilation are enabled - downstream targets' compilation tasks after this node, allowing them to run in parallel with this target's compilation tasks.
374374
private func lookupModulesReadyNode(_ dependency: ConfiguredTarget, _ target: ConfiguredTarget) -> any PlannedNode {
375-
let taskInfo = context.globalProductPlan.targetTaskInfos[dependency]!
375+
let taskInfo = context.globalProductPlan.targetGateNodes[dependency]!
376376
let targetScope = context.globalProductPlan.getTargetSettings(dependency).globalScope
377377
if targetScope.evaluate(BuiltinMacros.EAGER_COMPILATION_DISABLE) {
378378
return taskInfo.endNode
@@ -381,7 +381,7 @@ final class TargetOrderTaskProducer: StandardTaskProducer, TaskProducer {
381381
}
382382

383383
private func lookupLinkerInputsReadyNode(_ dependency: ConfiguredTarget, _ target: ConfiguredTarget) -> any PlannedNode {
384-
let taskInfo = context.globalProductPlan.targetTaskInfos[dependency]!
384+
let taskInfo = context.globalProductPlan.targetGateNodes[dependency]!
385385
let targetScope = context.globalProductPlan.getTargetSettings(dependency).globalScope
386386
if targetScope.evaluate(BuiltinMacros.EAGER_COMPILATION_DISABLE) {
387387
return taskInfo.endNode
@@ -390,7 +390,7 @@ final class TargetOrderTaskProducer: StandardTaskProducer, TaskProducer {
390390
}
391391

392392
private func lookupScanningInputsReadyNode(_ dependency: ConfiguredTarget, _ target: ConfiguredTarget) -> any PlannedNode {
393-
let taskInfo = context.globalProductPlan.targetTaskInfos[dependency]!
393+
let taskInfo = context.globalProductPlan.targetGateNodes[dependency]!
394394
return taskInfo.scanInputsReadyNode
395395

396396
}

Sources/SWBTaskConstruction/TaskProducers/TaskProducer.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,7 +1037,7 @@ public class TaskProducerContext: StaleFileRemovalContext, BuildFileResolution
10371037
}
10381038

10391039
public final class TargetTaskProducerContext: TaskProducerContext {
1040-
private let targetTaskInfo: TargetTaskInfo
1040+
private let targetTaskInfo: TargetGateNodes
10411041

10421042
/// A path node representing the tasks necessary to 'prepare-for-index' a target, before any compilation can occur.
10431043
/// This is only set for an index build.
@@ -1077,7 +1077,7 @@ public final class TargetTaskProducerContext: TaskProducerContext {
10771077
/// - parameter targetTaskInfo: The high-level target task information.
10781078
/// - parameter globalProductPlan: The high-level global build information.
10791079
/// - parameter delegate: The delegate to use for task construction.
1080-
init(configuredTarget: ConfiguredTarget, workspaceContext: WorkspaceContext, targetTaskInfo: TargetTaskInfo, globalProductPlan: GlobalProductPlan, delegate: any TaskPlanningDelegate) {
1080+
init(configuredTarget: ConfiguredTarget, workspaceContext: WorkspaceContext, targetTaskInfo: TargetGateNodes, globalProductPlan: GlobalProductPlan, delegate: any TaskPlanningDelegate) {
10811081
self.targetTaskInfo = targetTaskInfo
10821082

10831083
// Create the target end gate task, which connects the target's start node to its end node.
@@ -1111,7 +1111,7 @@ public final class TargetTaskProducerContext: TaskProducerContext {
11111111

11121112
// Create the will-sign gate task.
11131113
// This depends on the unsigned-products-ready node, and also on the end nodes of all the targets whose products this target is hosting.
1114-
let willSignTaskInputs = [targetTaskInfo.unsignedProductReadyNode] + (globalProductPlan.hostedTargetsForTargets[configuredTarget]?.compactMap({ globalProductPlan.targetTaskInfos[$0]?.endNode }) ?? [])
1114+
let willSignTaskInputs = [targetTaskInfo.unsignedProductReadyNode] + (globalProductPlan.hostedTargetsForTargets[configuredTarget]?.compactMap({ globalProductPlan.targetGateNodes[$0]?.endNode }) ?? [])
11151115
self.willSignTask = delegate.createGateTask(willSignTaskInputs, output: targetTaskInfo.willSignNode, name: targetTaskInfo.willSignNode.name, mustPrecede: []) {
11161116
$0.forTarget = configuredTarget
11171117
$0.makeGate()

0 commit comments

Comments
 (0)