Skip to documentation
SLOP

tiny.choir.passes.pass

Reference tiny.choir passes pass

Defined in passes.

API (67)

Actions

Public operations.

Types and contracts

Public types and contracts.

Namespaces

Public namespaces.

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

Source

Source: lib/choir/src/passes/pass/analysis.zig:129

zig
pub const AnalysisCache = struct {    allocator: std.mem.Allocator,    entries: std.AutoHashMap(AnalysisKey, AnalysisEntry),    stats: ?*PassManagerStats,    accounting: ?*revision.AccountingV1 = null,    allocation_failure: subject.work.AllocationFailure = .{},    entry_limit: ?u32 = null,    pub fn init(allocator: std.mem.Allocator, stats: ?*PassManagerStats) AnalysisCache {        return .{            .allocator = allocator,            .entries = std.AutoHashMap(AnalysisKey, AnalysisEntry).init(allocator),            .stats = stats,        };    }    /// The ledger outlives this fresh cache and every computation using it.    pub fn initAccounted(        allocator: std.mem.Allocator,        stats: ?*PassManagerStats,        accounting: *revision.AccountingV1,        allocation_failure: subject.work.AllocationFailure,        entry_limit: u32,    ) !AnalysisCache {        if (allocation_failure.exhausted()) {            accounting.fail(.exhausted);            return error.WorkExhausted;        }        var cache = init(allocator, stats);        cache.accounting = accounting;        cache.allocation_failure = allocation_failure;        cache.entry_limit = entry_limit;        errdefer cache.deinit();        const bytes = storageBound(entry_limit) catch |err| {            accounting.fail(.exhausted);            return err;        };        const token = try accounting.begin(.input, .{            .identity = .{ .name = "choir-analysis-cache", .version = 1 },            .work = .{ .allocation_capacity = bytes },            .workspace = bytes,            .retained_storage = bytes,        });        cache.entries.ensureTotalCapacity(entry_limit) catch |err| {            const failure = allocation_failure.classify(err);            accounting.fail(if (failure == error.WorkExhausted) .exhausted else .rejected);            try accounting.finish(token, .rejected, .{});            return failure;        };        try accounting.finish(token, .success, .{});        return cache;    }    /// Bounds the pinned HashMap header, aligned keys/values and one-byte slot metadata.    /// The table is allocated once, before the first computation, without later growth.    pub fn storageBound(entry_limit: u32) !u64 {        if (entry_limit == 0) return 0;        const load_capacity = @as(u64, entry_limit) * 100 / 80 + 1;        if (load_capacity > std.math.maxInt(u32)) return error.WorkOverflow;        const capacity = std.math.ceilPowerOfTwo(u32, @intCast(load_capacity)) catch            return error.WorkOverflow;        if (capacity > std.math.maxInt(u32) / 80) return error.WorkOverflow;        const slots: u64 = @max(8, capacity);        const slot_bytes = 1 + @sizeOf(AnalysisKey) + @sizeOf(AnalysisEntry);        const alignment = @max(@alignOf(usize), @alignOf(AnalysisKey), @alignOf(AnalysisEntry));        const bytes = 4 * @sizeOf(usize) + 3 * alignment + slots * slot_bytes;        if (bytes > std.math.maxInt(usize)) return error.WorkOverflow;        return bytes;    }    pub fn deinit(self: *AnalysisCache) void {        var iter = self.entries.valueIterator();        while (iter.next()) |entry| {            if (entry.cleanup) |cleanup| {                cleanup(entry.value, self.allocator);            }        }        self.entries.deinit();    }    pub fn getOrCompute(        self: *AnalysisCache,        ctx: *PassContext,        op: *ir.Operation,        descriptor: *const AnalysisDescriptor,        compute: *const fn (*PassContext, *ir.Operation) anyerror!*anyopaque,        cleanup: ?*const fn (*anyopaque, std.mem.Allocator) void,        instrumentor: ?*const PassInstrumentor,    ) !*anyopaque {        try self.requireRunning();        const key = AnalysisKey{ .op = op, .analysis = descriptor.id };        if (self.entries.get(key)) |entry| {            if (self.accounting) |ledger| try ledger.observeCounters(.{ .analysis_hits = 1 });            if (self.stats) |stats| stats.analysis_hits += 1;            return entry.value;        }        const run = try Computation.begin(self.accounting, descriptor, op, ctx.run_options);        if (self.entry_limit) |limit| {            if (self.entries.count() >= limit) {                try run.finish(error.WorkExhausted, false);                return error.WorkExhausted;            }        }        const value = self.computeAndCache(            ctx,            op,            descriptor,            compute,            cleanup,            instrumentor,        ) catch |err| {            const failure = self.allocation_failure.classify(err);            try run.finish(failure, true);            return failure;        };        try run.finish(null, true);        return value;    }    /// Refresh replaces the cached value in place; failure must leave it intact.    pub fn refresh(        self: *AnalysisCache,        ctx: *PassContext,        op: *ir.Operation,        descriptor: *const AnalysisDescriptor,        refresh_value: *const fn (*PassContext, *ir.Operation, *anyopaque) anyerror!void,        instrumentor: ?*const PassInstrumentor,    ) !void {        try self.requireRunning();        const entry = self.entries.get(.{ .op = op, .analysis = descriptor.id }) orelse            return error.UncachedAnalysis;        const run = try Computation.begin(self.accounting, entry.descriptor, op, ctx.run_options);        const info = AnalysisInfo{            .id = descriptor.id,            .name = descriptor.name,            .target_op = op,        };        if (instrumentor) |inst| inst.runBeforeAnalysis(info);        refresh_value(ctx, op, entry.value) catch |err| {            if (instrumentor) |inst| inst.runAfterAnalysis(info);            const failure = self.allocation_failure.classify(err);            try run.finish(failure, true);            return failure;        };        if (instrumentor) |inst| inst.runAfterAnalysis(info);        self.requireRunning() catch |err| {            try run.finish(err, true);            return err;        };        if (self.stats) |stats| stats.analysis_misses += 1;        try run.finish(null, true);    }    fn computeAndCache(        self: *AnalysisCache,        ctx: *PassContext,        op: *ir.Operation,        descriptor: *const AnalysisDescriptor,        compute: *const fn (*PassContext, *ir.Operation) anyerror!*anyopaque,        cleanup: ?*const fn (*anyopaque, std.mem.Allocator) void,        instrumentor: ?*const PassInstrumentor,    ) !*anyopaque {        const info = AnalysisInfo{            .id = descriptor.id,            .name = descriptor.name,            .target_op = op,        };        if (instrumentor) |inst| inst.runBeforeAnalysis(info);        const value = compute(ctx, op) catch |err| {            if (instrumentor) |inst| inst.runAfterAnalysis(info);            return err;        };        if (instrumentor) |inst| inst.runAfterAnalysis(info);        errdefer if (cleanup) |cleanup_fn| cleanup_fn(value, self.allocator);        try self.requireRunning();        const key = AnalysisKey{ .op = op, .analysis = descriptor.id };        const entry = AnalysisEntry{ .descriptor = descriptor, .value = value, .cleanup = cleanup };        if (self.entry_limit != null) {            self.entries.putAssumeCapacityNoClobber(key, entry);        } else {            try self.entries.put(key, entry);        }        if (self.stats) |stats| stats.analysis_misses += 1;        return value;    }    fn requireRunning(self: *AnalysisCache) !void {        const ledger = self.accounting orelse return;        if (ledger.view().outcome != .running) return error.TerminalWorkOutcome;        if (self.allocation_failure.exhausted()) {            ledger.fail(.exhausted);            return error.WorkExhausted;        }    }    pub fn invalidate(self: *AnalysisCache, preserved: *const PreservedAnalyses) void {        if (preserved.preserve_all) return;        var iter = self.entries.iterator();        while (iter.next()) |kv| {            if (!preserved.preservesDescriptor(kv.value_ptr.descriptor)) {                const entry = kv.value_ptr.*;                self.entries.removeByPtr(kv.key_ptr);                if (entry.cleanup) |cleanup| {                    cleanup(entry.value, self.allocator);                }                if (self.stats) |stats| stats.analyses_invalidated += 1;            }        }    }};

Source: lib/choir/src/passes/pass/analysis.zig:16

zig
pub const AnalysisDescriptor = struct {    work_contract: ?subject.work.Contract = null,    id: AnalysisId,    name: []const u8,    required_interfaces: []const ir.InterfaceId = &.{},};

Source: lib/choir/src/passes/pass/analysis.zig:378

zig
pub const PassContext = struct {    op: *ir.Operation,    ir_ctx: *ir.Context,    allocator: std.mem.Allocator,    analysis_cache: *AnalysisCache,    preserved: PreservedAnalyses,    modified: bool,    instrumentor: ?*const PassInstrumentor,    run_options: PassManagerRunOptions,    pass_info: ?PassInfo,    pub fn init(        op: *ir.Operation,        ir_ctx: *ir.Context,        allocator: std.mem.Allocator,        analysis_cache: *AnalysisCache,    ) PassContext {        return initWithOptions(op, ir_ctx, allocator, analysis_cache, .{});    }    pub fn initWithOptions(        op: *ir.Operation,        ir_ctx: *ir.Context,        allocator: std.mem.Allocator,        analysis_cache: *AnalysisCache,        options: PassManagerRunOptions,    ) PassContext {        return initWithInstrumentorAndOptions(op, ir_ctx, allocator, analysis_cache, null, options);    }    pub fn initWithInstrumentor(        op: *ir.Operation,        ir_ctx: *ir.Context,        allocator: std.mem.Allocator,        analysis_cache: *AnalysisCache,        instrumentor: ?*const PassInstrumentor,    ) PassContext {        return initWithInstrumentorAndOptions(            op,            ir_ctx,            allocator,            analysis_cache,            instrumentor,            .{},        );    }    pub fn initWithInstrumentorAndOptions(        op: *ir.Operation,        ir_ctx: *ir.Context,        allocator: std.mem.Allocator,        analysis_cache: *AnalysisCache,        instrumentor: ?*const PassInstrumentor,        options: PassManagerRunOptions,    ) PassContext {        return .{            .op = op,            .ir_ctx = ir_ctx,            .allocator = allocator,            .analysis_cache = analysis_cache,            .preserved = PreservedAnalyses.init(allocator),            .modified = false,            .instrumentor = instrumentor,            .run_options = options,            .pass_info = null,        };    }    pub fn deinit(self: *PassContext) void {        self.preserved.deinit();    }    pub fn markModified(self: *PassContext) void {        self.modified = true;    }    pub fn preserveAllAnalyses(self: *PassContext) void {        self.preserved.preserveAll();    }    pub fn preserveAnalysisSet(self: *PassContext, comptime ids: []const AnalysisId) void {        self.preserved.preserveAnalysisSet(ids);    }    pub fn preserveAnalysis(self: *PassContext, id: AnalysisId) !void {        try self.preserved.preserveAnalysis(id);    }    pub fn preserveInterface(self: *PassContext, id: ir.InterfaceId) !void {        try self.preserved.preserveInterface(id);    }    pub fn getAnalysis(        self: *PassContext,        op: *ir.Operation,        descriptor: *const AnalysisDescriptor,        compute: *const fn (*PassContext, *ir.Operation) anyerror!*anyopaque,        cleanup: ?*const fn (*anyopaque, std.mem.Allocator) void,    ) !*anyopaque {        return self.analysis_cache.getOrCompute(            self,            op,            descriptor,            compute,            cleanup,            self.instrumentor,        );    }    pub fn refreshAnalysis(        self: *PassContext,        op: *ir.Operation,        descriptor: *const AnalysisDescriptor,        refresh: *const fn (*PassContext, *ir.Operation, *anyopaque) anyerror!void,    ) !void {        try self.analysis_cache.refresh(self, op, descriptor, refresh, self.instrumentor);    }    pub fn incrementStatistic(        self: *PassContext,        name: []const u8,        description: []const u8,    ) void {        self.addStatistic(name, description, 1);    }    pub fn addStatistic(        self: *PassContext,        name: []const u8,        description: []const u8,        value: u64,    ) void {        const pass_info = self.pass_info orelse return;        const inst = self.instrumentor orelse return;        inst.runPassStatistic(.{            .pass = pass_info,            .name = name,            .description = description,            .value = value,        });    }    pub fn workerCount(self: *const PassContext, item_count: usize) usize {        return self.run_options.workerCount(item_count);    }    pub fn workerAllocator(self: *const PassContext) std.mem.Allocator {        return self.run_options.workerAllocator(self.allocator);    }};

Source: lib/choir/src/passes/pass/analysis.zig:62

zig
pub const PreservedAnalyses = struct {    allocator: std.mem.Allocator,    preserve_all: bool = false,    analysis_set: []const AnalysisId,    runtime_analyses: std.AutoHashMap(AnalysisId, void),    interfaces: std.AutoHashMap(ir.InterfaceId, void),    pub fn init(allocator: std.mem.Allocator) PreservedAnalyses {        return .{            .allocator = allocator,            .analysis_set = &.{},            .runtime_analyses = std.AutoHashMap(AnalysisId, void).init(allocator),            .interfaces = std.AutoHashMap(ir.InterfaceId, void).init(allocator),            .preserve_all = false,        };    }    pub fn deinit(self: *PreservedAnalyses) void {        self.runtime_analyses.deinit();        self.interfaces.deinit();    }    pub fn preserveAll(self: *PreservedAnalyses) void {        self.preserve_all = true;    }    pub fn preserveAnalysisSet(self: *PreservedAnalyses, comptime ids: []const AnalysisId) void {        std.debug.assert(self.analysis_set.len == 0);        self.analysis_set = ids;    }    pub fn preserveAnalysis(self: *PreservedAnalyses, id: AnalysisId) !void {        for (self.analysis_set) |preserved_id| {            if (preserved_id == id) return;        }        try self.runtime_analyses.put(id, {});    }    pub fn preserveInterface(self: *PreservedAnalyses, id: ir.InterfaceId) !void {        try self.interfaces.put(id, {});    }    fn preservesDescriptor(self: *const PreservedAnalyses, desc: *const AnalysisDescriptor) bool {        if (self.preserve_all) return true;        for (self.analysis_set) |id| {            if (id == desc.id) return true;        }        if (self.runtime_analyses.contains(desc.id)) return true;        if (desc.required_interfaces.len == 0) return false;        for (desc.required_interfaces) |iface| {            if (!self.interfaces.contains(iface)) return false;        }        return true;    }};

Source: lib/choir/src/passes/pass/manager.zig:142

zig
pub const OpPassManager = struct {    allocator: std.mem.Allocator,    target_op_name: ?[]const u8,    target_kind: OpPassManagerTargetKind,    pipeline: std.ArrayListUnmanaged(PipelineEntry),    nested_managers: std.ArrayListUnmanaged(*OpPassManager),    parent: ?*OpPassManager,    pub fn init(allocator: std.mem.Allocator, target_op_name: ?[]const u8) OpPassManager {        return initWithTarget(            allocator,            if (target_op_name == null) .root else .op,            target_op_name,        );    }    pub fn initAny(allocator: std.mem.Allocator) OpPassManager {        return initWithTarget(allocator, .any, null);    }    pub fn initWithTarget(        allocator: std.mem.Allocator,        target_kind: OpPassManagerTargetKind,        target_op_name: ?[]const u8,    ) OpPassManager {        return .{            .allocator = allocator,            .target_op_name = target_op_name,            .target_kind = target_kind,            .pipeline = .empty,            .nested_managers = .empty,            .parent = null,        };    }    pub fn deinit(self: *OpPassManager) void {        for (self.nested_managers.items) |nested| {            nested.deinit();            self.allocator.destroy(nested);        }        for (self.pipeline.items) |*entry| {            switch (entry.*) {                .pass => |*pass| pass.deinit(self.allocator),                .nested => {},            }        }        self.nested_managers.deinit(self.allocator);        self.pipeline.deinit(self.allocator);    }    pub fn addPass(self: *OpPassManager, pass: Pass) !void {        if (!pass.validRerunContract()) return error.InvalidPassRerunContract;        try self.pipeline.append(self.allocator, .{ .pass = pass });    }    pub fn nest(self: *OpPassManager, op_name: []const u8) !*OpPassManager {        const nested = try self.allocator.create(OpPassManager);        nested.* = OpPassManager.init(self.allocator, op_name);        nested.parent = self;        try self.nested_managers.append(self.allocator, nested);        try self.pipeline.append(self.allocator, .{ .nested = nested });        return nested;    }    pub fn nestAny(self: *OpPassManager) !*OpPassManager {        const nested = try self.allocator.create(OpPassManager);        nested.* = OpPassManager.initAny(self.allocator);        nested.parent = self;        try self.nested_managers.append(self.allocator, nested);        try self.pipeline.append(self.allocator, .{ .nested = nested });        return nested;    }    pub fn collectDependentDialects(        self: *const OpPassManager,        allocator: std.mem.Allocator,        names: *std.ArrayListUnmanaged([]const u8),    ) !void {        for (self.pipeline.items) |entry| {            switch (entry) {                .pass => |pass| {                    for (pass.dependent_dialects) |dialect_name| {                        try appendDependentDialectName(allocator, names, dialect_name);                    }                },                .nested => |nested_pm| try nested_pm.collectDependentDialects(allocator, names),            }        }    }    fn matchesOp(self: *const OpPassManager, op: *ir.Operation) bool {        return switch (self.target_kind) {            .root, .any => true,            .op => std.mem.eql(u8, op.name.name, self.target_op_name.?),        };    }    fn matchesScheduledOp(        self: *const OpPassManager,        op: *ir.Operation,        ir_ctx: *ir.Context,    ) bool {        return switch (self.target_kind) {            .root => true,            .op => self.matchesOp(op),            .any => self.isRegisteredIsolatedTarget(op, ir_ctx),        };    }    fn canRunOnTarget(        self: *const OpPassManager,        op: *ir.Operation,        ir_ctx: *ir.Context,    ) bool {        if (self.target_kind == .root) return true;        if (self.target_kind == .any) return self.isRegisteredIsolatedTarget(op, ir_ctx);        const info = op.name.getRegisteredInfo() orelse            ir_ctx.lookupOperation(op.name.name) orelse return false;        return info.hasTraitId(ir.traits.IsolatedFromAbove.id);    }    fn isRegisteredIsolatedTarget(        _: *const OpPassManager,        op: *ir.Operation,        ir_ctx: *ir.Context,    ) bool {        const info = op.name.getRegisteredInfo() orelse            ir_ctx.lookupOperation(op.name.name) orelse return false;        return info.hasTraitId(ir.traits.IsolatedFromAbove.id);    }    fn instrumentationTargetName(self: *const OpPassManager) ?[]const u8 {        return switch (self.target_kind) {            .root => null,            .any => "any",            .op => self.target_op_name,        };    }    pub fn runOnOperation(        self: *OpPassManager,        op: *ir.Operation,        ir_ctx: *ir.Context,        analysis_cache: *AnalysisCache,        stats: *PassManagerStats,        instrumentor: ?*const PassInstrumentor,        verifier: ?*PassVerifierConfig,        failure: ?*?CapturedPassFailure,        options: PassManagerRunOptions,        run_allocator: std.mem.Allocator,    ) PassResult {        if (!self.matchesScheduledOp(op, ir_ctx)) {            return .success;        }        const pipeline_info = PipelineInfo{            .target_op_name = self.instrumentationTargetName(),            .depth = self.getNestingDepth(),        };        if (instrumentor) |inst| {            inst.runBeforePipeline(pipeline_info, op);        }        if (!self.canRunOnTarget(op, ir_ctx)) {            if (instrumentor) |inst| {                inst.runAfterPipeline(pipeline_info, op, true);            }            recordPassFailure(failure, .{                .kind = .target,                .target_op_name = op.name.name,                .target_symbol_name = ir.SymbolTable.getSymbolName(op),            });            return .failure;        }        var run = PipelineRun{            .op = op,            .ir_ctx = ir_ctx,            .analysis_cache = analysis_cache,            .stats = stats,            .instrumentor = instrumentor,            .verifier = verifier,            .failure = failure,            .options = options,            .allocator = run_allocator,        };        const result = self.runPipelineEntries(&run);        if (instrumentor) |inst| {            inst.runAfterPipeline(pipeline_info, op, result == .failure);        }        return result;    }    fn runPipelineEntries(self: *const OpPassManager, run: *PipelineRun) PassResult {        var revision_start: usize = 0;        for (self.pipeline.items, 0..) |entry, entry_index| {            const result = switch (entry) {                .pass => |pass| self.runPassEntry(                    pass,                    entry_index,                    &revision_start,                    run,                ),                .nested => |nested_pm| runNestedEntry(                    nested_pm,                    entry_index,                    &revision_start,                    run,                ),            };            if (result == .failure) return .failure;        }        return .success;    }    /// A failing pass that reports IR modification preserves only analyses it declared preserved.    fn runPassEntry(        self: *const OpPassManager,        pass: Pass,        entry_index: usize,        revision_start: *usize,        run: *PipelineRun,    ) PassResult {        if (run.analysis_cache.accounting == null and            self.hasRerunIdentity(pass, revision_start.*, entry_index))        {            run.stats.passes_skipped += 1;            return .success;        }        const pass_info = PassInfo{            .name = pass.name,            .description = pass.description,            .target_op = run.op,            .mutation_scope = pass.mutation_scope,        };        if (run.instrumentor) |inst| inst.runBeforePass(pass_info);        var ctx = PassContext.initWithInstrumentorAndOptions(            run.op,            run.ir_ctx,            run.allocator,            run.analysis_cache,            run.instrumentor,            run.options,        );        ctx.pass_info = pass_info;        defer ctx.deinit();        const work = PassWork.begin(pass, run);        var finalized: PassResult = .failure;        defer work.finish(finalized, run.stats.*);        const native = if (work.admitted) pass.run(&ctx) else PassResult.failure;        const result = work.normalize(native, pass, run);        if (work.admitted) run.stats.pass_runs += 1;        if (ctx.modified) {            run.stats.passes_modified += 1;            run.analysis_cache.invalidate(&ctx.preserved);            revision_start.* = entry_index;        }        if (result == .failure) {            run.stats.pass_failures += 1;            if (run.instrumentor) |inst| inst.runAfterPassFailed(pass_info);            recordPassFailure(run.failure, .{                .kind = .pass,                .pass_name = pass.name,                .target_op_name = run.op.name.name,                .target_symbol_name = ir.SymbolTable.getSymbolName(run.op),            });            return .failure;        }        if (run.instrumentor) |inst| inst.runAfterPass(pass_info, ctx.modified);        finalized = verifyPass(pass, pass_info, run);        return finalized;    }    fn verifyPass(pass: Pass, pass_info: PassInfo, run: *PipelineRun) PassResult {        const verifier = run.verifier orelse return .success;        if (verifier.verifyAfterPass(pass_info) == .success) return .success;        run.stats.verifier_failures += 1;        recordPassFailure(run.failure, .{            .kind = .verifier,            .pass_name = pass.name,            .target_op_name = run.op.name.name,            .target_symbol_name = ir.SymbolTable.getSymbolName(run.op),            .verifier_error = if (verifier.failure.*) |failure| failure.err else null,        });        return .failure;    }    fn runNestedEntry(        nested: *OpPassManager,        entry_index: usize,        revision_start: *usize,        run: *PipelineRun,    ) PassResult {        const modified_before = run.stats.passes_modified;        const result = nested.walkAndRun(            run.op,            run.ir_ctx,            run.analysis_cache,            run.stats,            run.instrumentor,            run.verifier,            run.failure,            run.options,            run.allocator,        );        if (result == .failure) return .failure;        if (run.stats.passes_modified != modified_before) {            revision_start.* = entry_index + 1;        }        return .success;    }    fn hasRerunIdentity(        self: *const OpPassManager,        pass: Pass,        revision_start: usize,        entry_index: usize,    ) bool {        std.debug.assert(revision_start <= entry_index);        std.debug.assert(entry_index <= self.pipeline.items.len);        var previous_index = entry_index;        while (previous_index > revision_start) {            previous_index -= 1;            switch (self.pipeline.items[previous_index]) {                .pass => |previous| if (pass.sameRerunIdentity(previous)) return true,                .nested => {},            }        }        return false;    }    fn walkAndRun(        self: *OpPassManager,        root: *ir.Operation,        ir_ctx: *ir.Context,        analysis_cache: *AnalysisCache,        stats: *PassManagerStats,        instrumentor: ?*const PassInstrumentor,        verifier: ?*PassVerifierConfig,        failure: ?*?CapturedPassFailure,        options: PassManagerRunOptions,        run_allocator: std.mem.Allocator,    ) PassResult {        if (self.canRunNestedTargetsParallel(instrumentor, verifier, options)) {            const targets = self.collectMatchingTargets(root, ir_ctx) catch return .failure;            defer if (targets.len != 0) self.allocator.free(targets);            if (targets.len > 1 and !targetSetOverlaps(targets)) {                return self.runTargetsParallel(                    targets,                    ir_ctx,                    analysis_cache,                    stats,                    verifier,                    failure,                    options,                );            }        }        return self.walkAndRunSerial(            root,            ir_ctx,            analysis_cache,            stats,            instrumentor,            verifier,            failure,            options,            run_allocator,        );    }    fn walkAndRunSerial(        self: *OpPassManager,        root: *ir.Operation,        ir_ctx: *ir.Context,        analysis_cache: *AnalysisCache,        stats: *PassManagerStats,        instrumentor: ?*const PassInstrumentor,        verifier: ?*PassVerifierConfig,        failure: ?*?CapturedPassFailure,        options: PassManagerRunOptions,        run_allocator: std.mem.Allocator,    ) PassResult {        for (root.regions.items) |*region| {            var block_iter = region.getBlocks();            while (block_iter.next()) |block| {                var current_op: ?*ir.Operation = @ptrCast(@alignCast(block.operations.head));                while (current_op) |nested_op| {                    if (self.matchesScheduledOp(nested_op, ir_ctx)) {                        const result = self.runOnOperation(                            nested_op,                            ir_ctx,                            analysis_cache,                            stats,                            instrumentor,                            verifier,                            failure,                            options,                            run_allocator,                        );                        if (result == .failure) {                            return .failure;                        }                    }                    const walk_result = self.walkAndRunSerial(                        nested_op,                        ir_ctx,                        analysis_cache,                        stats,                        instrumentor,                        verifier,                        failure,                        options,                        run_allocator,                    );                    if (walk_result == .failure) {                        return .failure;                    }                    current_op = nested_op.next_op;                }            }        }        return .success;    }    fn canRunNestedTargetsParallel(        self: *const OpPassManager,        instrumentor: ?*const PassInstrumentor,        verifier: ?*PassVerifierConfig,        options: PassManagerRunOptions,    ) bool {        if (instrumentor != null) return false;        _ = verifier;        if (!options.requestsParallelism()) return false;        return self.parallelReadOnlyPipeline();    }    fn parallelReadOnlyPipeline(self: *const OpPassManager) bool {        for (self.pipeline.items) |entry| {            switch (entry) {                .pass => |pass| {                    if (!pass.readOnly() or !pass.parallelStateSafe()) return false;                },                .nested => |nested_pm| if (!nested_pm.parallelReadOnlyPipeline()) return false,            }        }        return true;    }    fn cloneForParallelTarget(        self: *const OpPassManager,        allocator: std.mem.Allocator,    ) anyerror!OpPassManager {        var cloned = OpPassManager.initWithTarget(            allocator,            self.target_kind,            self.target_op_name,        );        errdefer cloned.deinit();        for (self.pipeline.items) |entry| {            switch (entry) {                .pass => |pass| {                    var pass_clone = try pass.cloneForParallelTarget(allocator);                    var pass_registered = false;                    errdefer if (!pass_registered) pass_clone.deinit(allocator);                    try cloned.pipeline.append(allocator, .{ .pass = pass_clone });                    pass_registered = true;                },                .nested => |nested_pm| {                    const nested = try allocator.create(OpPassManager);                    var nested_initialized = false;                    var nested_registered = false;                    errdefer if (!nested_registered) {                        if (nested_initialized) nested.deinit();                        allocator.destroy(nested);                    };                    nested.* = try nested_pm.cloneForParallelTarget(allocator);                    nested_initialized = true;                    nested.parent = &cloned;                    try cloned.nested_managers.append(allocator, nested);                    nested_registered = true;                    try cloned.pipeline.append(allocator, .{ .nested = nested });                },            }        }        return cloned;    }    fn refreshParentLinks(self: *OpPassManager, parent: ?*OpPassManager) void {        self.parent = parent;        for (self.nested_managers.items) |nested| {            nested.refreshParentLinks(self);        }    }    fn collectMatchingTargets(        self: *OpPassManager,        root: *ir.Operation,        ir_ctx: *ir.Context,    ) ![]*ir.Operation {        var targets: std.ArrayListUnmanaged(*ir.Operation) = .empty;        errdefer targets.deinit(self.allocator);        try self.collectMatchingTargetsInto(root, ir_ctx, &targets);        return if (targets.items.len == 0)            &.{}        else            try targets.toOwnedSlice(self.allocator);    }    fn collectMatchingTargetsInto(        self: *OpPassManager,        root: *ir.Operation,        ir_ctx: *ir.Context,        targets: *std.ArrayListUnmanaged(*ir.Operation),    ) !void {        for (root.regions.items) |*region| {            var block_iter = region.getBlocks();            while (block_iter.next()) |block| {                var current_op: ?*ir.Operation = @ptrCast(@alignCast(block.operations.head));                while (current_op) |nested_op| {                    if (self.matchesScheduledOp(nested_op, ir_ctx)) {                        try targets.append(self.allocator, nested_op);                    }                    try self.collectMatchingTargetsInto(nested_op, ir_ctx, targets);                    current_op = nested_op.next_op;                }            }        }    }    fn runTargetsParallel(        self: *OpPassManager,        targets: []const *ir.Operation,        ir_ctx: *ir.Context,        analysis_cache: *AnalysisCache,        stats: *PassManagerStats,        verifier: ?*PassVerifierConfig,        failure: ?*?CapturedPassFailure,        options: PassManagerRunOptions,    ) PassResult {        _ = analysis_cache;        const worker_allocator = options.workerAllocator(self.allocator);        const slots = self.allocator.alloc(ParallelTargetSlot, targets.len) catch return .failure;        defer self.allocator.free(slots);        for (slots) |*slot| slot.* = ParallelTargetSlot.init(worker_allocator);        defer deinitParallelTargetSlots(slots);        for (slots) |*slot| {            slot.manager = self.cloneForParallelTarget(worker_allocator) catch return .failure;            slot.manager.?.refreshParentLinks(null);        }        var batch = ParallelTargetBatch{            .manager = self,            .allocator = worker_allocator,            .ir_ctx = ir_ctx,            .targets = targets,            .verifier = verifier,            .failure = failure,            .options = options,            .slots = slots,        };        var execution_guard: ?ir.ThreadingExecutionGuard = null;        if (options.workerCount(targets.len) > 1) {            execution_guard = ir_ctx.enterMultithreadedExecution();        }        defer if (execution_guard) |*guard| guard.deinit();        ir.threading.parallelForEachIndex(            self.allocator,            options,            targets.len,            &batch,            runParallelTarget,        ) catch return .failure;        var result: PassResult = .success;        for (slots) |*slot| {            mergeStats(stats, slot.stats);            if (slot.result == .failure) result = .failure;            if (slot.failure) |captured_failure| {                var slot_failure = captured_failure;                slot_failure.worker_count = options.workerCount(targets.len);                recordPassFailure(failure, slot_failure);            }            if (slot.verifier_failure) |verifier_failure| {                if (verifier) |verify| {                    if (verify.failure.* == null) verify.failure.* = verifier_failure;                }            }            _ = ir_ctx.replayDiagnostics(&slot.diagnostics) catch {                result = .failure;                continue;            };        }        return result;    }    pub fn getNestingDepth(self: *const OpPassManager) usize {        var depth: usize = 0;        var current: ?*const OpPassManager = self;        while (current) |pm| {            if (pm.parent) |parent| {                depth += 1;                current = parent;            } else {                break;            }        }        return depth;    }};

Source: lib/choir/src/passes/pass/manager.zig:136

zig
pub const OpPassManagerTargetKind = enum {    root,    any,    op,};

Source: lib/choir/src/passes/pass/manager.zig:131

zig
pub const PipelineEntry = union(enum) {    pass: Pass,    nested: *OpPassManager,};

Source: lib/choir/src/passes/pass/model.zig:69

zig
pub const PassFailureKind = enum {    pass,    verifier,    target,    exhausted,};

Source: lib/choir/src/passes/pass/model.zig:76

zig
pub const PassFailureReproducer = struct {    pipeline: []const u8,    ir: []const u8,    max_threads: usize,    worker_count: usize,    verifier_enabled: bool,    failure_kind: ?PassFailureKind = null,    pass_name: ?[]const u8 = null,    target_op_name: ?[]const u8 = null,    target_symbol_name: ?[]const u8 = null,    verifier_error: ?anyerror = null,    verifier_error_name: ?[]const u8 = null,    pub fn deinit(self: *PassFailureReproducer, allocator: std.mem.Allocator) void {        allocator.free(self.pipeline);        allocator.free(self.ir);        if (self.pass_name) |name| allocator.free(name);        if (self.target_op_name) |name| allocator.free(name);        if (self.target_symbol_name) |name| allocator.free(name);        if (self.verifier_error_name) |name| allocator.free(name);        self.* = undefined;    }};

Source: lib/choir/src/passes/pass/model.zig:36

zig
pub const PassManagerFixedPointResult = struct {    result: PassResult = .success,    iterations: usize = 0,    changed: bool = false,};

Source: lib/choir/src/passes/pass/model.zig:48

zig
pub const PassManagerStats = struct {    pass_runs: u64 = 0,    passes_skipped: u64 = 0,    pass_failures: u64 = 0,    verifier_failures: u64 = 0,    passes_modified: u64 = 0,    analysis_hits: u64 = 0,    analysis_misses: u64 = 0,    analyses_invalidated: u64 = 0,    pub fn reset(self: *PassManagerStats) void {        self.* = .{};    }};

Source: lib/choir/src/passes/pass/model.zig:4

zig
pub const PassMutationScope = enum {    read_only,    isolated,    whole_module,};

Source: lib/choir/src/passes/pass/model.zig:15

zig
pub const PassRerunPolicy = enum {    always,    skip_if_unchanged,};

Source: lib/choir/src/passes/pass/model.zig:100

zig
pub const PassResult = enum {    success,    failure,};

Source: lib/choir/src/passes/pass/model.zig:10

zig
pub const PassStateConcurrency = enum {    exclusive,    shared,};

Source: lib/choir/src/passes/pass/model.zig:63

zig
pub const PassVerifierFailure = struct {    pass_name: []const u8,    target_op_name: []const u8,    err: anyerror,};

Source: lib/choir/src/passes/pass/analysis.zig:23

zig
pub fn Analysis(    comptime Value: type,    comptime name: []const u8,    comptime required_interfaces: []const ir.InterfaceId,    comptime compute: *const fn (*PassContext, *ir.Operation) anyerror!*Value,    comptime cleanup: ?*const fn (*Value, std.mem.Allocator) void,    comptime work_contract: ?subject.work.Contract,) type {    return struct {        pub const id = analysisId(name);        pub const value_type = Value;        pub const descriptor = AnalysisDescriptor{            .id = id,            .name = name,            .required_interfaces = required_interfaces,            .work_contract = work_contract,        };        pub fn get(ctx: *PassContext, op: *ir.Operation) !*Value {            const raw = try ctx.getAnalysis(op, &descriptor, computeOpaque, cleanupOpaque);            return @ptrCast(@alignCast(raw));        }        pub fn preserve(ctx: *PassContext) !void {            try ctx.preserveAnalysis(id);        }        fn computeOpaque(ctx: *PassContext, op: *ir.Operation) anyerror!*anyopaque {            return @ptrCast(try compute(ctx, op));        }        fn cleanupOpaque(raw: *anyopaque, allocator: std.mem.Allocator) void {            if (cleanup) |cleanup_fn| {                cleanup_fn(@ptrCast(@alignCast(raw)), allocator);            }        }    };}
Called byCallsNo direct callerspassesanalysisIdpassesAnalysis
Static calls · unresolved targets: 3 · external targets: 2.
Called byCallsNo direct callsPassManagerrunToFixedPointWithOptionsPassManagerrunWithOptionsprivate sourcelib.choir.src.passes.pass.managerrunParallelTargetprivate sourcelib.choir.src.passes.pass.testexpectFailedMutationCachetest sourcelib.choir.src.passes.pass.testtest: AnalysisCache cleans computed v...+7 morepasses.AnalysisCachedeinit
Static calls · unresolved targets: 1 · external targets: 3.
Called byCallspasses.PassContextgetAnalysisprivate sourcelib.choir.src.passes.pass.analysis.AnalysisCachecomputeAndCacheprivate sourcelib.choir.src.passes.pass.analysis.AnalysisCacherequireRunningprivate sourcelib.choir.src.passes.pass.analysis.Computationbeginpasses.AnalysisCachegetOrCompute
Static calls · unresolved targets: 2 · external targets: 4.
Called byCallsNo direct callsPassManagerrunToFixedPointWithOptionsPassManagerrunWithOptionsprivate sourcelib.choir.src.passes.pass.managerrunParallelTargetprivate sourcelib.choir.src.passes.pass.testexpectFailedMutationCachetest sourcelib.choir.src.passes.pass.testtest: AnalysisCache cleans computed v...+7 morepasses.AnalysisCacheinit
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsprivate sourcelib.choir.src.passes.pass.testcheckContextAnalysisFailureprivate sourcelib.choir.src.passes.pass.testcheckContextPassFailureprivate sourcelib.choir.src.passes.pass.testcheckWorkerAllocationFailuretest sourcelib.choir.src.passes.pass.testtest: U0 analysis accounting records ...test sourcelib.choir.src.passes.pass.testtest: U0 analysis admission refuses b...+17 morepasses.AnalysisCachestorageBoundpasses.AnalysisCacheinitAccounted
Static calls · unresolved targets: 1 · external targets: 7.
Called byCallsNo direct callstest sourcelib.choir.src.passes.pass.testtest: AnalysisCache invalidates based...test sourcelib.choir.src.passes.pass.testtest: Analysis wraps typed compute an...test sourcelib.choir.src.passes.pass.testtest: PreservedAnalyses borrows compi...passes.AnalysisCacheinvalidate
Static calls · unresolved targets: 1 · external targets: 4.
Called byCallspasses.PassContextrefreshAnalysisprivate sourcelib.choir.src.passes.pass.analysis.AnalysisCacherequireRunningprivate sourcelib.choir.src.passes.pass.analysis.Computationbeginpasses.AnalysisCacherefresh
Static calls · unresolved targets: 3 · external targets: 4.
Called byCallsNo direct callspasses.AnalysisCacheinitAccountedtest sourcelib.choir.src.passes.pass.testtest: U0 analysis cache storage bound...passes.AnalysisCachestorageBound
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callspasses.PassContextincrementStatisticpasses.PassContextaddStatistic
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallstest sourcelib.choir.src.backends.gpu.nvptx.conversiontest: nvptx conversion lowers gpu idx...test sourcelib.choir.src.backends.gpu.nvptx.conversiontest: nvptx conversion rejects unknow...test sourcelib.choir.src.backends.gpu.spirv.conversiontest: gpu to spirv conversion rewrite...test sourcelib.choir.src.backends.gpu.spirv.conversiontest: spirv backend emits after gpu-t...test sourcelib.choir.src.backends.gpu.spirv.conversiontest: spirv conversion rejects unknow...+20 morepasses.PreservedAnalysesdeinitpasses.PassContextdeinit
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsprivate sourcelib.choir.src.passes.pass.testcheckContextAnalysisFailuretest sourcelib.choir.src.passes.pass.testtest: AnalysisCache invalidates based...test sourcelib.choir.src.passes.pass.testtest: PreservedAnalyses borrows compi...test sourcelib.choir.src.passes.pass.testtest: U0 analysis accounting records ...test sourcelib.choir.src.passes.pass.testtest: U0 analysis cache refuses its e...+4 morepasses.AnalysisCachegetOrComputepasses.PassContextgetAnalysis
Static calls · unresolved targets: 1 · external targets: 0.
Called byCallsNo direct callerspasses.PassContextaddStatisticpasses.PassContextincrementStatistic
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallstest sourcelib.choir.src.backends.gpu.nvptx.conversiontest: nvptx conversion lowers gpu idx...test sourcelib.choir.src.backends.gpu.nvptx.conversiontest: nvptx conversion rejects unknow...test sourcelib.choir.src.backends.gpu.spirv.conversiontest: gpu to spirv conversion rewrite...test sourcelib.choir.src.backends.gpu.spirv.conversiontest: spirv backend emits after gpu-t...test sourcelib.choir.src.backends.gpu.spirv.conversiontest: spirv conversion rejects unknow...+20 morepasses.PassContextinitWithOptionspasses.PassContextinit
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallstest sourcelib.choir.src.passes.pass.testtest: PassContext instruments analysi...test sourcelib.choir.src.passes.pass.testtest: U0 analysis admission refuses b...passes.PassContextinitWithInstrumentorAndOptionspasses.PassContextinitWithInstrumentor
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallspasses.PassContextinitWithInstrumentorpasses.PassContextinitWithOptionsprivate sourcelib.choir.src.passes.pass.manager.OpPassManagerrunPassEntrypasses.PreservedAnalysesinitpasses.PassContextinitWithInstrumentorAndOptions
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallspasses.PassContextinitprivate sourcelib.choir.src.passes.pass.testcheckWorkerAllocationFailurepasses.PassContextinitWithInstrumentorAndOptionspasses.PassContextinitWithOptions
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callerspasses.PreservedAnalysespreserveAllpasses.PassContextpreserveAllAnalyses
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callerspasses.PreservedAnalysespreserveAnalysispasses.PassContextpreserveAnalysis
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callerspasses.PreservedAnalysespreserveAnalysisSetpasses.PassContextpreserveAnalysisSet
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callerspasses.PreservedAnalysespreserveInterfacepasses.PassContextpreserveInterface
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsprivate sourcelib.choir.src.passes.pass.testcheckContextAnalysisFailuretest sourcelib.choir.src.passes.pass.testtest: U0 analysis caught workspace ex...test sourcelib.choir.src.passes.pass.testtest: U0 analysis refresh charges bef...passes.AnalysisCacherefreshpasses.PassContextrefreshAnalysis
Static calls · unresolved targets: 1 · external targets: 0.
Called byCallsNo direct callspasses.PassContextdeinittest sourcelib.choir.src.passes.pass.testtest: AnalysisCache invalidates based...test sourcelib.choir.src.passes.pass.testtest: Analysis wraps typed compute an...test sourcelib.choir.src.passes.pass.testtest: PreservedAnalyses borrows compi...passes.PreservedAnalysesdeinit
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsNo direct callspasses.PassContextinitWithInstrumentorAndOptionstest sourcelib.choir.src.passes.pass.testtest: AnalysisCache invalidates based...test sourcelib.choir.src.passes.pass.testtest: Analysis wraps typed compute an...test sourcelib.choir.src.passes.pass.testtest: PreservedAnalyses borrows compi...passes.PreservedAnalysesinit
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callspasses.PassContextpreserveAllAnalysespasses.PreservedAnalysespreserveAll
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callspasses.PassContextpreserveAnalysistest sourcelib.choir.src.passes.pass.testtest: PreservedAnalyses borrows compi...passes.PreservedAnalysespreserveAnalysis
Static calls · unresolved targets: 1 · external targets: 0.
Called byCallsNo direct callspasses.PassContextpreserveAnalysisSetpasses.PreservedAnalysespreserveAnalysisSet
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callspasses.PassContextpreserveInterfacetest sourcelib.choir.src.passes.pass.testtest: AnalysisCache invalidates based...passes.PreservedAnalysespreserveInterface
Static calls · unresolved targets: 1 · external targets: 0.
Called byCallsNo direct callsPassManageraddPasstest sourcelib.choir.src.passes.pass.testtest: Pass rerun identity is stateles...passes.OpPassManageraddPass
Static calls · unresolved targets: 1 · external targets: 1.
Called byCallsprivate sourcelib.choir.src.passes.pass.manager.PassManagerprepareDependentDialectsprivate sourcelib.choir.src.passes.pass.managerappendDependentDialectNamepasses.OpPassManagercollectDependentDialects
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsNo direct callsPassManagerdeinittest sourcelib.choir.src.passes.pass.testtest: OpPassManager basic nestingtest sourcelib.choir.src.passes.pass.testtest: OpPassManager supports op-agnos...test sourcelib.choir.src.passes.pass.testtest: Pass rerun identity is stateles...passes.OpPassManagerdeinit
Static calls · unresolved targets: 0 · external targets: 4.
Called byCallsNo direct callspasses.OpPassManagerrunOnOperationtest sourcelib.choir.src.passes.pass.testtest: OpPassManager basic nestingpasses.OpPassManagergetNestingDepth
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallspasses.OpPassManagernestPassManagerinittest sourcelib.choir.src.passes.pass.testtest: OpPassManager basic nestingtest sourcelib.choir.src.passes.pass.testtest: OpPassManager supports op-agnos...test sourcelib.choir.src.passes.pass.testtest: Pass rerun identity is stateles...passes.OpPassManagerinitWithTargetpasses.OpPassManagerinit
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallspasses.OpPassManagernestAnypasses.OpPassManagerinitWithTargetpasses.OpPassManagerinitAny
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsprivate sourcelib.choir.src.passes.pass.manager.OpPassManagercloneForParallelTargetpasses.OpPassManagerinitpasses.OpPassManagerinitAnypasses.OpPassManagerinitWithTarget
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsPassManagernesttest sourcelib.choir.src.passes.pass.testtest: OpPassManager basic nestingpasses.OpPassManagerinitpasses.OpPassManagernest
Static calls · unresolved targets: 1 · external targets: 1.
Called byCallsPassManagernestAnytest sourcelib.choir.src.passes.pass.testtest: OpPassManager supports op-agnos...passes.OpPassManagerinitAnypasses.OpPassManagernestAny
Static calls · unresolved targets: 1 · external targets: 1.
Called byCallsprivate sourcelib.choir.src.passes.pass.manager.OpPassManagerwalkAndRunSerialPassManagerrunToFixedPointWithOptionsPassManagerrunWithAnalysisCacheprivate sourcelib.choir.src.passes.pass.manager.OpPassManagercanRunOnTargetpasses.OpPassManagergetNestingDepthprivate sourcelib.choir.src.passes.pass.manager.OpPassManagerinstrumentationTargetNameprivate sourcelib.choir.src.passes.pass.manager.OpPassManagermatchesScheduledOpprivate sourcelib.choir.src.passes.pass.manager.OpPassManagerrunPipelineEntriesprivate sourcelib.choir.src.passes.pass.managerrecordPassFailurepasses.OpPassManagerrunOnOperation
Static calls · unresolved targets: 0 · external targets: 3.

Source: lib/choir/src/passes/pass/model.zig:42

zig
pub const AnalysisId = u64;

Source: lib/choir/src/passes/pass/model.zig:20

zig
pub const DependentDialects = []const []const u8;
Called byCallsNo direct callsPassManagerresetStatspasses.PassManagerStatsreset
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/choir/src/passes/pass/model.zig:44

zig
pub fn analysisId(comptime name: []const u8) AnalysisId {    return ir.interfaceId(name);}
Called byCallsNo direct callspassesAnalysisprivate sourcelib.choir.src.passes.pass.testpreserveCompileTimeTestAnalysisSettest sourcelib.choir.src.passes.pass.testtest: AnalysisCache invalidates based...test sourcelib.choir.src.passes.pass.testtest: Analysis wraps typed compute an...test sourcelib.choir.src.passes.pass.testtest: PassContext instruments analysi...+7 morepassesanalysisId
Static calls · unresolved targets: 0 · external targets: 1.

Source: lib/choir/src/passes/pass/model.zig:22

zig
pub fn dialectDependencies(comptime names: DependentDialects) DependentDialects {    comptime {        for (names, 0..) |name, index| {            if (name.len == 0) @compileError("dependent dialect name cannot be empty");            for (names[0..index]) |prior| {                if (std.mem.eql(u8, name, prior)) @compileError("duplicate dependent dialect name");            }        }    }    return names;}
Called byCallsNo direct callstest sourcelib.choir.src.passes.pass.testtest: OpPassManager collects dependen...test sourcelib.choir.src.passes.pass.test.test_PassManagerrunToFixedPoint preloads dependent di...test sourcelib.choir.src.passes.pass.testtest: PassManager fails before runnin...test sourcelib.choir.src.passes.pass.testtest: PassManager preloads dependent ...passesdialectDependencies
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/choir/src/passes/pass/operation.zig:10

zig
pub fn OperationPass(    comptime OpType: type,    comptime run_on_op: fn (*OpType, *PassContext) PassResult,) type {    return struct {        base: Pass,        const Self = @This();        pub fn init(            name: []const u8,            description: []const u8,        ) Self {            return initWithMutationScope(name, description, .whole_module);        }        pub fn initWithMutationScope(            name: []const u8,            description: []const u8,            mutation_scope: PassMutationScope,        ) Self {            return .{                .base = .{                    .name = name,                    .description = description,                    .run_fn = &runImpl,                    .mutation_scope = mutation_scope,                },            };        }        fn runImpl(ctx: *PassContext) PassResult {            return walkAndApply(ctx.op, ctx);        }        fn walkAndApply(op: *ir.Operation, ctx: *PassContext) PassResult {            if (std.mem.eql(u8, op.name.name, OpType.operation_name)) {                var typed_op = OpType{ .op = op };                const result = run_on_op(&typed_op, ctx);                if (result == .failure) {                    return .failure;                }            }            for (op.regions.items) |*region| {                var block_iter = region.getBlocks();                while (block_iter.next()) |block| {                    var current_op: ?*ir.Operation = @ptrCast(@alignCast(block.operations.head));                    while (current_op) |nested_op| {                        const result = walkAndApply(nested_op, ctx);                        if (result == .failure) {                            return .failure;                        }                        current_op = nested_op.next_op;                    }                }            }            return .success;        }    };}
Called byCallsNo direct callstest sourcelib.choir.src.passes.pass.testtest: OperationPass stops on failuretest sourcelib.choir.src.passes.pass.testtest: OperationPass walks and matches...passesOperationPass
Static calls · unresolved targets: 4 · external targets: 2.

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

zig
pub const work = @import("work.zig");const model = @import("model.zig");const base = @import("base.zig");const analysis = @import("analysis.zig");const manager = @import("manager.zig");const operation = @import("operation.zig");pub const PassMutationScope = model.PassMutationScope;pub const PassStateConcurrency = model.PassStateConcurrency;pub const PassRerunPolicy = model.PassRerunPolicy;pub const DependentDialects = model.DependentDialects;pub const dialectDependencies = model.dialectDependencies;pub const Pass = base.Pass;pub const PassManagerRunOptions = model.PassManagerRunOptions;pub const PassManagerFixedPointResult = model.PassManagerFixedPointResult;pub const AnalysisId = model.AnalysisId;pub const analysisId = model.analysisId;pub const AnalysisDescriptor = analysis.AnalysisDescriptor;pub const Analysis = analysis.Analysis;pub const PassManagerStats = model.PassManagerStats;pub const PassVerifierFailure = model.PassVerifierFailure;pub const PassFailureKind = model.PassFailureKind;pub const PassFailureReproducer = model.PassFailureReproducer;pub const PreservedAnalyses = analysis.PreservedAnalyses;pub const AnalysisCache = analysis.AnalysisCache;pub const PassContext = analysis.PassContext;pub const PassResult = model.PassResult;pub const PipelineEntry = manager.PipelineEntry;pub const OpPassManagerTargetKind = manager.OpPassManagerTargetKind;pub const OpPassManager = manager.OpPassManager;pub const PassManager = manager.PassManager;pub const OperationPass = operation.OperationPass;

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

zig
pub const pass = @import("pass/root.zig");

Complete caller list for passes.AnalysisCache.deinit

12 direct callers.

Complete caller list for passes.AnalysisCache.init

12 direct callers.

Complete caller list for passes.AnalysisCache.initAccounted

22 direct callers.

Complete caller list for passes.PassContext.deinit

25 direct callers.

Complete caller list for passes.PassContext.getAnalysis

9 direct callers.

Complete caller list for passes.PassContext.init

25 direct callers.

Complete caller list for passes.analysisId

12 direct callers.

Audit

Definitions64
Public names126
Members73
Version26.7.0
Revisiondaab053ee433