Skip to documentation
SLOP

tiny.choir.ir.rewrite

Reference tiny.choir ir rewrite

Defined in ir.

API (96)

Actions

Public operations.

Types and contracts

Public types and contracts.

Values and defaults

Public values and defaults.

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

Source

Source: lib/choir/src/core/rewrite/index.zig:88

zig
pub const PatternIndex = struct {    pub const claim: alloc_phase.capacity.Declaration = .{        .source = .{            .id = "choir.rewrite_pattern_index",            .kind = .phase_static,            .limit_source = .caller,            .storage = .{                .covered = &.{                    .{                        .id = "load_bounded_rewrite_root_slots_and_exact_sealed_pattern_groups",                        .lifetime = .steady,                        .detail = "load-bounded rewrite-root slots and exact sealed pattern groups",                    },                },                .excluded = &.{                    "geometrically grown rewrite-pattern builder storage",                    "borrowed root names, rewrite callbacks, IR, and pattern-rewriter state",                },            },            .capacity = .{                .inputs = &.{                    alloc_phase.capacity.bindInput(Limits, "patterns", "patterns"),                },                .type_selectors = &.{                    alloc_phase.capacity.bindType(PatternRootSlot, "rootslot"),                    alloc_phase.capacity.bindType(RewritePattern, "rewritepattern"),                },                .nodes = &.{                    .{ .collection = .{ .length = 0 } },                    .{ .constant = 2 },                    .{ .scale = .{ .node = 1, .coefficient = .{ .size_of_concrete_type = 0 } } },                    .{ .scale = .{ .node = 0, .coefficient = .{ .size_of_concrete_type = 1 } } },                    .{ .add = .{ .left = 2, .right = 3 } },                },                .assertions = &.{.{                    .scope = .closure_total,                    .measure = .retained,                    .relation = .exact,                    .expression = 4,                }},            },            .overload = .{                .kind = .reject_before_seal,                .detail = "pattern-count, unique-root count, placement arithmetic, or OOM failure leaves the pattern set unsealed and retryable",            },            .risks = .{                .transitive = .{                    .status = .open,                    .detail = "benefit sorting and root-name hashing use standard-library helpers without a transitive allocation-closure certificate",                },                .foreign = .{                    .status = .excluded,                    .detail = "pattern indexing is process-local and invokes no callback or operating-system boundary",                },            },            .obligations = &.{                .{ .key = "pattern_index_capacity", .role = .capacity_model },                .{ .key = "pattern_index_sealed_reuse_overload", .role = .overload },                .{ .key = "pattern_index_sealed_reuse_transitive_risk", .role = .transitive_risk },                .{ .key = "pattern_index_sealed_reuse_foreign_risk", .role = .foreign_risk },                .{ .key = "pattern_index_oom_retry", .role = .overload },            },        },        .bindings = .{            .owner = @This(),            .seal = .{                .family = alloc_phase.capacity.selector(@This().activate),                .premise = .{                    .class = .checked_semantic_fact,                    .authority = .checker,                },            },            .teardown = .{                .family = alloc_phase.capacity.selector(@This().deinit),                .premise = .{                    .class = .checked_semantic_fact,                    .authority = .checker,                },            },        },    };    phase: alloc_phase.capacity.Phase,    capacity: PatternIndexCapacity,    source_patterns: ?[]const RewritePattern,    bytes: []align(pattern_index_alignment) u8,    slots: []PatternRootSlot,    grouped_patterns: []RewritePattern,    root_count: usize,    pub const Limits = PatternIndexLimits;    pub const Capacity = PatternIndexCapacity;    pub fn init(allocator: std.mem.Allocator, limits: PatternIndexLimits) !PatternIndex {        const capacity = try PatternIndexCapacity.derive(limits);        const bytes = try allocator.alignedAlloc(            u8,            .fromByteUnits(pattern_index_alignment),            capacity.working_bytes,        );        errdefer allocator.free(bytes);        const slots = patternIndexSlice(            PatternRootSlot,            bytes,            capacity.slots_offset,            capacity.slot_count,        );        @memset(slots, .{});        const grouped_patterns = patternIndexSlice(            RewritePattern,            bytes,            capacity.patterns_offset,            capacity.facts.pattern_count,        );        var root_count: usize = 0;        for (limits.patterns) |pattern| {            const insertion = getOrInsertPatternRoot(slots, pattern.spec.root_op_name);            root_count += @intFromBool(insertion.inserted);            slots[insertion.index].len = std.math.add(                PatternOrdinal,                slots[insertion.index].len,                1,            ) catch unreachable;        }        setPatternRootStarts(slots, grouped_patterns.len);        var source_index = limits.patterns.len;        while (source_index > 0) {            source_index -= 1;            const pattern = limits.patterns[source_index];            const slot_index = findPatternRootSlotIndex(                slots,                pattern.spec.root_op_name,            ).?;            std.debug.assert(slots[slot_index].len > 0);            slots[slot_index].len -= 1;            const grouped_index = @as(usize, slots[slot_index].start) +                @as(usize, slots[slot_index].len);            std.debug.assert(grouped_index < grouped_patterns.len);            grouped_patterns[grouped_index] = pattern;        }        restorePatternRootLengths(slots, grouped_patterns.len);        const index = PatternIndex{            .phase = .initialization,            .capacity = capacity,            .source_patterns = limits.patterns,            .bytes = bytes,            .slots = slots,            .grouped_patterns = grouped_patterns,            .root_count = root_count,        };        index.assertInvariant();        return index;    }    pub fn activate(self: *PatternIndex) error{ AlreadyActive, InputChanged }!void {        if (self.phase != .initialization) return error.AlreadyActive;        if (self.source_patterns == null) return error.InputChanged;        self.source_patterns = null;        self.phase = .steady;        self.assertInvariant();    }    pub fn deinit(self: *PatternIndex, allocator: std.mem.Allocator) void {        if (self.phase == .teardown) @panic("rewrite pattern index teardown is terminal");        self.assertInvariant();        self.phase = .teardown;        allocator.free(self.bytes);        self.source_patterns = undefined;        self.bytes = undefined;        self.slots = undefined;        self.grouped_patterns = undefined;        self.root_count = undefined;    }    pub fn matching(self: *const PatternIndex, root_name: []const u8) []const RewritePattern {        self.requireSteady();        std.debug.assert(self.grouped_patterns.len == self.capacity.facts.pattern_count);        std.debug.assert(self.slots.len == self.capacity.slot_count);        const range = self.findRoot(root_name) orelse return &.{};        const start: usize = @intCast(range.start);        const len: usize = @intCast(range.len);        std.debug.assert(start <= self.grouped_patterns.len);        std.debug.assert(len <= self.grouped_patterns.len - start);        return self.grouped_patterns[start..][0..len];    }    fn findRoot(self: *const PatternIndex, root_name: []const u8) ?PatternRootSlot {        const slot_index = findPatternRootSlotIndex(self.slots, root_name) orelse            return null;        return self.slots[slot_index];    }    fn requireSteady(self: *const PatternIndex) void {        if (self.phase != .steady) @panic("rewrite pattern index is not active");    }    fn assertInvariant(self: *const PatternIndex) void {        std.debug.assert(self.phase != .teardown);        std.debug.assert(self.bytes.len == self.capacity.working_bytes);        if (self.phase == .initialization) {            std.debug.assert(self.source_patterns != null);            std.debug.assert(self.source_patterns.?.len == self.capacity.facts.pattern_count);        } else {            std.debug.assert(self.source_patterns == null);        }        std.debug.assert(self.slots.len == self.capacity.slot_count);        std.debug.assert(self.grouped_patterns.len == self.capacity.facts.pattern_count);        var root_count: usize = 0;        var pattern_count: usize = 0;        for (self.slots) |slot| {            const name = slot.name orelse continue;            root_count += 1;            std.debug.assert(slot.len > 0);            const start: usize = @intCast(slot.start);            const len: usize = @intCast(slot.len);            std.debug.assert(start <= self.grouped_patterns.len);            std.debug.assert(len <= self.grouped_patterns.len - start);            pattern_count = std.math.add(usize, pattern_count, len) catch unreachable;            std.debug.assert(pattern_count <= self.grouped_patterns.len);            const found = self.findRoot(name).?;            std.debug.assert(found.start == slot.start);            std.debug.assert(found.len == slot.len);        }        std.debug.assert(root_count == self.root_count);        std.debug.assert(pattern_count == self.grouped_patterns.len);        for (self.grouped_patterns, 0..) |_, pattern_index| {            var containing_ranges: usize = 0;            for (self.slots) |slot| {                if (slot.name == null) continue;                const start: usize = @intCast(slot.start);                const len: usize = @intCast(slot.len);                if (pattern_index >= start and pattern_index - start < len) {                    containing_ranges += 1;                }            }            std.debug.assert(containing_ranges == 1);        }    }    fn matchesPatterns(self: *const PatternIndex) bool {        if (self.grouped_patterns.len != self.capacity.facts.pattern_count) return false;        for (self.slots) |slot| {            const root_name = slot.name orelse continue;            const start: usize = @intCast(slot.start);            const len: usize = @intCast(slot.len);            for (self.grouped_patterns[start..][0..len], 0..) |pattern, group_index| {                if (!std.mem.eql(                    u8,                    root_name,                    pattern.spec.root_op_name,                )) return false;                if (group_index > 0 and RewritePattern.lessThan(                    {},                    pattern,                    self.grouped_patterns[start + group_index - 1],                )) return false;            }        }        return true;    }};

