tiny.choir.backends.regalloc.range
Defined in backends.regalloc.
API (6)
Actions
Public operations.
ValueLocationRangeappendValueLocationRangecandidateRangeConflictsWithFixedPositionscandidateRangeFixedConflictStart
Types and contracts
Public types and contracts.
Source
Source: lib/choir/src/backends/regalloc/range.zig
zig
const std = @import("std");const ir = @import("../../core/root.zig");const interval = @import("interval.zig");const position = @import("position.zig");pub const Entry = enum { resident, reload,};pub const Exit = enum { retain, spill,};pub fn ValueLocationRange(comptime Register: type) type { return struct { value: *ir.Value, start: u32, end: u32, reg: Register, entry: Entry = .resident, end_phase: position.Phase = .definition, exit: Exit = .retain, const Self = @This(); pub fn startPhase(self: Self) position.Phase { return switch (self.entry) { .reload => .source, .resident => position.valueStartPhase(self.value), }; } pub fn containsPoint(self: Self, point: position.Point) bool { if (point.position < self.start or point.position >= self.end) return false; if (point.position == self.start and @backingInt(point.phase) < @backingInt(self.startPhase())) return false; if (point.position == self.end - 1 and @backingInt(point.phase) > @backingInt(self.end_phase)) return false; return true; } pub fn startPoint(self: Self) position.Point { return .{ .position = self.start, .phase = self.startPhase() }; } pub fn endPoint(self: Self) position.Point { return .{ .position = self.end - 1, .phase = self.end_phase }; } pub fn overlaps(self: Self, other: Self) bool { if (self.start >= self.end or other.start >= other.end) return false; const start = @max(self.startPoint().rank(), other.startPoint().rank()); const end = @min(self.endPoint().rank(), other.endPoint().rank()); return start <= end; } pub fn coversValueAt(self: Self, value: *ir.Value, point: position.Point) bool { return self.value == value and self.containsPoint(point); } pub fn blocksRegisterAt(self: Self, reg: Register, point: position.Point) bool { return self.reg == reg and self.containsPoint(point); } };}pub fn appendValueLocationRange( comptime Register: type, ranges: *std.ArrayListUnmanaged(ValueLocationRange(Register)), allocator: std.mem.Allocator, value: *ir.Value, start: u32, end: u32, reg: Register, entry: Entry, end_phase: position.Phase, exit: Exit,) !void { if (start >= end) return; try ranges.append(allocator, .{ .value = value, .start = start, .end = end, .reg = reg, .entry = entry, .end_phase = end_phase, .exit = exit, });}pub fn candidateRangeFixedConflictStart( comptime Register: type, comptime Mask: type, candidate: interval.Candidate(Register, Mask), fixed_positions: interval.FixedPositionIndex(Register), proposed: ValueLocationRange(Register),) ?position.Point { for (fixed_positions.between(proposed.reg, proposed.startPoint(), proposed.endPoint())) |fixed| { if (fixed.kind == .source or fixed.kind == .use) continue; if (!candidate.ownsFixedPosition(fixed)) return fixed.point; } return null;}pub fn candidateRangeConflictsWithFixedPositions( comptime Register: type, comptime Mask: type, candidate: interval.Candidate(Register, Mask), fixed_positions: interval.FixedPositionIndex(Register), proposed: ValueLocationRange(Register),) bool { return candidateRangeFixedConflictStart(Register, Mask, candidate, fixed_positions, proposed) != null;}test "value location ranges compare phase-aware overlap" { var owner: u8 = 0; var first_value = ir.Value{ .kind = .{ .op_result = .{ .owner = &owner, .result_number = 0 } }, .type = undefined, .id = 0, }; var second_value = ir.Value{ .kind = .{ .op_result = .{ .owner = &owner, .result_number = 1 } }, .type = undefined, .id = 1, }; const Range = ValueLocationRange(u8); const resident = Range{ .value = &first_value, .start = 1, .end = 3, .reg = 1, .end_phase = .source, }; const reload = Range{ .value = &second_value, .start = 2, .end = 3, .reg = 1, .entry = .reload, .end_phase = .source, }; const late = Range{ .value = &second_value, .start = 2, .end = 3, .reg = 1, }; try std.testing.expect(resident.overlaps(reload)); try std.testing.expect(!resident.overlaps(late));}test "value location ranges cover values and block registers at points" { var owner: u8 = 0; var value = ir.Value{ .kind = .{ .op_result = .{ .owner = &owner, .result_number = 0 } }, .type = undefined, .id = 0, }; var other_value = ir.Value{ .kind = .{ .op_result = .{ .owner = &owner, .result_number = 1 } }, .type = undefined, .id = 1, }; const Range = ValueLocationRange(u8); const range = Range{ .value = &value, .start = 4, .end = 5, .reg = 2, }; const point = position.Point.definition(4); try std.testing.expect(range.coversValueAt(&value, point)); try std.testing.expect(!range.coversValueAt(&other_value, point)); try std.testing.expect(range.blocksRegisterAt(2, point)); try std.testing.expect(!range.blocksRegisterAt(3, point));}test "candidate range fixed-position conflict query uses proposed range" { var owner: u8 = 0; var value = ir.Value{ .kind = .{ .op_result = .{ .owner = &owner, .result_number = 0 } }, .type = undefined, .id = 0, }; const Candidate = interval.Candidate(u8, u8); const UsePosition = interval.UsePosition(u8, u8); const FixedPosition = interval.FixedPosition(u8); const Range = ValueLocationRange(u8); var uses: std.ArrayListUnmanaged(UsePosition) = .empty; defer uses.deinit(std.testing.allocator); try uses.append(std.testing.allocator, .{ .point = position.Point.source(4), .requirement = .{ .fixed = 2 }, .source_blockers = 0, }); const candidate = Candidate{ .value = &value, .range = .{ .start = 0, .end = 4, .end_phase = .source }, .use_positions = uses, .definition = .{ .point = position.Point.definition(0), .requirement = .{ .fixed = 1 }, .source = .any, }, .order = 0, .is_constant = false, }; var fixed_positions = [_]FixedPosition{ .{ .point = position.Point.definition(3), .reg = 1, .kind = .clobber }, .{ .point = position.Point.source(4), .reg = 2, .kind = .scratch_use }, .{ .point = position.Point.source(4), .reg = 1, .kind = .use }, }; var fixed_position_index_storage: interval.FixedPositionIndex(u8).Storage = undefined; const fixed_position_index = interval.FixedPositionIndex(u8).init(&fixed_positions, &fixed_position_index_storage); const crosses_clobber = Range{ .value = &value, .start = 2, .end = 5, .reg = 1, .end_phase = .source, }; const after_clobber = Range{ .value = &value, .start = 4, .end = 5, .reg = 1, .end_phase = .source, }; const owned_scratch = Range{ .value = &value, .start = 4, .end = 5, .reg = 2, .end_phase = .source, }; try std.testing.expect(candidateRangeConflictsWithFixedPositions(u8, u8, candidate, fixed_position_index, crosses_clobber)); try std.testing.expect(!candidateRangeConflictsWithFixedPositions(u8, u8, candidate, fixed_position_index, after_clobber)); try std.testing.expect(!candidateRangeConflictsWithFixedPositions(u8, u8, candidate, fixed_position_index, owned_scratch)); const conflict = candidateRangeFixedConflictStart(u8, u8, candidate, fixed_position_index, crosses_clobber) orelse return error.TestFailure; try std.testing.expectEqual(position.Point.definition(3), conflict); try std.testing.expectEqual(@as(?position.Point, null), candidateRangeFixedConflictStart(u8, u8, candidate, fixed_position_index, after_clobber));}test "value location range append skips empty ranges" { var owner: u8 = 0; var value = ir.Value{ .kind = .{ .op_result = .{ .owner = &owner, .result_number = 0 } }, .type = undefined, .id = 0, }; const Range = ValueLocationRange(u8); var ranges: std.ArrayListUnmanaged(Range) = .empty; defer ranges.deinit(std.testing.allocator); try appendValueLocationRange(u8, &ranges, std.testing.allocator, &value, 3, 3, 1, .resident, .source, .retain); try std.testing.expectEqual(@as(usize, 0), ranges.items.len); try appendValueLocationRange(u8, &ranges, std.testing.allocator, &value, 3, 4, 1, .resident, .definition, .retain); try std.testing.expectEqual(@as(usize, 1), ranges.items.len); try std.testing.expect(ranges.items[0].coversValueAt(&value, position.Point.definition(3)));}Source: lib/choir/src/backends/regalloc/root.zig:5
zig
pub const range = @import("range.zig");Complete caller list for backends.regalloc.range.ValueLocationRange
23 direct callers.
tiny.choir.backends.regalloc.locations.ValueLocationIndex[function] atlib/choir/src/backends/regalloc/locations.zig:6lib.choir.src.backends.regalloc.locations.test_value_location_index_preserves_phase_and_earliest_overlap_semantics[function] — test source atlib/choir/src/backends/regalloc/locations.zig:424in nearest public ownertiny.choir.backends.regalloc.locationslib.choir.src.backends.regalloc.locations.test_value_location_index_tracks_values_registers_and_events[function] — test source atlib/choir/src/backends/regalloc/locations.zig:356in nearest public ownertiny.choir.backends.regalloc.locationstiny.choir.backends.regalloc.range.appendValueLocationRange[function] atlib/choir/src/backends/regalloc/range.zig:67tiny.choir.backends.regalloc.range.candidateRangeConflictsWithFixedPositions[function] atlib/choir/src/backends/regalloc/range.zig:105tiny.choir.backends.regalloc.range.candidateRangeFixedConflictStart[function] atlib/choir/src/backends/regalloc/range.zig:91lib.choir.src.backends.regalloc.range.test_candidate_range_fixed-position_conflict_query_uses_proposed_range[function] — test source atlib/choir/src/backends/regalloc/range.zig:183in nearest public ownertiny.choir.backends.regalloc.rangelib.choir.src.backends.regalloc.range.test_value_location_range_append_skips_empty_ranges[function] — test source atlib/choir/src/backends/regalloc/range.zig:255in nearest public ownertiny.choir.backends.regalloc.rangelib.choir.src.backends.regalloc.range.test_value_location_ranges_compare_phase-aware_overlap[function] — test source atlib/choir/src/backends/regalloc/range.zig:115in nearest public ownertiny.choir.backends.regalloc.rangelib.choir.src.backends.regalloc.range.test_value_location_ranges_cover_values_and_block_registers_at_points[function] — test source atlib/choir/src/backends/regalloc/range.zig:155in nearest public ownertiny.choir.backends.regalloc.rangelib.choir.src.backends.regalloc.verify.VerificationCapacity[function] — private source atlib/choir/src/backends/regalloc/verify.zig:58in nearest public ownertiny.choir.backends.regalloc.verifylib.choir.src.backends.regalloc.verify.VerificationLimits[function] — private source atlib/choir/src/backends/regalloc/verify.zig:50in nearest public ownertiny.choir.backends.regalloc.verifylib.choir.src.backends.regalloc.verify.allocationVerifierType[function] — private source atlib/choir/src/backends/regalloc/verify.zig:264in nearest public ownertiny.choir.backends.regalloc.verifylib.choir.src.backends.regalloc.verify.initAllocationVerifier[function] — private source atlib/choir/src/backends/regalloc/verify.zig:123in nearest public ownertiny.choir.backends.regalloc.verifylib.choir.src.backends.regalloc.verify.test_allocation_verifier_accepts_owned_noninterfering_ranges[function] — test source atlib/choir/src/backends/regalloc/verify.zig:864in nearest public ownertiny.choir.backends.regalloc.verifylib.choir.src.backends.regalloc.verify.test_allocation_verifier_rejects_ranges_outside_candidate_intervals[function] — test source atlib/choir/src/backends/regalloc/verify.zig:825in nearest public ownertiny.choir.backends.regalloc.verifylib.choir.src.backends.regalloc.verify.test_allocation_verifier_rejects_ranges_without_candidate_ownership[function] — test source atlib/choir/src/backends/regalloc/verify.zig:803in nearest public ownertiny.choir.backends.regalloc.verifylib.choir.src.backends.regalloc.verify.test_interference_verifier_permits_overlapping_ranges_for_one_value[function] — test source atlib/choir/src/backends/regalloc/verify.zig:953in nearest public ownertiny.choir.backends.regalloc.verifylib.choir.src.backends.regalloc.verify.test_interference_verifier_retains_the_widest_same-value_range[function] — test source atlib/choir/src/backends/regalloc/verify.zig:927in nearest public ownertiny.choir.backends.regalloc.verifylib.choir.src.backends.regalloc.verify.valueLocationRangeOrder[function] — private source atlib/choir/src/backends/regalloc/verify.zig:31in nearest public ownertiny.choir.backends.regalloc.verifylib.choir.src.backends.regalloc.verify.verifyOrderedRangeInterference[function] — private source atlib/choir/src/backends/regalloc/verify.zig:101in nearest public ownertiny.choir.backends.regalloc.verifylib.choir.src.backends.regalloc.verify.verifyTestAllocation[function] — private source atlib/choir/src/backends/regalloc/verify.zig:482in nearest public ownertiny.choir.backends.regalloc.verifylib.choir.src.backends.regalloc.verify.verifyTestInterference[function] — private source atlib/choir/src/backends/regalloc/verify.zig:497in nearest public ownertiny.choir.backends.regalloc.verify
Audit
| Definitions | 7 |
|---|---|
| Public names | 13 |
| Members | 4 |
| Version | 26.7.0 |
| Revision | daab053ee433 |