Skip to documentation
SLOP

tiny.choir.passes.plan

Reference tiny.choir passes plan

Defined in passes.

API (21)

Actions

Public operations.

Types and contracts

Public types and contracts.

No direct callersNo direct callspassesplan
Static calls · unresolved targets: unknown · external targets: unknown.

Source

Called byCallsNo direct callspasses.plan.StepconfiguredPasspasses.plan.StepconfiguredPipelinepasses.PassPlanInvocationconfigured
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callspasses.plan.StepnamedPasspasses.plan.StepnamedPipelinepasses.PassPlanInvocationnamed
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callspasses.plan.SteptextualPipelinepasses.PassPlanInvocationtextual
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callerspasses.PassPlanaddToOppasses.PassPlanaddTo
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallspasses.PassPlanaddToprivate sourcelib.choir.src.passes.planappendParsedManagerprivate sourcelib.choir.src.passes.planapplyStepspasses.PassPlanaddToOp
Static calls · unresolved targets: 0 · external targets: 2.
Called byCallsNo direct callerspasses.PassPlanwritepasses.PassPlanformatAlloc
Static calls · unresolved targets: 0 · external targets: 2.
Called byCallspasses.PassPlanformatAllocprivate sourcelib.choir.src.passes.planwriteStepspasses.PassPlanwrite
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallstest sourcelib.choir.src.passes.plantest: pass plan formats bare boolean ...test sourcelib.choir.src.passes.plantest: pass plan materializes nested c...passes.plan.Invocationconfiguredpasses.PassPlanStepconfiguredPass
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallstest sourcelib.choir.src.passes.plantest: pass plan materializes configur...passes.plan.Invocationconfiguredpasses.PassPlanStepconfiguredPipeline
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallstest sourcelib.choir.src.passes.plantest: pass plan errors do not mutate ...test sourcelib.choir.src.passes.plantest: pass plan materializes named pa...test sourcelib.choir.src.passes.plantest: pass plan materializes nested c...passes.plan.Invocationnamedpasses.PassPlanStepnamedPass
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallstest sourcelib.choir.src.passes.plantest: pass plan materializes named pa...passes.plan.Invocationnamedpasses.PassPlanStepnamedPipeline
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callstest sourcelib.choir.src.passes.plantest: pass plan materializes nested c...passes.PassPlanStepnestedAny
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callstest sourcelib.choir.src.passes.plantest: pass plan materializes nested c...passes.PassPlanStepnestedOp
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callerspasses.plan.Invocationtextualpasses.PassPlanSteptextualPipeline
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsprivate sourcelib.choir.src.passes.planapplyPassprivate sourcelib.choir.src.passes.planbuildTestPipelineWithOptionspasses.planwriteOptionspasses.planformatOptionsAlloc
Static calls · unresolved targets: 0 · external targets: 2.
Called byCallspasses.planformatOptionsAllocprivate sourcelib.choir.src.passes.planwriteInvocationprivate sourcelib.choir.src.passes.planwriteOptionValuepasses.planwriteOptions
Static calls · unresolved targets: 0 · external targets: 2.

Source: lib/choir/src/passes/plan.zig