Source: lib/choir/src/core/rewrite/pattern.zig:92

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

Source: lib/choir/src/core/rewrite/pattern.zig:26

zig
pub const RewritePattern = struct {    spec: RewritePatternSpec,    rewrite_fn: *const fn (        op: *ir.Operation,        rewriter: *PatternRewriter,    ) PatternResult,    match_fn: ?*const fn (op: *ir.Operation) bool,    order: usize,    pub fn init(        spec: RewritePatternSpec,        rewrite_fn: *const fn (*ir.Operation, *PatternRewriter) PatternResult,    ) RewritePattern {        return .{            .spec = spec,            .rewrite_fn = rewrite_fn,            .match_fn = null,            .order = 0,        };    }    pub fn initWithMatch(        spec: RewritePatternSpec,        match_fn: *const fn (*ir.Operation) bool,        rewrite_fn: *const fn (*ir.Operation, *PatternRewriter) PatternResult,    ) RewritePattern {        return .{            .spec = spec,            .rewrite_fn = rewrite_fn,            .match_fn = match_fn,            .order = 0,        };    }    pub fn matches(self: *const RewritePattern, op: *ir.Operation) bool {        if (!std.mem.eql(u8, op.name.name, self.spec.root_op_name)) {            return false;        }        return self.matchesAfterRoot(op);    }    pub fn matchesAfterRoot(self: *const RewritePattern, op: *ir.Operation) bool {        if (self.match_fn) |match| {            return match(op);        }        return true;    }    pub fn apply(self: *const RewritePattern, op: *ir.Operation, rewriter: *PatternRewriter) PatternResult {        return self.rewrite_fn(op, rewriter);    }    pub fn matchAndRewrite(self: *const RewritePattern, op: *ir.Operation, rewriter: *PatternRewriter) PatternResult {        if (!self.matches(op)) return .failure;        return self.apply(op, rewriter);    }    pub fn lessThan(_: void, a: RewritePattern, b: RewritePattern) bool {        if (a.spec.benefit != b.spec.benefit) return a.spec.benefit > b.spec.benefit;        return a.order < b.order;    }};

Source: lib/choir/src/core/rewrite/pattern.zig:7

zig
pub const RewritePatternKind = enum {    rewrite,    fold,};

Source: lib/choir/src/core/rewrite/pattern.zig:12

zig
pub const RewritePatternProducts = union(enum) {    unknown,    none,    operations: []const []const u8,};

Source: lib/choir/src/core/rewrite/pattern.zig:18

zig
pub const RewritePatternSpec = struct {    name: []const u8,    root_op_name: []const u8,    benefit: PatternBenefit = 1,    kind: RewritePatternKind = .rewrite,    products: RewritePatternProducts = .unknown,};

Source: lib/choir/src/core/rewrite/rewriter.zig:8

zig
pub const PatternRewriteAttempt = struct {    rewriter: *PatternRewriter,    created_before: usize,    guard: PatternRewriter.InsertionGuard,    pub inline fn init(op: *ir.Operation, rewriter: *PatternRewriter) PatternRewriteAttempt {        const attempt = PatternRewriteAttempt{            .rewriter = rewriter,            .created_before = rewriter.created_ops.items.len,            .guard = rewriter.insertionGuard(),        };        rewriter.setInsertionPointBefore(op);        return attempt;    }    pub inline fn finish(self: *PatternRewriteAttempt, result: PatternResult) bool {        if (result == .failure and self.rewriter.created_ops.items.len != self.created_before) {            self.rewriter.created_ops.items.len = self.created_before;        }        self.guard.deinit();        self.* = undefined;        return result == .success;    }};

