mirror of
https://github.com/ziglang/zig.git
synced 2026-01-14 11:25:14 +00:00
spirv: keep track of air & liveness so that it can be used in flush()
This commit is contained in:
parent
94dd763936
commit
462d8fd3ac
@ -190,12 +190,12 @@ pub const DeclGen = struct {
|
||||
/// The decl we are currently generating code for.
|
||||
decl: *Decl,
|
||||
|
||||
/// If `gen` returned `Error.AnalysisFail`, this contains an explanatory message.
|
||||
/// If `gen` returned `Error.CodegenFail`, this contains an explanatory message.
|
||||
/// Memory is owned by `module.gpa`.
|
||||
error_msg: ?*Module.ErrorMsg,
|
||||
|
||||
/// Possible errors the `gen` function may return.
|
||||
const Error = error{ AnalysisFail, OutOfMemory };
|
||||
const Error = error{ CodegenFail, OutOfMemory };
|
||||
|
||||
/// This structure is used to return information about a type typically used for
|
||||
/// arithmetic operations. These types may either be integers, floats, or a vector
|
||||
@ -276,8 +276,12 @@ pub const DeclGen = struct {
|
||||
self.decl = decl;
|
||||
self.error_msg = null;
|
||||
|
||||
try self.genDecl();
|
||||
return self.error_msg;
|
||||
self.genDecl() catch |err| switch (err) {
|
||||
error.CodegenFail => return self.error_msg,
|
||||
else => |others| return others,
|
||||
};
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Free resources owned by the DeclGen.
|
||||
@ -297,7 +301,7 @@ pub const DeclGen = struct {
|
||||
const src: LazySrcLoc = .{ .node_offset = 0 };
|
||||
const src_loc = src.toSrcLoc(self.decl);
|
||||
self.error_msg = try Module.ErrorMsg.create(self.spv.module.gpa, src_loc, format, args);
|
||||
return error.AnalysisFail;
|
||||
return error.CodegenFail;
|
||||
}
|
||||
|
||||
fn resolve(self: *DeclGen, inst: Air.Inst.Ref) !ResultId {
|
||||
|
||||
@ -24,6 +24,7 @@ const SpirV = @This();
|
||||
|
||||
const std = @import("std");
|
||||
const Allocator = std.mem.Allocator;
|
||||
const ArenaAllocator = std.heap.ArenaAllocator;
|
||||
const assert = std.debug.assert;
|
||||
const log = std.log.scoped(.link);
|
||||
|
||||
@ -38,6 +39,7 @@ const build_options = @import("build_options");
|
||||
const spec = @import("../codegen/spirv/spec.zig");
|
||||
const Air = @import("../Air.zig");
|
||||
const Liveness = @import("../Liveness.zig");
|
||||
const Value = @import("../value.zig").Value;
|
||||
|
||||
// TODO: Should this struct be used at all rather than just a hashmap of aux data for every decl?
|
||||
pub const FnData = struct {
|
||||
@ -55,7 +57,15 @@ decl_table: std.AutoArrayHashMapUnmanaged(*Module.Decl, DeclGenContext) = .{},
|
||||
|
||||
const DeclGenContext = struct {
|
||||
air: Air,
|
||||
air_value_arena: ArenaAllocator.State,
|
||||
liveness: Liveness,
|
||||
|
||||
fn deinit(self: *DeclGenContext, gpa: Allocator) void {
|
||||
self.air.deinit(gpa);
|
||||
self.liveness.deinit(gpa);
|
||||
self.air_value_arena.promote(gpa).deinit();
|
||||
self.* = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
pub fn createEmpty(gpa: Allocator, options: link.Options) !*SpirV {
|
||||
@ -113,12 +123,27 @@ pub fn updateFunc(self: *SpirV, module: *Module, func: *Module.Fn, air: Air, liv
|
||||
@panic("Attempted to compile for architecture that was disabled by build configuration");
|
||||
}
|
||||
_ = module;
|
||||
// Keep track of all decls so we can iterate over them on flush().
|
||||
_ = try self.decl_table.getOrPut(self.base.allocator, func.owner_decl);
|
||||
|
||||
_ = air;
|
||||
_ = liveness;
|
||||
@panic("TODO SPIR-V needs to keep track of Air and Liveness so it can use them later");
|
||||
// Keep track of all decls so we can iterate over them on flush().
|
||||
const result = try self.decl_table.getOrPut(self.base.allocator, func.owner_decl);
|
||||
if (result.found_existing) {
|
||||
result.value_ptr.deinit(self.base.allocator);
|
||||
}
|
||||
|
||||
var arena = ArenaAllocator.init(self.base.allocator);
|
||||
errdefer arena.deinit();
|
||||
|
||||
var new_air = try cloneAir(air, self.base.allocator, arena.allocator());
|
||||
errdefer new_air.deinit(self.base.allocator);
|
||||
|
||||
var new_liveness = try cloneLiveness(liveness, self.base.allocator);
|
||||
errdefer new_liveness.deinit(self.base.allocator);
|
||||
|
||||
result.value_ptr.* = .{
|
||||
.air = new_air,
|
||||
.air_value_arena = arena.state,
|
||||
.liveness = new_liveness,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn updateDecl(self: *SpirV, module: *Module, decl: *Module.Decl) !void {
|
||||
@ -143,7 +168,11 @@ pub fn updateDeclExports(
|
||||
}
|
||||
|
||||
pub fn freeDecl(self: *SpirV, decl: *Module.Decl) void {
|
||||
assert(self.decl_table.swapRemove(decl));
|
||||
const index = self.decl_table.getIndex(decl).?;
|
||||
if (decl.val.tag() == .function) {
|
||||
self.decl_table.values()[index].deinit(self.base.allocator);
|
||||
}
|
||||
self.decl_table.swapRemoveAt(index);
|
||||
}
|
||||
|
||||
pub fn flush(self: *SpirV, comp: *Compilation) !void {
|
||||
@ -273,3 +302,35 @@ fn writeMemoryModel(binary: *std.ArrayList(Word), target: std.Target) !void {
|
||||
@enumToInt(addressing_model), @enumToInt(memory_model),
|
||||
});
|
||||
}
|
||||
|
||||
fn cloneLiveness(l: Liveness, gpa: Allocator) !Liveness {
|
||||
const tomb_bits = try gpa.dupe(usize, l.tomb_bits);
|
||||
errdefer gpa.free(tomb_bits);
|
||||
|
||||
const extra = try gpa.dupe(u32, l.extra);
|
||||
errdefer gpa.free(extra);
|
||||
|
||||
return Liveness{
|
||||
.tomb_bits = tomb_bits,
|
||||
.extra = extra,
|
||||
.special = try l.special.clone(gpa),
|
||||
};
|
||||
}
|
||||
|
||||
fn cloneAir(air: Air, gpa: Allocator, value_arena: Allocator) !Air {
|
||||
const values = try gpa.alloc(Value, air.values.len);
|
||||
errdefer gpa.free(values);
|
||||
|
||||
for (values) |*value, i| {
|
||||
value.* = try air.values[i].copy(value_arena);
|
||||
}
|
||||
|
||||
var instructions = try air.instructions.toMultiArrayList().clone(gpa);
|
||||
errdefer instructions.deinit(gpa);
|
||||
|
||||
return Air{
|
||||
.instructions = instructions.slice(),
|
||||
.extra = try gpa.dupe(u32, air.extra),
|
||||
.values = values,
|
||||
};
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user