zig
const std = @import("std");const pass_mod = @import("pass/root.zig");const registry_mod = @import("pipeline.zig");pub const Target = union(enum) {    any,    op: []const u8,};pub const Invocation = struct {    name: []const u8,    options: []const registry_mod.PassOptionAssignment = &.{},    text: ?[]const u8 = null,    pub fn named(name: []const u8) Invocation {        return .{ .name = name };    }    pub fn configured(        name: []const u8,        options: []const registry_mod.PassOptionAssignment,    ) Invocation {        return .{            .name = name,            .options = options,        };    }    pub fn textual(        name: []const u8,        text: []const u8,        options: []const registry_mod.PassOptionAssignment,    ) Invocation {        return .{            .name = name,            .options = options,            .text = text,        };    }    fn hasOptions(self: Invocation) bool {        return self.text != null or self.options.len != 0;    }};pub const Nested = struct {    target: Target,    steps: []const Step,};pub const Step = union(enum) {    pass: Invocation,    pipeline: Invocation,    nested: Nested,    pub fn namedPass(name: []const u8) Step {        return .{ .pass = Invocation.named(name) };    }    pub fn configuredPass(        name: []const u8,        options: []const registry_mod.PassOptionAssignment,    ) Step {        return .{ .pass = Invocation.configured(name, options) };    }    pub fn namedPipeline(name: []const u8) Step {        return .{ .pipeline = Invocation.named(name) };    }    pub fn configuredPipeline(        name: []const u8,        options: []const registry_mod.PassOptionAssignment,    ) Step {        return .{ .pipeline = Invocation.configured(name, options) };    }    pub fn textualPipeline(        name: []const u8,        text: []const u8,        options: []const registry_mod.PassOptionAssignment,    ) Step {        return .{ .pipeline = Invocation.textual(name, text, options) };    }    pub fn nestedAny(steps: []const Step) Step {        return .{            .nested = .{                .target = .any,                .steps = steps,            },        };    }    pub fn nestedOp(name: []const u8, steps: []const Step) Step {        return .{            .nested = .{                .target = .{ .op = name },                .steps = steps,            },        };    }};pub const Plan = struct {    steps: []const Step,    pub fn addTo(        self: Plan,        registry: *const registry_mod.PassRegistry,        manager: *pass_mod.PassManager,    ) anyerror!void {        try self.addToOp(registry, &manager.root);    }    pub fn addToOp(        self: Plan,        registry: *const registry_mod.PassRegistry,        manager: *pass_mod.OpPassManager,    ) anyerror!void {        var parsed = pass_mod.OpPassManager.initWithTarget(            manager.allocator,            manager.target_kind,            manager.target_op_name,        );        defer parsed.deinit();        try applySteps(self.steps, registry, &parsed);        try appendParsedManager(manager, &parsed);    }    pub fn write(self: Plan, writer: *std.Io.Writer) std.Io.Writer.Error!void {        try writeSteps(writer, self.steps);    }    pub fn formatAlloc(self: Plan, allocator: std.mem.Allocator) ![]u8 {        var out = std.Io.Writer.Allocating.init(allocator);        defer out.deinit();        try self.write(&out.writer);        return try out.toOwnedSlice();    }};fn applySteps(    steps: []const Step,    registry: *const registry_mod.PassRegistry,    manager: *pass_mod.OpPassManager,) anyerror!void {    for (steps) |step| {        switch (step) {            .pass => |invocation| try applyPass(invocation, registry, manager),            .pipeline => |invocation| try applyPipeline(invocation, registry, manager),            .nested => |nested| {                const nested_manager = switch (nested.target) {                    .any => try manager.nestAny(),                    .op => |name| try manager.nest(name),                };                try applySteps(nested.steps, registry, nested_manager);            },        }    }}fn applyPipeline(    invocation: Invocation,    registry: *const registry_mod.PassRegistry,    manager: *pass_mod.OpPassManager,) anyerror!void {    const registration = registry.lookupPipeline(invocation.name) orelse return error.UnknownPipeline;    if (!invocation.hasOptions()) {        try registration.addTo(manager);        return;    }    try registration.addToWithOptions(        manager,        .{ .assignments = invocation.options },    );}fn applyPass(    invocation: Invocation,    registry: *const registry_mod.PassRegistry,    manager: *pass_mod.OpPassManager,) anyerror!void {    const registration = registry.lookupPass(invocation.name) orelse return error.UnknownPass;    if (!invocation.hasOptions()) {        try registration.addTo(manager);        return;    }    var owned_text: ?[]u8 = null;    defer if (owned_text) |text| manager.allocator.free(text);    const option_text = invocation.text orelse blk: {        owned_text = try formatOptionsAlloc(manager.allocator, invocation.options);        break :blk owned_text.?;    };    try registration.addToWithOptions(        manager,        option_text,        .{ .assignments = invocation.options },    );}fn appendParsedManager(    dst: *pass_mod.OpPassManager,    src: *pass_mod.OpPassManager,) std.mem.Allocator.Error!void {    try dst.pipeline.ensureUnusedCapacity(dst.allocator, src.pipeline.items.len);    try dst.nested_managers.ensureUnusedCapacity(dst.allocator, src.nested_managers.items.len);    for (src.nested_managers.items) |nested| {        nested.parent = dst;    }    dst.pipeline.appendSliceAssumeCapacity(src.pipeline.items);    dst.nested_managers.appendSliceAssumeCapacity(src.nested_managers.items);    src.pipeline.clearRetainingCapacity();    src.nested_managers.clearRetainingCapacity();}fn writeSteps(writer: *std.Io.Writer, steps: []const Step) std.Io.Writer.Error!void {    for (steps, 0..) |step, index| {        if (index != 0) try writer.writeByte(',');        switch (step) {            .pass => |invocation| try writeInvocation(writer, invocation),            .pipeline => |invocation| try writeInvocation(writer, invocation),            .nested => |nested| {                switch (nested.target) {                    .any => try writer.writeAll("any"),                    .op => |name| try writer.writeAll(name),                }                try writer.writeByte('(');                try writeSteps(writer, nested.steps);                try writer.writeByte(')');            },        }    }}fn writeInvocation(writer: *std.Io.Writer, invocation: Invocation) std.Io.Writer.Error!void {    try writer.writeAll(invocation.name);    if (invocation.text) |text| {        try writer.writeByte('{');        try writer.writeAll(text);        try writer.writeByte('}');    } else if (invocation.options.len != 0) {        try writer.writeByte('{');        try writeOptions(writer, invocation.options);        try writer.writeByte('}');    }}pub fn formatOptionsAlloc(    allocator: std.mem.Allocator,    options: []const registry_mod.PassOptionAssignment,) ![]u8 {    var out = std.Io.Writer.Allocating.init(allocator);    defer out.deinit();    try writeOptions(&out.writer, options);    return try out.toOwnedSlice();}pub fn writeOptions(    writer: *std.Io.Writer,    options: []const registry_mod.PassOptionAssignment,) std.Io.Writer.Error!void {    for (options, 0..) |option, index| {        if (index != 0) try writer.writeByte(',');        try writer.writeAll(option.name);        if (option.value.len == 0) continue;        try writer.writeByte('=');        try writeOptionValue(writer, option.value);    }}fn writeOptionValue(writer: *std.Io.Writer, value: []const u8) std.Io.Writer.Error!void {    if (!optionValueNeedsQuotes(value)) {        try writer.writeAll(value);        return;    }    try writer.writeByte('"');    try writer.writeAll(value);    try writer.writeByte('"');}fn optionValueNeedsQuotes(value: []const u8) bool {    if (value.len == 0) return true;    for (value) |byte| {        if (std.ascii.isWhitespace(byte) or byte == ',' or byte == '}') return true;    }    return false;}fn noopPass(_: *pass_mod.PassContext) pass_mod.PassResult {    return .success;}const test_pass = pass_mod.Pass{    .name = "choir-plan-test-pass",    .description = "test pass for pass plans",    .run_fn = noopPass,};const test_other_pass = pass_mod.Pass{    .name = "choir-plan-test-other-pass",    .description = "second test pass for pass plans",    .run_fn = noopPass,};const test_option_pass = pass_mod.Pass{    .name = "choir-plan-test-option-pass",    .description = "test pass for pass plan options",    .run_fn = noopPass,};const test_option_specs = [_]registry_mod.PassOptionSpec{    .{        .name = "limit",        .description = "test limit",        .kind = .unsigned,        .default_value = "0",    },    .{        .name = "enabled",        .description = "test toggle",        .kind = .boolean,        .default_value = "false",    },};fn buildTestOptionPass(_: std.mem.Allocator, options: registry_mod.PassOptionSet) anyerror!pass_mod.Pass {    _ = try options.unsignedValue(usize, "limit", 0);    _ = try options.boolValue("enabled", false);    return test_option_pass;}fn buildTestPipeline(manager: *pass_mod.OpPassManager) anyerror!void {    try manager.addPass(test_pass);}const test_pass_registration = registry_mod.PassRegistration{    .name = test_pass.name,    .description = test_pass.description,    .pass = test_pass,};const test_other_pass_registration = registry_mod.PassRegistration{    .name = test_other_pass.name,    .description = test_other_pass.description,    .pass = test_other_pass,};const test_option_pass_registration = registry_mod.PassRegistration{    .name = test_option_pass.name,    .description = test_option_pass.description,    .pass = test_option_pass,    .options = &test_option_specs,    .build_with_options = buildTestOptionPass,};const test_pipeline = registry_mod.PipelineRegistration{    .name = "choir-plan-test-pipeline",    .description = "test pipeline for pass plans",    .build = buildTestPipeline,};fn buildTestPipelineWithOptions(manager: *pass_mod.OpPassManager, options: registry_mod.PassOptionSet) anyerror!void {    const text = try formatOptionsAlloc(manager.allocator, options.assignments);    defer manager.allocator.free(text);    try test_option_pass_registration.addToWithOptions(manager, text, options);}const test_option_pipeline = registry_mod.PipelineRegistration{    .name = "choir-plan-test-option-pipeline",    .description = "test pipeline with options",    .build = buildTestPipeline,    .options = &test_option_specs,    .build_with_options = buildTestPipelineWithOptions,};fn buildTestRegistry(allocator: std.mem.Allocator) !registry_mod.PassRegistry {    var registry = registry_mod.PassRegistry.init(allocator);    errdefer registry.deinit();    try registry.registerPass(test_pass_registration);    try registry.registerPass(test_other_pass_registration);    try registry.registerPass(test_option_pass_registration);    try registry.registerPipeline(test_pipeline);    try registry.registerPipeline(test_option_pipeline);    return registry;}test "pass plan materializes named passes and pipelines" {    var registry = try buildTestRegistry(std.testing.allocator);    defer registry.deinit();    const steps = [_]Step{        Step.namedPass(test_pass.name),        Step.namedPipeline(test_pipeline.name),    };    const pass_plan = Plan{ .steps = &steps };    const plan_text = try pass_plan.formatAlloc(std.testing.allocator);    defer std.testing.allocator.free(plan_text);    try std.testing.expectEqualStrings("choir-plan-test-pass,choir-plan-test-pipeline", plan_text);    var manager = pass_mod.PassManager.init(std.testing.allocator);    defer manager.deinit();    try pass_plan.addTo(&registry, &manager);    try std.testing.expectEqual(@as(usize, 2), manager.root.pipeline.items.len);    switch (manager.root.pipeline.items[0]) {        .pass => |pass| try std.testing.expectEqualStrings(test_pass.name, pass.name),        .nested => return error.TestExpectedPass,    }    switch (manager.root.pipeline.items[1]) {        .pass => |pass| try std.testing.expectEqualStrings(test_pass.name, pass.name),        .nested => return error.TestExpectedPass,    }}test "pass plan materializes configured pipelines" {    var registry = try buildTestRegistry(std.testing.allocator);    defer registry.deinit();    const options = [_]registry_mod.PassOptionAssignment{        .{ .name = "limit", .value = "9" },    };    const steps = [_]Step{        Step.configuredPipeline(test_option_pipeline.name, &options),    };    const pass_plan = Plan{ .steps = &steps };    const plan_text = try pass_plan.formatAlloc(std.testing.allocator);    defer std.testing.allocator.free(plan_text);    try std.testing.expectEqualStrings("choir-plan-test-option-pipeline{limit=9}", plan_text);    var manager = pass_mod.PassManager.init(std.testing.allocator);    defer manager.deinit();    try pass_plan.addTo(&registry, &manager);    try std.testing.expectEqual(@as(usize, 1), manager.root.pipeline.items.len);    switch (manager.root.pipeline.items[0]) {        .pass => |pass| {            try std.testing.expectEqualStrings(test_option_pass.name, pass.name);            try std.testing.expectEqualStrings("limit=9", pass.textual_options.?);        },        .nested => return error.TestExpectedPass,    }}test "pass plan formats bare boolean option flags" {    var registry = try buildTestRegistry(std.testing.allocator);    defer registry.deinit();    const options = [_]registry_mod.PassOptionAssignment{        .{ .name = "enabled", .value = "" },        .{ .name = "limit", .value = "7" },    };    const steps = [_]Step{        Step.configuredPass(test_option_pass.name, &options),    };    const pass_plan = Plan{ .steps = &steps };    const plan_text = try pass_plan.formatAlloc(std.testing.allocator);    defer std.testing.allocator.free(plan_text);    try std.testing.expectEqualStrings("choir-plan-test-option-pass{enabled,limit=7}", plan_text);    var manager = pass_mod.PassManager.init(std.testing.allocator);    defer manager.deinit();    try pass_plan.addTo(&registry, &manager);    switch (manager.root.pipeline.items[0]) {        .pass => |pass| try std.testing.expectEqualStrings("enabled,limit=7", pass.textual_options.?),        .nested => return error.TestExpectedPass,    }}test "pass plan materializes nested configured passes" {    var registry = try buildTestRegistry(std.testing.allocator);    defer registry.deinit();    const options = [_]registry_mod.PassOptionAssignment{        .{ .name = "limit", .value = "7" },    };    const nested_steps = [_]Step{        Step.configuredPass(test_option_pass.name, &options),    };    const steps = [_]Step{        Step.nestedOp("test.op", &nested_steps),        Step.nestedAny(&.{Step.namedPass(test_other_pass.name)}),    };    const pass_plan = Plan{ .steps = &steps };    const plan_text = try pass_plan.formatAlloc(std.testing.allocator);    defer std.testing.allocator.free(plan_text);    try std.testing.expectEqualStrings("test.op(choir-plan-test-option-pass{limit=7}),any(choir-plan-test-other-pass)", plan_text);    var manager = pass_mod.PassManager.init(std.testing.allocator);    defer manager.deinit();    try pass_plan.addTo(&registry, &manager);    try std.testing.expectEqual(@as(usize, 2), manager.root.pipeline.items.len);    switch (manager.root.pipeline.items[0]) {        .nested => |nested| {            try std.testing.expectEqual(pass_mod.OpPassManagerTargetKind.op, nested.target_kind);            try std.testing.expectEqualStrings("test.op", nested.target_op_name.?);            switch (nested.pipeline.items[0]) {                .pass => |pass| {                    try std.testing.expectEqualStrings(test_option_pass.name, pass.name);                    try std.testing.expectEqualStrings("limit=7", pass.textual_options.?);                },                .nested => return error.TestExpectedPass,            }        },        .pass => return error.TestExpectedNestedPassManager,    }    switch (manager.root.pipeline.items[1]) {        .nested => |nested| {            try std.testing.expectEqual(pass_mod.OpPassManagerTargetKind.any, nested.target_kind);            try std.testing.expectEqual(@as(?[]const u8, null), nested.target_op_name);        },        .pass => return error.TestExpectedNestedPassManager,    }}test "pass plan errors do not mutate destination manager" {    var registry = try buildTestRegistry(std.testing.allocator);    defer registry.deinit();    const existing_steps = [_]Step{Step.namedPass(test_pass.name)};    const existing_plan = Plan{ .steps = &existing_steps };    var manager = pass_mod.PassManager.init(std.testing.allocator);    defer manager.deinit();    try existing_plan.addTo(&registry, &manager);    const bad_steps = [_]Step{        Step.namedPass(test_other_pass.name),        Step.namedPass("missing-pass"),    };    const bad_plan = Plan{ .steps = &bad_steps };    try std.testing.expectError(error.UnknownPass, bad_plan.addTo(&registry, &manager));    try std.testing.expectEqual(@as(usize, 1), manager.root.pipeline.items.len);    switch (manager.root.pipeline.items[0]) {        .pass => |pass| try std.testing.expectEqualStrings(test_pass.name, pass.name),        .nested => return error.TestExpectedPass,    }}

Source: lib/choir/src/passes/root.zig:50

zig
pub const plan = @import("plan.zig");

Audit

Definitions22
Public names43
Members11
Version26.7.0
Revisiondaab053ee433