Source: lib/choir/src/core/rewrite/rewriter.zig:52

zig
pub const PatternRewriter = struct {    pub const ReplacementMode = enum {        immediate,        deferred,    };    allocator: std.mem.Allocator,    ir_ctx: *ir.Context,    type_converter: ?*const TypeConverter,    replacement_mode: ReplacementMode,    created_ops: std.ArrayListUnmanaged(*ir.Operation),    ops_to_erase: std.ArrayListUnmanaged(*ir.Operation),    replacements: std.AutoHashMap(*ir.Value, *ir.Value),    builder: ir.OperationBuilder,    listener: ?Listener,    pub const InsertPoint: type = ir.OperationBuilder.InsertPoint;    pub const InsertionGuard: type = ir.OperationBuilder.InsertionGuard;    pub const OperationReplacement = struct {        op: *ir.Operation,        new_values: []const *ir.Value,    };    pub const DetachedOperation = struct {        op: *ir.Operation,        block: *ir.Block,        next: ?*ir.Operation,    };    pub const RewriteEvent = union(enum) {        modified: *ir.Operation,        replaced: OperationReplacement,        erased: *ir.Operation,    };    pub const Listener = struct {        context: ?*anyopaque = null,        notify_event: ?*const fn (?*anyopaque, RewriteEvent) void = null,        pub fn bind(target: anytype) Listener {            const TargetPtr = @TypeOf(target);            comptime {                const pointer_info = switch (@typeInfo(TargetPtr)) {                    .pointer => |info| info,                    else => @compileError("PatternRewriter.Listener.bind expects a mutable pointer"),                };                if (pointer_info.size != .one) {                    @compileError("PatternRewriter.Listener.bind expects a single-item pointer");                }                if (pointer_info.attrs.@"const") {                    @compileError("PatternRewriter.Listener.bind expects a mutable pointer");                }                if (!@hasDecl(pointer_info.child, "notifyRewriteEvent")) {                    @compileError("PatternRewriter listener target must define notifyRewriteEvent");                }            }            return .{                .context = target,                .notify_event = rewrite_listener_target(TargetPtr).notify_event,            };        }        pub fn notify(self: Listener, event: RewriteEvent) void {            if (self.notify_event) |notify_event| notify_event(self.context, event);        }    };    pub fn init(allocator: std.mem.Allocator, ir_ctx: *ir.Context) PatternRewriter {        return initWithMode(allocator, ir_ctx, .immediate);    }    pub fn initDeferred(allocator: std.mem.Allocator, ir_ctx: *ir.Context) PatternRewriter {        return initWithMode(allocator, ir_ctx, .deferred);    }    fn initWithMode(        allocator: std.mem.Allocator,        ir_ctx: *ir.Context,        replacement_mode: ReplacementMode,    ) PatternRewriter {        return .{            .allocator = allocator,            .ir_ctx = ir_ctx,            .type_converter = null,            .replacement_mode = replacement_mode,            .created_ops = .empty,            .ops_to_erase = .empty,            .replacements = std.AutoHashMap(*ir.Value, *ir.Value).init(allocator),            .builder = ir.OperationBuilder.init(ir_ctx),            .listener = null,        };    }    pub fn initWithTypeConverter(        allocator: std.mem.Allocator,        ir_ctx: *ir.Context,        type_converter: ?*const TypeConverter,    ) PatternRewriter {        var rewriter = PatternRewriter.init(allocator, ir_ctx);        rewriter.type_converter = type_converter;        return rewriter;    }    pub fn deinit(self: *PatternRewriter) void {        self.created_ops.deinit(self.allocator);        self.ops_to_erase.deinit(self.allocator);        self.replacements.deinit();    }    pub fn setTypeConverter(self: *PatternRewriter, type_converter: ?*const TypeConverter) void {        self.type_converter = type_converter;    }    pub fn getTypeConverter(self: *const PatternRewriter) ?*const TypeConverter {        return self.type_converter;    }    pub fn setListener(self: *PatternRewriter, listener: ?Listener) void {        self.listener = listener;    }    pub fn getListener(self: *const PatternRewriter) ?Listener {        return self.listener;    }    pub fn materializeConversion(self: *PatternRewriter, value: *ir.Value, target_type: ir.Type) ?*ir.Value {        const converter = self.type_converter orelse return null;        return converter.materialize(self, value, target_type);    }    pub fn clearInsertionPoint(self: *PatternRewriter) void {        self.builder.clearInsertionPoint();    }    pub fn hasInsertionPoint(self: *const PatternRewriter) bool {        return self.builder.hasInsertionPoint();    }    pub fn saveInsertionPoint(self: *const PatternRewriter) InsertPoint {        return self.builder.saveInsertionPoint();    }    pub fn restoreInsertionPoint(self: *PatternRewriter, insert_point: InsertPoint) void {        self.builder.restoreInsertionPoint(insert_point);    }    pub fn insertionGuard(self: *PatternRewriter) InsertionGuard {        return self.builder.insertionGuard();    }    pub fn setInsertionPoint(self: *PatternRewriter, block: *ir.Block) void {        self.builder.setInsertionPoint(block);    }    pub fn setInsertionPointBefore(self: *PatternRewriter, op: *ir.Operation) void {        self.builder.setInsertionPointBefore(op);    }    pub fn setInsertionPointAfter(self: *PatternRewriter, op: *ir.Operation) void {        self.builder.setInsertionPointAfter(op);    }    fn ensureBuilderListener(self: *PatternRewriter) void {        self.builder.setListener(.{            .context = self,            .notify_operation_inserted = recordInsertedOperation,        });    }    fn recordInsertedOperation(context: ?*anyopaque, op: *ir.Operation, previous: ir.OperationBuilder.InsertPoint) !void {        _ = previous;        const self: *PatternRewriter = @ptrCast(@alignCast(context.?));        try self.created_ops.append(self.allocator, op);    }    pub fn insert(self: *PatternRewriter, op: *ir.Operation) !*ir.Operation {        self.ensureBuilderListener();        return try self.builder.insert(op);    }    pub fn create(self: *PatternRewriter, state: ir.Operation.State) !*ir.Operation {        self.ensureBuilderListener();        return try self.builder.create(state);    }    fn notifyRewriteEvent(self: *const PatternRewriter, event: RewriteEvent) void {        if (self.listener) |listener| listener.notify(event);    }    fn replaceUsesImmediately(self: *PatternRewriter, old_value: *ir.Value, new_value: *ir.Value) void {        if (old_value == new_value) return;        var uses = old_value.useIterator();        while (uses.next()) |operand| {            operand.setValue(new_value);            const owner: *ir.Operation = @ptrCast(@alignCast(operand.owner));            self.notifyRewriteEvent(.{ .modified = owner });        }    }    fn ensureReplacementCapacity(self: *PatternRewriter, count: usize) !void {        if (self.replacement_mode == .deferred) {            try self.replacements.ensureUnusedCapacity(@intCast(count));        }    }    fn ensureEraseCapacity(self: *PatternRewriter) !void {        try self.ops_to_erase.ensureUnusedCapacity(self.allocator, 1);    }    pub fn setOperandValue(self: *PatternRewriter, op: *ir.Operation, index: usize, new_value: *ir.Value) void {        op.setOperandValue(index, new_value);        self.notifyRewriteEvent(.{ .modified = op });    }    pub fn setAttr(self: *PatternRewriter, op: *ir.Operation, attr_name: []const u8, value: ir.Attribute) !void {        try op.setAttr(attr_name, value);        self.notifyRewriteEvent(.{ .modified = op });    }    pub fn replaceAllUsesWith(self: *PatternRewriter, old_value: *ir.Value, new_value: *ir.Value) !void {        switch (self.replacement_mode) {            .immediate => self.replaceUsesImmediately(old_value, new_value),            .deferred => try self.replacements.put(old_value, new_value),        }    }    pub fn replaceAllOpUsesWith(self: *PatternRewriter, op: *ir.Operation, new_values: []const *ir.Value) !void {        if (new_values.len != op.getNumResults()) return error.ReplacementResultCountMismatch;        try self.ensureReplacementCapacity(new_values.len);        self.notifyRewriteEvent(.{ .replaced = .{ .op = op, .new_values = new_values } });        switch (self.replacement_mode) {            .immediate => for (op.results.items, new_values) |*result, new_value| {                self.replaceUsesImmediately(result, new_value);            },            .deferred => for (op.results.items, new_values) |*result, new_value| {                self.replacements.putAssumeCapacity(result, new_value);            },        }    }    pub fn replaceAllOpUsesWithOperation(self: *PatternRewriter, op: *ir.Operation, replacement: *ir.Operation) !void {        const result_count = op.getNumResults();        if (replacement.getNumResults() != result_count) return error.ReplacementResultCountMismatch;        if (result_count == 0) {            try self.replaceAllOpUsesWith(op, &.{});            return;        }        if (result_count == 1) {            const value = replacement.getResult(0) orelse return error.ReplacementResultCountMismatch;            try self.replaceAllOpUsesWith(op, &.{value});            return;        }        const values = try self.allocator.alloc(*ir.Value, result_count);        defer self.allocator.free(values);        for (values, 0..) |*value, index| {            value.* = replacement.getResult(index) orelse return error.ReplacementResultCountMismatch;        }        try self.replaceAllOpUsesWith(op, values);    }    pub fn replaceOp(self: *PatternRewriter, op: *ir.Operation, new_values: []const *ir.Value) !void {        if (new_values.len != op.getNumResults()) return error.ReplacementResultCountMismatch;        try self.ensureEraseCapacity();        try self.replaceAllOpUsesWith(op, new_values);        self.ops_to_erase.appendAssumeCapacity(op);    }    pub fn replaceOpWithOperation(self: *PatternRewriter, op: *ir.Operation, replacement: *ir.Operation) !void {        if (replacement.getNumResults() != op.getNumResults()) return error.ReplacementResultCountMismatch;        try self.ensureEraseCapacity();        try self.replaceAllOpUsesWithOperation(op, replacement);        self.ops_to_erase.appendAssumeCapacity(op);    }    pub fn replaceOpWithNewOp(self: *PatternRewriter, op: *ir.Operation, state: ir.Operation.State) !*ir.Operation {        const result_count = op.getNumResults();        if (state.result_types.len != result_count) return error.ReplacementResultCountMismatch;        try self.ensureEraseCapacity();        try self.ensureReplacementCapacity(result_count);        const new_op = try self.create(state);        try self.replaceOpWithOperation(op, new_op);        return new_op;    }    pub fn replaceOpWithValue(self: *PatternRewriter, op: *ir.Operation, new_value: *ir.Value) !void {        try self.replaceOp(op, &.{new_value});    }    pub fn eraseOp(self: *PatternRewriter, op: *ir.Operation) !void {        try self.ops_to_erase.append(self.allocator, op);    }    pub fn isScheduledForErase(self: *const PatternRewriter, op: *const ir.Operation) bool {        for (self.ops_to_erase.items) |erased_op| {            if (erased_op == op) return true;        }        return false;    }    pub fn getRemappedValue(self: *const PatternRewriter, value: *ir.Value) *ir.Value {        if (self.replacement_mode == .immediate) return value;        var current = value;        while (self.replacements.get(current)) |replacement| {            current = replacement;        }        return current;    }    pub fn finalize(self: *PatternRewriter, root_op: *ir.Operation) void {        self.applyPendingReplacements(root_op);        for (self.ops_to_erase.items) |op| {            self.notifyRewriteEvent(.{ .erased = op });            op.erase();        }    }    pub fn applyPendingReplacements(self: *PatternRewriter, root_op: *ir.Operation) void {        if (self.replacement_mode == .immediate) return;        if (self.replacements.count() != 0) self.applyReplacementsToOp(root_op);    }    pub fn detachScheduledOperations(        self: *PatternRewriter,        storage: []DetachedOperation,    ) []DetachedOperation {        std.debug.assert(storage.len >= self.ops_to_erase.items.len);        for (self.ops_to_erase.items, 0..) |op, index| {            const block = op.getBlock() orelse @panic("scheduled erased operation is detached");            storage[index] = .{                .op = op,                .block = block,                .next = op.next_op,            };            self.notifyRewriteEvent(.{ .erased = op });            block.detachOperation(op);        }        return storage[0..self.ops_to_erase.items.len];    }    pub fn restoreDetachedOperations(detached: []const DetachedOperation) void {        var index = detached.len;        while (index > 0) {            index -= 1;            const entry = detached[index];            if (entry.next) |next| {                entry.block.insertBefore(entry.op, next) catch unreachable;            } else {                entry.block.addOperation(entry.op) catch unreachable;            }        }    }    pub fn destroyDetachedOperations(detached: []const DetachedOperation) void {        for (detached) |entry| entry.op.dropAllReferences();        var index = detached.len;        while (index > 0) {            index -= 1;            detached[index].op.erase();        }    }    pub fn rollbackCreatedOperations(self: *PatternRewriter) void {        var index = self.created_ops.items.len;        while (index > 0) {            index -= 1;            self.created_ops.items[index].erase();        }        self.created_ops.clearRetainingCapacity();    }    fn applyReplacementsToOp(self: *PatternRewriter, op: *ir.Operation) void {        var context = ReplacementWalk{ .rewriter = self };        _ = op.walk(.{ .order = .pre_order }, &context, ReplacementWalk.visit) catch unreachable;    }};

