tiny.choir.passes.pass
Defined in passes.
API (67)
Actions
Public operations.
AnalysisAnalysisCache.deinitAnalysisCache.getOrComputeAnalysisCache.initAnalysisCache.initAccounted: The ledger outlives this fresh cache and every computation using it.AnalysisCache.invalidateAnalysisCache.refresh: Refresh replaces the cached value in place; failure must leave it intact.AnalysisCache.storageBound: Bounds the pinned HashMap header, aligned keys/values and one-byte slot metadata.OpPassManager.addPassOpPassManager.collectDependentDialectsOpPassManager.deinitOpPassManager.getNestingDepthOpPassManager.initOpPassManager.initAnyOpPassManager.initWithTargetOpPassManager.nestOpPassManager.nestAnyOpPassManager.runOnOperationOperationPassPassContext.addStatisticPassContext.deinitPassContext.getAnalysisPassContext.incrementStatisticPassContext.initPassContext.initWithInstrumentorPassContext.initWithInstrumentorAndOptionsPassContext.initWithOptionsPassContext.markModifiedPassContext.preserveAllAnalysesPassContext.preserveAnalysisPassContext.preserveAnalysisSetPassContext.preserveInterfacePassContext.refreshAnalysisPassContext.workerAllocatorPassContext.workerCountPassFailureReproducer.deinitPassManagerStats.resetPreservedAnalyses.deinitPreservedAnalyses.initPreservedAnalyses.preserveAllPreservedAnalyses.preserveAnalysisPreservedAnalyses.preserveAnalysisSetPreservedAnalyses.preserveInterfaceanalysisIddialectDependencies
Types and contracts
Public types and contracts.
AnalysisCacheAnalysisDescriptorAnalysisIdDependentDialectsOpPassManagerOpPassManagerTargetKindPassPassContextPassFailureKindPassFailureReproducerPassManagerPassManagerFixedPointResultPassManagerRunOptionsPassManagerStatsPassMutationScopePassRerunPolicyPassResultPassStateConcurrencyPassVerifierFailurePipelineEntryPreservedAnalyses
Namespaces
Public namespaces.
Source
Source: lib/choir/src/passes/pass/analysis.zig:129
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
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
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
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
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
pub const OpPassManagerTargetKind = enum { root, any, op,};Source: lib/choir/src/passes/pass/manager.zig:131
pub const PipelineEntry = union(enum) { pass: Pass, nested: *OpPassManager,};Source: lib/choir/src/passes/pass/model.zig:69
pub const PassFailureKind = enum { pass, verifier, target, exhausted,};Source: lib/choir/src/passes/pass/model.zig:76
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
pub const PassManagerFixedPointResult = struct { result: PassResult = .success, iterations: usize = 0, changed: bool = false,};Source: lib/choir/src/passes/pass/model.zig:48
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
pub const PassMutationScope = enum { read_only, isolated, whole_module,};Source: lib/choir/src/passes/pass/model.zig:15
pub const PassRerunPolicy = enum { always, skip_if_unchanged,};Source: lib/choir/src/passes/pass/model.zig:100
pub const PassResult = enum { success, failure,};Source: lib/choir/src/passes/pass/model.zig:10
pub const PassStateConcurrency = enum { exclusive, shared,};Source: lib/choir/src/passes/pass/model.zig:63
pub const PassVerifierFailure = struct { pass_name: []const u8, target_op_name: []const u8, err: anyerror,};Source: lib/choir/src/passes/pass/analysis.zig:23
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); } } };}Source: lib/choir/src/passes/pass/model.zig:42
pub const AnalysisId = u64;Source: lib/choir/src/passes/pass/model.zig:20
pub const DependentDialects = []const []const u8;Source: lib/choir/src/passes/pass/model.zig:44
pub fn analysisId(comptime name: []const u8) AnalysisId { return ir.interfaceId(name);}Source: lib/choir/src/passes/pass/model.zig:22
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;}Source: lib/choir/src/passes/pass/operation.zig:10
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; } };}Source: lib/choir/src/passes/pass/root.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
pub const pass = @import("pass/root.zig");Complete caller list for passes.AnalysisCache.deinit
12 direct callers.
tiny.choir.PassManager.runToFixedPointWithOptions[method] atlib/choir/src/passes/pass/manager.zig:941tiny.choir.PassManager.runWithOptions[method] atlib/choir/src/passes/pass/manager.zig:864lib.choir.src.passes.pass.manager.runParallelTarget[function] — private source atlib/choir/src/passes/pass/manager.zig:1145in nearest public ownerlib.choir.src.passes.pass.managerlib.choir.src.passes.pass.test.expectFailedMutationCache[function] — private source atlib/choir/src/passes/pass/test.zig:530in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_AnalysisCache_cleans_computed_values_after_insertion_failure[function] — test source atlib/choir/src/passes/pass/test.zig:454in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_AnalysisCache_invalidates_based_on_preserved_interfaces[function] — test source atlib/choir/src/passes/pass/test.zig:289in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_Analysis_wraps_typed_compute_and_cleanup_callbacks[function] — test source atlib/choir/src/passes/pass/test.zig:400in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_OperationPass_stops_on_failure[function] — test source atlib/choir/src/passes/pass/test.zig:179in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_OperationPass_walks_and_matches_operations[function] — test source atlib/choir/src/passes/pass/test.zig:129in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_PassContext_instruments_analysis_computation_misses[function] — test source atlib/choir/src/passes/pass/test.zig:348in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_PassManager.runWithAnalysisCache_leaves_caller_cache_reusable[function] — test source atlib/choir/src/passes/pass/test.zig:620in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_PreservedAnalyses_borrows_compile-time_analysis_sets[function] — test source atlib/choir/src/passes/pass/test.zig:227in nearest public ownerlib.choir.src.passes.pass.test
Complete caller list for passes.AnalysisCache.init
12 direct callers.
tiny.choir.PassManager.runToFixedPointWithOptions[method] atlib/choir/src/passes/pass/manager.zig:941tiny.choir.PassManager.runWithOptions[method] atlib/choir/src/passes/pass/manager.zig:864lib.choir.src.passes.pass.manager.runParallelTarget[function] — private source atlib/choir/src/passes/pass/manager.zig:1145in nearest public ownerlib.choir.src.passes.pass.managerlib.choir.src.passes.pass.test.expectFailedMutationCache[function] — private source atlib/choir/src/passes/pass/test.zig:530in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_AnalysisCache_cleans_computed_values_after_insertion_failure[function] — test source atlib/choir/src/passes/pass/test.zig:454in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_AnalysisCache_invalidates_based_on_preserved_interfaces[function] — test source atlib/choir/src/passes/pass/test.zig:289in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_Analysis_wraps_typed_compute_and_cleanup_callbacks[function] — test source atlib/choir/src/passes/pass/test.zig:400in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_OperationPass_stops_on_failure[function] — test source atlib/choir/src/passes/pass/test.zig:179in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_OperationPass_walks_and_matches_operations[function] — test source atlib/choir/src/passes/pass/test.zig:129in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_PassContext_instruments_analysis_computation_misses[function] — test source atlib/choir/src/passes/pass/test.zig:348in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_PassManager.runWithAnalysisCache_leaves_caller_cache_reusable[function] — test source atlib/choir/src/passes/pass/test.zig:620in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_PreservedAnalyses_borrows_compile-time_analysis_sets[function] — test source atlib/choir/src/passes/pass/test.zig:227in nearest public ownerlib.choir.src.passes.pass.test
Complete caller list for passes.AnalysisCache.initAccounted
22 direct callers.
lib.choir.src.passes.pass.test.checkContextAnalysisFailure[function] — private source atlib/choir/src/passes/pass/test.zig:3885in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.checkContextPassFailure[function] — private source atlib/choir/src/passes/pass/test.zig:3772in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.checkWorkerAllocationFailure[function] — private source atlib/choir/src/passes/pass/test.zig:4157in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_accounting_records_computations_and_hits_without_charging_a_second_computation[function] — test source atlib/choir/src/passes/pass/test.zig:3119in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_admission_refuses_before_computation_and_keeps_the_exhausted_charge[function] — test source atlib/choir/src/passes/pass/test.zig:3068in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_cache_refuses_its_entry_limit_before_the_next_computation_without_table_growth[function] — test source atlib/choir/src/passes/pass/test.zig:3495in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_cache_reserves_its_declared_table_before_computations[function] — test source atlib/choir/src/passes/pass/test.zig:3410in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_cache_storage_bound_covers_real_table_allocation_and_teardown[function] — test source atlib/choir/src/passes/pass/test.zig:3462in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_caught_workspace_exhaustion_refuses_computation_results_hits_and_refresh[function] — test source atlib/choir/src/passes/pass/test.zig:4016in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_computation_failure_stays_charged_and_cannot_retry_the_same_request[function] — test source atlib/choir/src/passes/pass/test.zig:3211in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_fixed_workspace_exhaustion_retains_cleanup_and_refuses_a_fresh_retry[function] — test source atlib/choir/src/passes/pass/test.zig:3364in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_host_OOM_before_workspace_allocation_stays_rejected[function] — test source atlib/choir/src/passes/pass/test.zig:4079in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_missing_contract_permits_transient_computation_and_refuses_qualification[function] — test source atlib/choir/src/passes/pass/test.zig:3173in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_refresh_charges_before_replacing_a_cached_value[function] — test source atlib/choir/src/passes/pass/test.zig:3270in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_refuses_setup_after_Context_exhaustion_without_acquiring_cache_storage[function] — test source atlib/choir/src/passes/pass/test.zig:3848in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_typed_registration_carries_its_normative_declaration[function] — test source atlib/choir/src/passes/pass/test.zig:3337in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_pass_accounting_executes_repeated_entries_and_records_one_cached_analysis_computation[function] — test source atlib/choir/src/passes/pass/test.zig:3611in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_pass_admission_refuses_before_the_callback_and_uses_the_existing_failure_finalization[function] — test source atlib/choir/src/passes/pass/test.zig:3549in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_pass_caught_workspace_exhaustion_stops_subsequent_callbacks_through_one_finalizer[function] — test source atlib/choir/src/passes/pass/test.zig:3944in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_pass_missing_contract_records_successful_and_failed_physical_callbacks_without_qualification[function] — test source atlib/choir/src/passes/pass/test.zig:3725in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_pass_propagates_analysis_exhaustion_even_when_native_code_reports_success[function] — test source atlib/choir/src/passes/pass/test.zig:3653in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_pass_refuses_scheduling_outside_the_declared_serial_job_before_its_callback[function] — test source atlib/choir/src/passes/pass/test.zig:3695in nearest public ownerlib.choir.src.passes.pass.test
Complete caller list for passes.PassContext.deinit
25 direct callers.
lib.choir.src.backends.gpu.nvptx.conversion.test_nvptx_conversion_lowers_gpu_idx_and_memref_ops[function] — test source atlib/choir/src/backends/gpu/nvptx/conversion.zig:546in nearest public ownertiny.choir.backends.gpu.nvptx.conversionlib.choir.src.backends.gpu.nvptx.conversion.test_nvptx_conversion_rejects_unknown_target_ops[function] — test source atlib/choir/src/backends/gpu/nvptx/conversion.zig:690in nearest public ownertiny.choir.backends.gpu.nvptx.conversionlib.choir.src.backends.gpu.spirv.conversion.test_gpu_to_spirv_conversion_rewrites_gpu_+_arith_ops[function] — test source atlib/choir/src/backends/gpu/spirv/conversion.zig:431in nearest public ownertiny.choir.backends.gpu.spirv.conversionlib.choir.src.backends.gpu.spirv.conversion.test_spirv_backend_emits_after_gpu-to-spirv_conversion[function] — test source atlib/choir/src/backends/gpu/spirv/conversion.zig:501in nearest public ownertiny.choir.backends.gpu.spirv.conversionlib.choir.src.backends.gpu.spirv.conversion.test_spirv_conversion_rejects_unknown_target_ops[function] — test source atlib/choir/src/backends/gpu/spirv/conversion.zig:547in nearest public ownertiny.choir.backends.gpu.spirv.conversionlib.choir.src.passes.optimizations.expectUnmodifiedCleanupPreservesAll[function] — private source atlib/choir/src/passes/optimizations.zig:230in nearest public ownertiny.choir.passes.optimizationslib.choir.src.passes.optimizations.test_choir-sccp_no-op_path_uses_no_pass_allocator[function] — test source atlib/choir/src/passes/optimizations.zig:1527in nearest public ownertiny.choir.passes.optimizationslib.choir.src.passes.pass.test.checkContextAnalysisFailure[function] — private source atlib/choir/src/passes/pass/test.zig:3885in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.checkContextPassFailure[function] — private source atlib/choir/src/passes/pass/test.zig:3772in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.expectFailedMutationCache[function] — private source atlib/choir/src/passes/pass/test.zig:530in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_AnalysisCache_cleans_computed_values_after_insertion_failure[function] — test source atlib/choir/src/passes/pass/test.zig:454in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_AnalysisCache_invalidates_based_on_preserved_interfaces[function] — test source atlib/choir/src/passes/pass/test.zig:289in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_Analysis_wraps_typed_compute_and_cleanup_callbacks[function] — test source atlib/choir/src/passes/pass/test.zig:400in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_OperationPass_stops_on_failure[function] — test source atlib/choir/src/passes/pass/test.zig:179in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_OperationPass_walks_and_matches_operations[function] — test source atlib/choir/src/passes/pass/test.zig:129in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_PassManager.runWithAnalysisCache_leaves_caller_cache_reusable[function] — test source atlib/choir/src/passes/pass/test.zig:620in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_PreservedAnalyses_borrows_compile-time_analysis_sets[function] — test source atlib/choir/src/passes/pass/test.zig:227in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_accounting_records_computations_and_hits_without_charging_a_second_computation[function] — test source atlib/choir/src/passes/pass/test.zig:3119in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_cache_refuses_its_entry_limit_before_the_next_computation_without_table_growth[function] — test source atlib/choir/src/passes/pass/test.zig:3495in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_caught_workspace_exhaustion_refuses_computation_results_hits_and_refresh[function] — test source atlib/choir/src/passes/pass/test.zig:4016in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_computation_failure_stays_charged_and_cannot_retry_the_same_request[function] — test source atlib/choir/src/passes/pass/test.zig:3211in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_fixed_workspace_exhaustion_retains_cleanup_and_refuses_a_fresh_retry[function] — test source atlib/choir/src/passes/pass/test.zig:3364in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_missing_contract_permits_transient_computation_and_refuses_qualification[function] — test source atlib/choir/src/passes/pass/test.zig:3173in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_refresh_charges_before_replacing_a_cached_value[function] — test source atlib/choir/src/passes/pass/test.zig:3270in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_typed_registration_carries_its_normative_declaration[function] — test source atlib/choir/src/passes/pass/test.zig:3337in nearest public ownerlib.choir.src.passes.pass.test
Complete caller list for passes.PassContext.getAnalysis
9 direct callers.
lib.choir.src.passes.pass.test.checkContextAnalysisFailure[function] — private source atlib/choir/src/passes/pass/test.zig:3885in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_AnalysisCache_invalidates_based_on_preserved_interfaces[function] — test source atlib/choir/src/passes/pass/test.zig:289in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_PreservedAnalyses_borrows_compile-time_analysis_sets[function] — test source atlib/choir/src/passes/pass/test.zig:227in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_accounting_records_computations_and_hits_without_charging_a_second_computation[function] — test source atlib/choir/src/passes/pass/test.zig:3119in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_cache_refuses_its_entry_limit_before_the_next_computation_without_table_growth[function] — test source atlib/choir/src/passes/pass/test.zig:3495in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_caught_workspace_exhaustion_refuses_computation_results_hits_and_refresh[function] — test source atlib/choir/src/passes/pass/test.zig:4016in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_computation_failure_stays_charged_and_cannot_retry_the_same_request[function] — test source atlib/choir/src/passes/pass/test.zig:3211in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_missing_contract_permits_transient_computation_and_refuses_qualification[function] — test source atlib/choir/src/passes/pass/test.zig:3173in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_refresh_charges_before_replacing_a_cached_value[function] — test source atlib/choir/src/passes/pass/test.zig:3270in nearest public ownerlib.choir.src.passes.pass.test
Complete caller list for passes.PassContext.init
25 direct callers.
lib.choir.src.backends.gpu.nvptx.conversion.test_nvptx_conversion_lowers_gpu_idx_and_memref_ops[function] — test source atlib/choir/src/backends/gpu/nvptx/conversion.zig:546in nearest public ownertiny.choir.backends.gpu.nvptx.conversionlib.choir.src.backends.gpu.nvptx.conversion.test_nvptx_conversion_rejects_unknown_target_ops[function] — test source atlib/choir/src/backends/gpu/nvptx/conversion.zig:690in nearest public ownertiny.choir.backends.gpu.nvptx.conversionlib.choir.src.backends.gpu.spirv.conversion.test_gpu_to_spirv_conversion_rewrites_gpu_+_arith_ops[function] — test source atlib/choir/src/backends/gpu/spirv/conversion.zig:431in nearest public ownertiny.choir.backends.gpu.spirv.conversionlib.choir.src.backends.gpu.spirv.conversion.test_spirv_backend_emits_after_gpu-to-spirv_conversion[function] — test source atlib/choir/src/backends/gpu/spirv/conversion.zig:501in nearest public ownertiny.choir.backends.gpu.spirv.conversionlib.choir.src.backends.gpu.spirv.conversion.test_spirv_conversion_rejects_unknown_target_ops[function] — test source atlib/choir/src/backends/gpu/spirv/conversion.zig:547in nearest public ownertiny.choir.backends.gpu.spirv.conversionlib.choir.src.passes.optimizations.expectUnmodifiedCleanupPreservesAll[function] — private source atlib/choir/src/passes/optimizations.zig:230in nearest public ownertiny.choir.passes.optimizationslib.choir.src.passes.optimizations.test_choir-sccp_no-op_path_uses_no_pass_allocator[function] — test source atlib/choir/src/passes/optimizations.zig:1527in nearest public ownertiny.choir.passes.optimizationslib.choir.src.passes.pass.test.checkContextAnalysisFailure[function] — private source atlib/choir/src/passes/pass/test.zig:3885in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.checkContextPassFailure[function] — private source atlib/choir/src/passes/pass/test.zig:3772in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.expectFailedMutationCache[function] — private source atlib/choir/src/passes/pass/test.zig:530in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_AnalysisCache_cleans_computed_values_after_insertion_failure[function] — test source atlib/choir/src/passes/pass/test.zig:454in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_AnalysisCache_invalidates_based_on_preserved_interfaces[function] — test source atlib/choir/src/passes/pass/test.zig:289in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_Analysis_wraps_typed_compute_and_cleanup_callbacks[function] — test source atlib/choir/src/passes/pass/test.zig:400in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_OperationPass_stops_on_failure[function] — test source atlib/choir/src/passes/pass/test.zig:179in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_OperationPass_walks_and_matches_operations[function] — test source atlib/choir/src/passes/pass/test.zig:129in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_PassManager.runWithAnalysisCache_leaves_caller_cache_reusable[function] — test source atlib/choir/src/passes/pass/test.zig:620in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_PreservedAnalyses_borrows_compile-time_analysis_sets[function] — test source atlib/choir/src/passes/pass/test.zig:227in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_accounting_records_computations_and_hits_without_charging_a_second_computation[function] — test source atlib/choir/src/passes/pass/test.zig:3119in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_cache_refuses_its_entry_limit_before_the_next_computation_without_table_growth[function] — test source atlib/choir/src/passes/pass/test.zig:3495in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_caught_workspace_exhaustion_refuses_computation_results_hits_and_refresh[function] — test source atlib/choir/src/passes/pass/test.zig:4016in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_computation_failure_stays_charged_and_cannot_retry_the_same_request[function] — test source atlib/choir/src/passes/pass/test.zig:3211in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_fixed_workspace_exhaustion_retains_cleanup_and_refuses_a_fresh_retry[function] — test source atlib/choir/src/passes/pass/test.zig:3364in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_missing_contract_permits_transient_computation_and_refuses_qualification[function] — test source atlib/choir/src/passes/pass/test.zig:3173in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_refresh_charges_before_replacing_a_cached_value[function] — test source atlib/choir/src/passes/pass/test.zig:3270in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_typed_registration_carries_its_normative_declaration[function] — test source atlib/choir/src/passes/pass/test.zig:3337in nearest public ownerlib.choir.src.passes.pass.test
Complete caller list for passes.analysisId
12 direct callers.
tiny.choir.passes.Analysis[function] atlib/choir/src/passes/pass/analysis.zig:23lib.choir.src.passes.pass.test.preserveCompileTimeTestAnalysisSet[function] — private source atlib/choir/src/passes/pass/test.zig:220in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_AnalysisCache_invalidates_based_on_preserved_interfaces[function] — test source atlib/choir/src/passes/pass/test.zig:289in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_Analysis_wraps_typed_compute_and_cleanup_callbacks[function] — test source atlib/choir/src/passes/pass/test.zig:400in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_PassContext_instruments_analysis_computation_misses[function] — test source atlib/choir/src/passes/pass/test.zig:348in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_PreservedAnalyses_borrows_compile-time_analysis_sets[function] — test source atlib/choir/src/passes/pass/test.zig:227in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_accounting_records_computations_and_hits_without_charging_a_second_computation[function] — test source atlib/choir/src/passes/pass/test.zig:3119in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_admission_refuses_before_computation_and_keeps_the_exhausted_charge[function] — test source atlib/choir/src/passes/pass/test.zig:3068in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_cache_refuses_its_entry_limit_before_the_next_computation_without_table_growth[function] — test source atlib/choir/src/passes/pass/test.zig:3495in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_computation_failure_stays_charged_and_cannot_retry_the_same_request[function] — test source atlib/choir/src/passes/pass/test.zig:3211in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_missing_contract_permits_transient_computation_and_refuses_qualification[function] — test source atlib/choir/src/passes/pass/test.zig:3173in nearest public ownerlib.choir.src.passes.pass.testlib.choir.src.passes.pass.test.test_U0_analysis_refresh_charges_before_replacing_a_cached_value[function] — test source atlib/choir/src/passes/pass/test.zig:3270in nearest public ownerlib.choir.src.passes.pass.test
Audit
| Definitions | 64 |
|---|---|
| Public names | 126 |
| Members | 73 |
| Version | 26.7.0 |
| Revision | daab053ee433 |