tiny.choir.inspection
Defined in tiny.choir.
API (8)
Actions
Public operations.
countOperationsNamedfindOperationNamedfunctionByNamefunctionByNameInBlockfunctionDefinitionByNamefunctionDefinitionByNameInBlockisFunctionDefinitionmoduleBodyBlock
Source
Source: lib/choir/src/core/inspection.zig
zig
const std = @import("std");const alloc_arena = @import("alloc_arena");const Operation = @import("operation/root.zig").Operation;const Block = @import("block.zig").Block;const interfaces = @import("interfaces/root.zig");pub fn countOperationsNamed(root: *Operation, name: []const u8) usize { var state = CountNamed{ .name = name }; _ = root.walk(.{ .order = .pre_order }, &state, CountNamed.visit) catch unreachable; return state.count;}pub fn findOperationNamed(root: *Operation, name: []const u8) ?*Operation { var state = FindNamed{ .name = name }; _ = root.walk(.{ .order = .pre_order }, &state, FindNamed.visit) catch unreachable; return state.found;}pub fn moduleBodyBlock(module: *Operation) ?*Block { const region = module.getRegion(0) orelse return null; return region.getEntryBlock();}pub fn isFunctionDefinition(op: *Operation) bool { const iface = functionInterface(op) orelse return false; return iface.call(.hasBody, .{});}pub fn functionByName(module: *Operation, name: []const u8) ?*Operation { const block = moduleBodyBlock(module) orelse return null; return functionByNameInBlock(block, name);}pub fn functionByNameInBlock(block: *Block, name: []const u8) ?*Operation { var ops = block.getOperations(); while (ops.next()) |op| { if (functionInterface(op) == null) continue; const symbol_name = symbolName(op) orelse continue; if (std.mem.eql(u8, symbol_name, name)) return op; } return null;}pub fn functionDefinitionByName(module: *Operation, name: []const u8) ?*Operation { const block = moduleBodyBlock(module) orelse return null; return functionDefinitionByNameInBlock(block, name);}pub fn functionDefinitionByNameInBlock(block: *Block, name: []const u8) ?*Operation { var ops = block.getOperations(); while (ops.next()) |op| { if (!isFunctionDefinition(op)) continue; const symbol_name = symbolName(op) orelse continue; if (std.mem.eql(u8, symbol_name, name)) return op; } return null;}fn functionInterface(op: *Operation) ?Operation.interface_handle(interfaces.FunctionOpInterface) { if (symbolName(op) == null) return null; return op.interface(interfaces.FunctionOpInterface);}fn symbolName(op: *Operation) ?[]const u8 { const iface = op.interface(interfaces.SymbolOpInterface) orelse return null; return iface.call(.getSymbolName, .{});}const CountNamed = struct { name: []const u8, count: usize = 0, fn visit(self: *CountNamed, op: *Operation) void { if (std.mem.eql(u8, op.name.name, self.name)) { self.count += 1; } }};const FindNamed = struct { name: []const u8, found: ?*Operation = null, fn visit(self: *FindNamed, op: *Operation) void { if (self.found != null) return; if (std.mem.eql(u8, op.name.name, self.name)) { self.found = op; } }};test "inspection counts operations by name" { const testing = std.testing; const dialects = @import("../dialects/root.zig"); const test_dialect = @import("../dialects/fixture/root.zig"); const ir = @import("root.zig"); var arena = alloc_arena.Arena.init(testing.allocator); defer arena.deinit(); var ctx = try ir.Context.init(arena.allocator(), ir.Context.Limits.testing); defer ctx.deinit(arena.allocator()); try ctx.allowUnregistered(); try test_dialect.registerTestDialect(&ctx); const loc = ir.Location.getUnknown(); const module = try dialects.BuiltinDialect.ModuleOp.create(&ctx, loc); const block = module.getBodyBlock(); const left = try ctx.createOperation(ir.Operation.State.init("test.leaf", loc)); const right = try ctx.createOperation(ir.Operation.State.init("test.leaf", loc)); const other = try ctx.createOperation(ir.Operation.State.init("test.other", loc)); try block.addOperation(left); try block.addOperation(other); try block.addOperation(right); try testing.expectEqual(@as(usize, 2), countOperationsNamed(module.op, "test.leaf")); try testing.expectEqual(@as(usize, 1), countOperationsNamed(module.op, "test.other")); try testing.expectEqual(@as(usize, 0), countOperationsNamed(module.op, "test.missing")); try testing.expect(findOperationNamed(module.op, "test.leaf") == left); try testing.expect(findOperationNamed(module.op, "test.other") == other); try testing.expect(findOperationNamed(module.op, "test.missing") == null);}test "inspection finds function definitions by symbol name" { const testing = std.testing; const dialects = @import("../dialects/root.zig"); const ir = @import("root.zig"); var arena = alloc_arena.Arena.init(testing.allocator); defer arena.deinit(); var ctx = try ir.Context.init(arena.allocator(), ir.Context.Limits.testing); defer ctx.deinit(arena.allocator()); const loc = ir.Location.getUnknown(); const module = try dialects.BuiltinDialect.ModuleOp.create(&ctx, loc); const block = module.getBodyBlock(); const body = try dialects.FuncDialect.FuncOp.create(&ctx, loc, "body", &.{}, &.{}); const declaration = try dialects.FuncDialect.FuncOp.createDeclaration(&ctx, loc, "declaration", &.{}, &.{}); try block.addOperation(declaration.op); try block.addOperation(body.op); try testing.expect(functionByName(module.op, "body") == body.op); try testing.expect(functionByNameInBlock(block, "body") == body.op); try testing.expect(functionByName(module.op, "declaration") == declaration.op); try testing.expect(functionDefinitionByName(module.op, "body") == body.op); try testing.expect(functionDefinitionByNameInBlock(block, "body") == body.op); try testing.expect(functionDefinitionByName(module.op, "declaration") == null); try testing.expect(functionByName(module.op, "missing") == null);}Source: lib/choir/src/root.zig:54
zig
pub const inspection = ir.inspection;Also reachable as
backends.wasm.emission.module_encoding.common.ir.inspection, ir.inspection.
Complete caller list for inspection.countOperationsNamed
7 direct callers.
lib.choir.src.backends.gpu.cpu.test.Lowered.count[method] — private source atlib/choir/src/backends/gpu/cpu/test.zig:60in nearest public ownerlib.choir.src.backends.gpu.cpu.testlib.choir.src.backends.gpu.cpu.test.test_a_derivative_of_a_helper's_result_calls_the_shared_helper_again_at_each_partner[function] — test source atlib/choir/src/backends/gpu/cpu/test.zig:262in nearest public ownerlib.choir.src.backends.gpu.cpu.testlib.choir.src.backends.gpu.cpu.test.test_a_fragment_that_takes_derivatives_lowers_to_a_quad_function_sharing_each_partner_slice[function] — test source atlib/choir/src/backends/gpu/cpu/test.zig:249in nearest public ownerlib.choir.src.backends.gpu.cpu.testlib.choir.src.backends.gpu.cpu.test.test_stage_calls_retain_shared_and_nested_helpers_in_the_CPU_twin[function] — test source atlib/choir/src/backends/gpu/cpu/test.zig:199in nearest public ownerlib.choir.src.backends.gpu.cpu.testlib.choir.src.backends.gpu.cpu.test.test_stage_local_array_survives_CPU_lowering_and_runs_from_host_stack[function] — test source atlib/choir/src/backends/gpu/cpu/test.zig:178in nearest public ownerlib.choir.src.backends.gpu.cpu.testlib.choir.src.backends.gpu.cpu.test.test_stage_lowering_turns_each_stage_into_a_host_function_over_the_stage_buffers[function] — test source atlib/choir/src/backends/gpu/cpu/test.zig:165in nearest public ownerlib.choir.src.backends.gpu.cpu.testlib.choir.src.core.inspection.test_inspection_counts_operations_by_name[function] — test source atlib/choir/src/core/inspection.zig:92in nearest public ownertiny.choir.inspection
Audit
| Definitions | 9 |
|---|---|
| Public names | 27 |
| Members | 0 |
| Version | 26.7.0 |
| Revision | daab053ee433 |