Source: lib/choir/src/core/rewrite/set.zig:12

zig
pub const RewritePatternSet = struct {    allocator: std.mem.Allocator,    patterns: std.ArrayListUnmanaged(RewritePattern),    index: ?PatternIndex,    pub fn init(allocator: std.mem.Allocator) RewritePatternSet {        return .{            .allocator = allocator,            .patterns = .empty,            .index = null,        };    }    pub fn deinit(self: *RewritePatternSet) void {        if (self.index) |*index| index.deinit(self.allocator);        self.patterns.deinit(self.allocator);        self.* = undefined;    }    pub fn add(self: *RewritePatternSet, pattern: RewritePattern) !void {        if (self.index != null) return error.PatternSetSealed;        var ordered = pattern;        ordered.order = self.patterns.items.len;        try self.patterns.append(self.allocator, ordered);    }    pub fn ensureUnusedCapacity(self: *RewritePatternSet, additional_count: usize) !void {        if (self.index != null) return error.PatternSetSealed;        const required_count = std.math.add(            usize,            self.patterns.items.len,            additional_count,        ) catch return error.CapacityOverflow;        try self.patterns.ensureTotalCapacity(self.allocator, required_count);    }    pub fn addPattern(        self: *RewritePatternSet,        op_name: []const u8,        rewrite_fn: *const fn (*ir.Operation, *PatternRewriter) PatternResult,    ) !void {        try self.add(RewritePattern.init(.{            .name = op_name,            .root_op_name = op_name,        }, rewrite_fn));    }    pub fn count(self: *const RewritePatternSet) usize {        if (self.index) |index| return index.capacity.facts.pattern_count;        return self.patterns.items.len;    }    pub fn seal(self: *RewritePatternSet) !void {        if (self.index != null) return;        std.mem.sort(RewritePattern, self.patterns.items, {}, RewritePattern.lessThan);        const limits = try PatternIndex.Limits.inspect(self.patterns.items);        var index = try PatternIndex.init(self.allocator, limits);        errdefer index.deinit(self.allocator);        try index.activate();        self.patterns.deinit(self.allocator);        self.patterns = .empty;        self.index = index;    }    pub fn getMatchingPatterns(self: *const RewritePatternSet, op: *ir.Operation) []const RewritePattern {        if (self.index) |*index| {            return index.matching(op.name.name);        }        @panic("rewrite pattern set is not sealed");    }    pub fn applyFirstMatchingPattern(        self: *const RewritePatternSet,        op: *ir.Operation,        rewriter: *PatternRewriter,    ) bool {        for (self.getMatchingPatterns(op)) |*pattern| {            if (tryApplyRewritePattern(pattern, op, rewriter)) return true;        }        return false;    }};

Source: lib/choir/src/core/rewrite/type.zig:5

zig
pub const TypeConverter = struct {    allocator: std.mem.Allocator,    conversions: std.HashMap(TypeKey, TypeConversionResult, TypeKeyContext, std.hash_map.default_max_load_percentage),    materialize_fn: ?MaterializeFn,    const TypeKey = struct {        name: []const u8,        param_key: []const u8,    };    const TypeKeyContext = struct {        pub fn hash(_: TypeKeyContext, key: TypeKey) u64 {            var hasher = std.hash.Wyhash.init(0);            hasher.update(key.name);            hasher.update(&[_]u8{0});            hasher.update(key.param_key);            return hasher.final();        }        pub fn eql(_: TypeKeyContext, a: TypeKey, b: TypeKey) bool {            return std.mem.eql(u8, a.name, b.name) and std.mem.eql(u8, a.param_key, b.param_key);        }    };    pub const TypeConversionResult = struct {        types: []ir.Type,    };    pub const MaterializeFn = *const fn (        rewriter: *PatternRewriter,        value: *ir.Value,        target_type: ir.Type,    ) ?*ir.Value;    fn dupeTypes(allocator: std.mem.Allocator, target_types: []const ir.Type) ![]ir.Type {        if (target_types.len == 0) {            return try allocator.alloc(ir.Type, 0);        }        const duped = try allocator.alloc(ir.Type, target_types.len);        @memcpy(duped, target_types);        return duped;    }    pub fn init(allocator: std.mem.Allocator) TypeConverter {        return .{            .allocator = allocator,            .conversions = std.HashMap(TypeKey, TypeConversionResult, TypeKeyContext, std.hash_map.default_max_load_percentage).init(allocator),            .materialize_fn = null,        };    }    pub fn deinit(self: *TypeConverter) void {        var iter = self.conversions.iterator();        while (iter.next()) |entry| {            const key = entry.key_ptr.*;            self.allocator.free(key.name);            if (key.param_key.len > 0) {                self.allocator.free(key.param_key);            }            const types = entry.value_ptr.types;            self.allocator.free(types);        }        self.conversions.deinit();    }    pub fn addConversion(self: *TypeConverter, source_type: ir.Type, target_types: []const ir.Type) !void {        const storage = source_type.getDialectStorage() orelse return error.InvalidType;        const lookup_key = TypeKey{ .name = storage.name, .param_key = storage.param_key };        if (self.conversions.getPtr(lookup_key)) |result| {            const types_copy = try dupeTypes(self.allocator, target_types);            errdefer self.allocator.free(types_copy);            self.allocator.free(result.types);            result.types = types_copy;            return;        }        const name_copy = try self.allocator.dupe(u8, storage.name);        errdefer self.allocator.free(name_copy);        const key_copy = if (storage.param_key.len > 0)            try self.allocator.dupe(u8, storage.param_key)        else            "";        errdefer if (key_copy.len > 0) self.allocator.free(key_copy);        const types_copy = try dupeTypes(self.allocator, target_types);        errdefer self.allocator.free(types_copy);        try self.conversions.put(.{ .name = name_copy, .param_key = key_copy }, TypeConversionResult{ .types = types_copy });    }    pub fn setMaterialization(self: *TypeConverter, materialize_fn: MaterializeFn) void {        self.materialize_fn = materialize_fn;    }    pub fn materialize(self: *const TypeConverter, rewriter: *PatternRewriter, value: *ir.Value, target_type: ir.Type) ?*ir.Value {        const func = self.materialize_fn orelse return null;        return func(rewriter, value, target_type);    }    pub fn convertType(self: *const TypeConverter, source_type: ir.Type) ?[]const ir.Type {        if (source_type.getDialectStorage()) |storage| {            const key = TypeKey{ .name = storage.name, .param_key = storage.param_key };            if (self.conversions.get(key)) |result| {                return result.types;            }        }        return null;    }    pub fn convertTypesAlloc(self: *const TypeConverter, allocator: std.mem.Allocator, source_types: []const ir.Type) ![]ir.Type {        var out: std.ArrayListUnmanaged(ir.Type) = .empty;        errdefer out.deinit(allocator);        for (source_types) |source_type| {            if (self.convertType(source_type)) |converted| {                try out.appendSlice(allocator, converted);            } else {                try out.append(allocator, source_type);            }        }        return out.toOwnedSlice(allocator);    }    pub fn isTypeLegal(self: *const TypeConverter, t: ir.Type) bool {        return self.convertType(t) == null;    }};
Called byCallsir.rewrite.RewritePatternSetsealtest sourcelib.choir.src.core.rewritetest: rewrite pattern index derives e...private sourcelib.choir.src.core.rewrite.PatternIndexassertInvariantir.rewrite.PatternIndexactivate
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsir.rewrite.RewritePatternSetsealtest sourcelib.choir.src.core.rewritetest: rewrite pattern index derives e...private sourcelib.choir.src.core.rewrite.PatternIndexassertInvariantir.rewrite.PatternIndexdeinit
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsir.rewrite.RewritePatternSetsealtest sourcelib.choir.src.core.rewritetest: rewrite pattern index derives e...private sourcelib.choir.src.core.rewrite.PatternIndexCapacityderiveprivate sourcelib.choir.src.core.rewritefindPatternRootSlotIndexprivate sourcelib.choir.src.core.rewritegetOrInsertPatternRootprivate sourcelib.choir.src.core.rewritepatternIndexSliceprivate sourcelib.choir.src.core.rewriterestorePatternRootLengthsprivate sourcelib.choir.src.core.rewritesetPatternRootStartsir.rewrite.PatternIndexinit
Static calls · unresolved targets: 0 · external targets: 3.
Called byCallstest sourcelib.choir.src.core.rewritetest: rewrite pattern index derives e...private sourcelib.choir.src.core.rewrite.PatternIndexfindRootprivate sourcelib.choir.src.core.rewrite.PatternIndexrequireSteadyir.rewrite.PatternIndexmatching
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/choir/src/core/rewrite/canonicalization.zig:5

zig
pub const builtin_pattern_benefit: rewrite.PatternBenefit = 10;

Source: lib/choir/src/core/rewrite/canonicalization.zig:6

zig
pub const fold_pattern_benefit: rewrite.PatternBenefit = 100;

Source: lib/choir/src/core/rewrite/pattern.zig:5

zig
pub const PatternBenefit = u16;
Called byCallsNo direct callsir.rewrite.RewritePatternmatchAndRewriteir.rewrite.RewritePatternapply
Static calls · unresolved targets: 1 · external targets: 0.
Called byCallsNo direct callsprivate sourcelib.choir.src.backends.gpu.nvptx.conversionrunGpuToNvptxprivate sourcelib.choir.src.backends.gpu.spirv.conversionrunGpuToSpirvprivate sourcelib.choir.src.core.rewritecheckRewritePatternIndexInitFailurestest sourcelib.choir.src.core.rewrite.patterntest: RewritePattern stores inspectab...ir.rewrite.RewritePatternSetaddPattern+6 moreir.rewrite.RewritePatterninit
Static calls · unresolved targets: 1 · external targets: 0.
Called byCallsNo direct callsprivate sourcelib.choir.src.core.rewrite.PatternIndexmatchesPatternsir.rewrite.RewritePatternlessThan
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callersir.rewrite.RewritePatternapplyir.rewrite.RewritePatternmatchesir.rewrite.RewritePatternmatchAndRewrite
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsir.rewrite.RewritePatternmatchAndRewriteir.rewrite.RewritePatternmatchesAfterRootir.rewrite.RewritePatternmatches
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsir.rewrite.RewritePatternmatchesir.rewrite.RewritePatternmatchesAfterRoot
Static calls · unresolved targets: 1 · external targets: 0.
Called byCallsNo direct callsir.rewritetryApplyRewritePatternir.rewrite.PatternRewriteAttemptfinish
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsNo direct callsir.rewritetryApplyRewritePatternir.rewrite.PatternRewriteAttemptinit
Static calls · unresolved targets: 0 · external targets: 2.
Called byCallstest sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter listener binds ...test sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter listener record...private sourcelib.choir.src.core.rewrite.rewriterrewrite listener targetir.rewrite.PatternRewriter.Listenerbind
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsir.rewrite.PatternRewriterfinalizeprivate sourcelib.choir.src.core.rewrite.rewriter.PatternRe...applyReplacementsToOpir.rewrite.PatternRewriterapplyPendingReplacements
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsir.rewrite.PatternRewriterreplaceOpWithNewOptest sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter delegates inser...test sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter tracks inserted...private sourcelib.choir.src.core.rewrite.rewriter.PatternRe...ensureBuilderListenerir.rewrite.PatternRewritercreate
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsNo direct callstest sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter delegates inser...test sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter finalize remaps...test sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter immediate repla...test sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter listener binds ...test sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter listener record...+10 moreir.rewrite.PatternRewriterdeinit
Static calls · unresolved targets: 0 · external targets: 2.
Called byCallsNo direct callstest sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter detached erasur...ir.rewrite.PatternRewriterdestroyDetachedOperations
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsNo direct callersprivate sourcelib.choir.src.core.rewrite.rewriter.PatternRe...notifyRewriteEventir.rewrite.PatternRewriterdetachScheduledOperations
Static calls · unresolved targets: 0 · external targets: 2.
Called byCallstest sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter finalize remaps...test sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter immediate repla...test sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter listener record...test sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter replaceOpWithNe...test sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter replaceOpWithOp...+4 moreir.rewrite.PatternRewriterapplyPendingReplacementsprivate sourcelib.choir.src.core.rewrite.rewriter.PatternRe...notifyRewriteEventir.rewrite.PatternRewriterfinalize
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsNo direct callsprivate sourcelib.choir.src.core.rewrite.rewriter.Replaceme...visitir.rewrite.PatternRewritergetRemappedValue
Static calls · unresolved targets: 1 · external targets: 0.
Called byCallsir.rewrite.PatternRewriterinitWithTypeConvertertest sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter delegates inser...test sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter finalize remaps...test sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter immediate repla...test sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter listener binds ...+11 moreprivate sourcelib.choir.src.core.rewrite.rewriter.PatternRe...initWithModeir.rewrite.PatternRewriterinit
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallstest sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter detached erasur...private sourcelib.choir.src.core.rewrite.rewriter.PatternRe...initWithModeir.rewrite.PatternRewriterinitDeferred
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callersir.rewrite.PatternRewriterinitir.rewrite.PatternRewriterinitWithTypeConverter
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallstest sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter tracks inserted...private sourcelib.choir.src.core.rewrite.rewriter.PatternRe...ensureBuilderListenerir.rewrite.PatternRewriterinsert
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsNo direct callstest sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter delegates inser...ir.rewrite.PatternRewriterinsertionGuard
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsNo direct callstest sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter immediate repla...test sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter replaceOpWithNe...test sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter replaceOpWithNe...test sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter replaceOpWithOp...test sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter replaceOp rejec...ir.rewrite.PatternRewriterisScheduledForErase
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsir.rewrite.PatternRewriterreplaceAllOpUsesWithOperationir.rewrite.PatternRewriterreplaceOpprivate sourcelib.choir.src.core.rewrite.rewriter.PatternRe...ensureReplacementCapacityprivate sourcelib.choir.src.core.rewrite.rewriter.PatternRe...notifyRewriteEventprivate sourcelib.choir.src.core.rewrite.rewriter.PatternRe...replaceUsesImmediatelyir.rewrite.PatternRewriterreplaceAllOpUsesWith
Static calls · unresolved targets: 0 · external targets: 2.
Called byCallsir.rewrite.PatternRewriterreplaceOpWithOperationtest sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter immediate repla...ir.rewrite.PatternRewriterreplaceAllOpUsesWithir.rewrite.PatternRewriterreplaceAllOpUsesWithOperation
Static calls · unresolved targets: 0 · external targets: 5.
Called byCallstest sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter finalize remaps...private sourcelib.choir.src.core.rewrite.rewriter.PatternRe...replaceUsesImmediatelyir.rewrite.PatternRewriterreplaceAllUsesWith
Static calls · unresolved targets: 1 · external targets: 0.
Called byCallsir.rewrite.PatternRewriterreplaceOpWithValuetest sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter replaceOp rejec...private sourcelib.choir.src.core.rewrite.rewriter.PatternRe...ensureEraseCapacityir.rewrite.PatternRewriterreplaceAllOpUsesWithir.rewrite.PatternRewriterreplaceOp
Static calls · unresolved targets: 0 · external targets: 2.
Called byCallstest sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter replaceOpWithNe...test sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter replaceOpWithNe...ir.rewrite.PatternRewritercreateprivate sourcelib.choir.src.core.rewrite.rewriter.PatternRe...ensureEraseCapacityprivate sourcelib.choir.src.core.rewrite.rewriter.PatternRe...ensureReplacementCapacityir.rewrite.PatternRewriterreplaceOpWithOperationir.rewrite.PatternRewriterreplaceOpWithNewOp
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsir.rewrite.PatternRewriterreplaceOpWithNewOptest sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter listener record...test sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter replaceOpWithOp...private sourcelib.choir.src.core.rewrite.rewriter.PatternRe...ensureEraseCapacityir.rewrite.PatternRewriterreplaceAllOpUsesWithOperationir.rewrite.PatternRewriterreplaceOpWithOperation
Static calls · unresolved targets: 0 · external targets: 3.
Called byCallsNo direct callersir.rewrite.PatternRewriterreplaceOpir.rewrite.PatternRewriterreplaceOpWithValue
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callstest sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter detached erasur...ir.rewrite.PatternRewriterrestoreDetachedOperations
Static calls · unresolved targets: 0 · external targets: 2.
Called byCallstest sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter listener binds ...private sourcelib.choir.src.core.rewrite.rewriter.PatternRe...notifyRewriteEventir.rewrite.PatternRewritersetAttr
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsNo direct callstest sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter delegates inser...test sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter tracks inserted...ir.rewrite.PatternRewritersetInsertionPoint
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsNo direct callstest sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter delegates inser...test sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter replaceOpWithNe...test sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter replaceOpWithNe...ir.rewrite.PatternRewritersetInsertionPointBefore
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsNo direct callstest sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter listener binds ...test sourcelib.choir.src.core.rewrite.rewritertest: PatternRewriter listener record...ir.rewrite.PatternRewritersetListener
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsprivate sourcelib.choir.src.core.rewrite.rewriter.Replaceme...visitprivate sourcelib.choir.src.core.rewrite.rewriter.PatternRe...notifyRewriteEventir.rewrite.PatternRewritersetOperandValue
Static calls · unresolved targets: 0 · external targets: 1.

Source: lib/choir/src/core/rewrite/rewriter.zig:33

zig
pub inline fn tryApplyRewritePattern(    pattern: *const RewritePattern,    op: *ir.Operation,    rewriter: *PatternRewriter,) bool {    if (!pattern.matchesAfterRoot(op)) return false;    var attempt = PatternRewriteAttempt.init(op, rewriter);    return attempt.finish(pattern.apply(op, rewriter));}
Called byCallsir.rewrite.RewritePatternSetapplyFirstMatchingPatternir.rewrite.PatternRewriteAttemptfinishir.rewrite.PatternRewriteAttemptinitir.rewritetryApplyRewritePattern
Static calls · unresolved targets: 0 · external targets: 2.
Called byCallsNo direct callsprivate sourcelib.choir.src.backends.gpu.nvptx.conversionrunGpuToNvptxprivate sourcelib.choir.src.backends.gpu.spirv.conversionrunGpuToSpirvprivate sourcelib.choir.src.core.rewritecheckRewritePatternIndexInitFailuresir.rewrite.RewritePatternSetaddPatterntest sourcelib.choir.src.core.rewrite.settest: RewritePatternSet indexes match...+2 moreir.rewrite.RewritePatternSetadd
Static calls · unresolved targets: 1 · external targets: 0.
Called byCallsNo direct callersir.rewrite.RewritePatterninitir.rewrite.RewritePatternSetaddir.rewrite.RewritePatternSetaddPattern
Static calls · unresolved targets: 1 · external targets: 0.
Called byCallsNo direct callersir.rewritetryApplyRewritePatternir.rewrite.RewritePatternSetgetMatchingPatternsir.rewrite.RewritePatternSetapplyFirstMatchingPattern
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callstest sourcelib.choir.src.core.rewrite.settest: RewritePatternSet seal preserve...ir.rewrite.RewritePatternSetcount
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsprivate sourcelib.choir.src.backends.gpu.nvptx.conversionrunGpuToNvptxprivate sourcelib.choir.src.backends.gpu.spirv.conversionrunGpuToSpirvprivate sourcelib.choir.src.core.rewritecheckRewritePatternIndexInitFailurestest sourcelib.choir.src.core.rewrite.settest: RewritePatternSet indexes match...test sourcelib.choir.src.core.rewrite.settest: RewritePatternSet seal preserve...test sourcelib.choir.src.core.rewrite.settest: rewrite pattern setir.rewrite.RewritePatternSetdeinit
Static calls · unresolved targets: 0 · external targets: 2.
Called byCallsNo direct callsir.rewrite.RewritePatternSetapplyFirstMatchingPatterntest sourcelib.choir.src.core.rewrite.settest: RewritePatternSet indexes match...ir.rewrite.RewritePatternSetgetMatchingPatterns
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsNo direct callsprivate sourcelib.choir.src.backends.gpu.nvptx.conversionrunGpuToNvptxprivate sourcelib.choir.src.backends.gpu.spirv.conversionrunGpuToSpirvprivate sourcelib.choir.src.core.rewritecheckRewritePatternIndexInitFailurestest sourcelib.choir.src.core.rewrite.settest: RewritePatternSet indexes match...test sourcelib.choir.src.core.rewrite.settest: RewritePatternSet seal preserve...+3 moreir.rewrite.RewritePatternSetinit
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsprivate sourcelib.choir.src.core.rewritecheckRewritePatternIndexInitFailurestest sourcelib.choir.src.core.rewrite.settest: RewritePatternSet indexes match...test sourcelib.choir.src.core.rewrite.settest: RewritePatternSet seal preserve...test sourcelib.choir.src.core.rewrite.settest: rewrite pattern setir.rewrite.PatternIndexactivateir.rewrite.PatternIndexdeinitir.rewrite.PatternIndexinitir.rewrite.RewritePatternSetseal
Static calls · unresolved targets: 0 · external targets: 2.
Called byCallsNo direct callersprivate sourcelib.choir.src.core.rewrite.type.TypeConverterdupeTypesir.rewrite.TypeConverteraddConversion
Static calls · unresolved targets: 1 · external targets: 4.
Called byCallsNo direct callsir.rewrite.TypeConverterconvertTypesAllocir.rewrite.TypeConverterisTypeLegalir.rewrite.TypeConverterconvertType
Static calls · unresolved targets: 1 · external targets: 1.
Called byCallsNo direct callersir.rewrite.TypeConverterconvertTypeir.rewrite.TypeConverterconvertTypesAlloc
Static calls · unresolved targets: 1 · external targets: 3.
Called byCallsNo direct callersir.rewrite.TypeConverterconvertTypeir.rewrite.TypeConverterisTypeLegal
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/choir/src/core/rewrite/root.zig

zig
const pattern_mod = @import("pattern.zig");pub const PatternBenefit = pattern_mod.PatternBenefit;pub const RewritePatternKind = pattern_mod.RewritePatternKind;pub const RewritePatternProducts = pattern_mod.RewritePatternProducts;pub const RewritePatternSpec = pattern_mod.RewritePatternSpec;pub const RewritePattern = pattern_mod.RewritePattern;pub const PatternResult = pattern_mod.PatternResult;const rewriter_mod = @import("rewriter.zig");pub const PatternRewriter = rewriter_mod.PatternRewriter;pub const PatternRewriteAttempt = rewriter_mod.PatternRewriteAttempt;pub const tryApplyRewritePattern = rewriter_mod.tryApplyRewritePattern;const set_mod = @import("set.zig");pub const RewritePatternSet = set_mod.RewritePatternSet;const index_mod = @import("index.zig");pub const PatternIndex = index_mod.PatternIndex;const type_mod = @import("type.zig");pub const TypeConverter = type_mod.TypeConverter;const canonicalization_mod = @import("canonicalization.zig");pub const DialectCanonicalizationInterface = canonicalization_mod.DialectCanonicalizationInterface;pub const builtin_pattern_benefit = canonicalization_mod.builtin_pattern_benefit;pub const fold_pattern_benefit = canonicalization_mod.fold_pattern_benefit;

Source: lib/choir/src/core/root.zig:90

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

Also reachable as

backends.wasm.emission.module_encoding.common.ir.rewrite.

Complete caller list for ir.rewrite.RewritePattern.init

11 direct callers.

Complete caller list for ir.rewrite.PatternRewriter.deinit

15 direct callers.

Complete caller list for ir.rewrite.PatternRewriter.finalize

9 direct callers.

Complete caller list for ir.rewrite.PatternRewriter.init

16 direct callers.

Complete caller list for ir.rewrite.RewritePatternSet.add

7 direct callers.

Complete caller list for ir.rewrite.RewritePatternSet.init

8 direct callers.

Audit

Definitions96
Public names192
Members54
Version26.7.0
Revisiondaab053ee433