mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
CBE: add CType interning
This commit is contained in:
parent
dc1f50e505
commit
d8fada6b63
@ -569,6 +569,7 @@ set(ZIG_STAGE2_SOURCES
|
||||
"${CMAKE_SOURCE_DIR}/src/clang_options_data.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/codegen.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/codegen/c.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/codegen/c/type.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/codegen/llvm.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/codegen/llvm/bindings.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/glibc.zig"
|
||||
|
||||
@ -3266,8 +3266,8 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
|
||||
const decl_emit_h = emit_h.declPtr(decl_index);
|
||||
const fwd_decl = &decl_emit_h.fwd_decl;
|
||||
fwd_decl.shrinkRetainingCapacity(0);
|
||||
var typedefs_arena = std.heap.ArenaAllocator.init(gpa);
|
||||
defer typedefs_arena.deinit();
|
||||
var ctypes_arena = std.heap.ArenaAllocator.init(gpa);
|
||||
defer ctypes_arena.deinit();
|
||||
|
||||
var dg: c_codegen.DeclGen = .{
|
||||
.gpa = gpa,
|
||||
@ -3276,8 +3276,9 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
|
||||
.decl_index = decl_index,
|
||||
.decl = decl,
|
||||
.fwd_decl = fwd_decl.toManaged(gpa),
|
||||
.ctypes = .{},
|
||||
.typedefs = c_codegen.TypedefMap.initContext(gpa, .{ .mod = module }),
|
||||
.typedefs_arena = typedefs_arena.allocator(),
|
||||
.typedefs_arena = ctypes_arena.allocator(),
|
||||
};
|
||||
defer {
|
||||
for (dg.typedefs.values()) |typedef| {
|
||||
|
||||
@ -27,6 +27,8 @@ const Mutability = enum { Const, ConstArgument, Mut };
|
||||
const BigIntLimb = std.math.big.Limb;
|
||||
const BigInt = std.math.big.int;
|
||||
|
||||
pub const CType = @import("c/type.zig").CType;
|
||||
|
||||
pub const CValue = union(enum) {
|
||||
none: void,
|
||||
local: LocalIndex,
|
||||
@ -446,7 +448,8 @@ pub const Function = struct {
|
||||
return f.object.dg.fmtIntLiteral(ty, val);
|
||||
}
|
||||
|
||||
pub fn deinit(f: *Function, gpa: mem.Allocator) void {
|
||||
pub fn deinit(f: *Function) void {
|
||||
const gpa = f.object.dg.gpa;
|
||||
f.allocs.deinit(gpa);
|
||||
f.locals.deinit(gpa);
|
||||
for (f.free_locals_stack.items) |*free_locals| {
|
||||
@ -460,6 +463,7 @@ pub const Function = struct {
|
||||
gpa.free(typedef.rendered);
|
||||
}
|
||||
f.object.dg.typedefs.deinit();
|
||||
f.object.dg.ctypes.deinit(gpa);
|
||||
f.object.dg.fwd_decl.deinit();
|
||||
f.arena.deinit();
|
||||
}
|
||||
@ -487,6 +491,7 @@ pub const DeclGen = struct {
|
||||
decl_index: Decl.Index,
|
||||
fwd_decl: std.ArrayList(u8),
|
||||
error_msg: ?*Module.ErrorMsg,
|
||||
ctypes: CType.Store,
|
||||
/// The key of this map is Type which has references to typedefs_arena.
|
||||
typedefs: TypedefMap,
|
||||
typedefs_arena: std.mem.Allocator,
|
||||
@ -1949,6 +1954,10 @@ pub const DeclGen = struct {
|
||||
return name;
|
||||
}
|
||||
|
||||
fn typeToCType(dg: *DeclGen, ty: Type) !CType {
|
||||
return dg.ctypes.typeToCType(dg.gpa, ty, dg.module);
|
||||
}
|
||||
|
||||
/// Renders a type as a single identifier, generating intermediate typedefs
|
||||
/// if necessary.
|
||||
///
|
||||
@ -1967,6 +1976,8 @@ pub const DeclGen = struct {
|
||||
t: Type,
|
||||
kind: TypedefKind,
|
||||
) error{ OutOfMemory, AnalysisFail }!void {
|
||||
_ = try dg.typeToCType(t);
|
||||
|
||||
const target = dg.module.getTarget();
|
||||
|
||||
switch (t.zigTypeTag()) {
|
||||
|
||||
1457
src/codegen/c/type.zig
Normal file
1457
src/codegen/c/type.zig
Normal file
File diff suppressed because it is too large
Load Diff
@ -30,6 +30,7 @@ arena: std.heap.ArenaAllocator,
|
||||
const DeclBlock = struct {
|
||||
code: std.ArrayListUnmanaged(u8) = .{},
|
||||
fwd_decl: std.ArrayListUnmanaged(u8) = .{},
|
||||
ctypes: codegen.CType.Store = .{},
|
||||
/// Each Decl stores a mapping of Zig Types to corresponding C types, for every
|
||||
/// Zig Type used by the Decl. In flush(), we iterate over each Decl
|
||||
/// and emit the typedef code for all types, making sure to not emit the same thing twice.
|
||||
@ -37,12 +38,13 @@ const DeclBlock = struct {
|
||||
typedefs: codegen.TypedefMap.Unmanaged = .{},
|
||||
|
||||
fn deinit(db: *DeclBlock, gpa: Allocator) void {
|
||||
db.code.deinit(gpa);
|
||||
db.fwd_decl.deinit(gpa);
|
||||
for (db.typedefs.values()) |typedef| {
|
||||
gpa.free(typedef.rendered);
|
||||
}
|
||||
db.typedefs.deinit(gpa);
|
||||
db.ctypes.deinit(gpa);
|
||||
db.fwd_decl.deinit(gpa);
|
||||
db.code.deinit(gpa);
|
||||
db.* = undefined;
|
||||
}
|
||||
};
|
||||
@ -105,9 +107,11 @@ pub fn updateFunc(self: *C, module: *Module, func: *Module.Fn, air: Air, livenes
|
||||
gop.value_ptr.* = .{};
|
||||
}
|
||||
const fwd_decl = &gop.value_ptr.fwd_decl;
|
||||
const ctypes = &gop.value_ptr.ctypes;
|
||||
const typedefs = &gop.value_ptr.typedefs;
|
||||
const code = &gop.value_ptr.code;
|
||||
fwd_decl.shrinkRetainingCapacity(0);
|
||||
ctypes.clearRetainingCapacity(module.gpa);
|
||||
for (typedefs.values()) |typedef| {
|
||||
module.gpa.free(typedef.rendered);
|
||||
}
|
||||
@ -127,6 +131,7 @@ pub fn updateFunc(self: *C, module: *Module, func: *Module.Fn, air: Air, livenes
|
||||
.decl_index = decl_index,
|
||||
.decl = module.declPtr(decl_index),
|
||||
.fwd_decl = fwd_decl.toManaged(module.gpa),
|
||||
.ctypes = ctypes.*,
|
||||
.typedefs = typedefs.promoteContext(module.gpa, .{ .mod = module }),
|
||||
.typedefs_arena = self.arena.allocator(),
|
||||
},
|
||||
@ -137,7 +142,7 @@ pub fn updateFunc(self: *C, module: *Module, func: *Module.Fn, air: Air, livenes
|
||||
};
|
||||
|
||||
function.object.indent_writer = .{ .underlying_writer = function.object.code.writer() };
|
||||
defer function.deinit(module.gpa);
|
||||
defer function.deinit();
|
||||
|
||||
codegen.genFunc(&function) catch |err| switch (err) {
|
||||
error.AnalysisFail => {
|
||||
@ -148,6 +153,7 @@ pub fn updateFunc(self: *C, module: *Module, func: *Module.Fn, air: Air, livenes
|
||||
};
|
||||
|
||||
fwd_decl.* = function.object.dg.fwd_decl.moveToUnmanaged();
|
||||
ctypes.* = function.object.dg.ctypes.move();
|
||||
typedefs.* = function.object.dg.typedefs.unmanaged;
|
||||
function.object.dg.typedefs.unmanaged = .{};
|
||||
code.* = function.object.code.moveToUnmanaged();
|
||||
@ -155,6 +161,7 @@ pub fn updateFunc(self: *C, module: *Module, func: *Module.Fn, air: Air, livenes
|
||||
// Free excess allocated memory for this Decl.
|
||||
fwd_decl.shrinkAndFree(module.gpa, fwd_decl.items.len);
|
||||
code.shrinkAndFree(module.gpa, code.items.len);
|
||||
ctypes.shrinkAndFree(module.gpa);
|
||||
}
|
||||
|
||||
pub fn updateDecl(self: *C, module: *Module, decl_index: Module.Decl.Index) !void {
|
||||
@ -166,9 +173,11 @@ pub fn updateDecl(self: *C, module: *Module, decl_index: Module.Decl.Index) !voi
|
||||
gop.value_ptr.* = .{};
|
||||
}
|
||||
const fwd_decl = &gop.value_ptr.fwd_decl;
|
||||
const ctypes = &gop.value_ptr.ctypes;
|
||||
const typedefs = &gop.value_ptr.typedefs;
|
||||
const code = &gop.value_ptr.code;
|
||||
fwd_decl.shrinkRetainingCapacity(0);
|
||||
ctypes.clearRetainingCapacity(module.gpa);
|
||||
for (typedefs.values()) |value| {
|
||||
module.gpa.free(value.rendered);
|
||||
}
|
||||
@ -185,6 +194,7 @@ pub fn updateDecl(self: *C, module: *Module, decl_index: Module.Decl.Index) !voi
|
||||
.decl_index = decl_index,
|
||||
.decl = decl,
|
||||
.fwd_decl = fwd_decl.toManaged(module.gpa),
|
||||
.ctypes = ctypes.*,
|
||||
.typedefs = typedefs.promoteContext(module.gpa, .{ .mod = module }),
|
||||
.typedefs_arena = self.arena.allocator(),
|
||||
},
|
||||
@ -198,6 +208,7 @@ pub fn updateDecl(self: *C, module: *Module, decl_index: Module.Decl.Index) !voi
|
||||
module.gpa.free(typedef.rendered);
|
||||
}
|
||||
object.dg.typedefs.deinit();
|
||||
object.dg.ctypes.deinit(object.dg.gpa);
|
||||
object.dg.fwd_decl.deinit();
|
||||
}
|
||||
|
||||
@ -210,6 +221,8 @@ pub fn updateDecl(self: *C, module: *Module, decl_index: Module.Decl.Index) !voi
|
||||
};
|
||||
|
||||
fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged();
|
||||
ctypes.* = object.dg.ctypes;
|
||||
object.dg.ctypes = .{};
|
||||
typedefs.* = object.dg.typedefs.unmanaged;
|
||||
object.dg.typedefs.unmanaged = .{};
|
||||
code.* = object.code.moveToUnmanaged();
|
||||
@ -217,6 +230,7 @@ pub fn updateDecl(self: *C, module: *Module, decl_index: Module.Decl.Index) !voi
|
||||
// Free excess allocated memory for this Decl.
|
||||
fwd_decl.shrinkAndFree(module.gpa, fwd_decl.items.len);
|
||||
code.shrinkAndFree(module.gpa, code.items.len);
|
||||
ctypes.shrinkAndFree(module.gpa);
|
||||
}
|
||||
|
||||
pub fn updateDeclLineNumber(self: *C, module: *Module, decl_index: Module.Decl.Index) !void {
|
||||
@ -326,6 +340,8 @@ pub fn flushModule(self: *C, comp: *Compilation, prog_node: *std.Progress.Node)
|
||||
const Flush = struct {
|
||||
err_decls: DeclBlock = .{},
|
||||
remaining_decls: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, void) = .{},
|
||||
|
||||
ctypes: CTypes = .{},
|
||||
typedefs: Typedefs = .{},
|
||||
typedef_buf: std.ArrayListUnmanaged(u8) = .{},
|
||||
asm_buf: std.ArrayListUnmanaged(u8) = .{},
|
||||
@ -334,6 +350,13 @@ const Flush = struct {
|
||||
/// Keeps track of the total bytes of `all_buffers`.
|
||||
file_size: u64 = 0,
|
||||
|
||||
const CTypes = std.ArrayHashMapUnmanaged(
|
||||
codegen.CType,
|
||||
void,
|
||||
codegen.CType.HashContext32,
|
||||
true,
|
||||
);
|
||||
|
||||
const Typedefs = std.HashMapUnmanaged(
|
||||
Type,
|
||||
void,
|
||||
@ -351,6 +374,7 @@ const Flush = struct {
|
||||
f.all_buffers.deinit(gpa);
|
||||
f.typedef_buf.deinit(gpa);
|
||||
f.typedefs.deinit(gpa);
|
||||
f.ctypes.deinit(gpa);
|
||||
f.remaining_decls.deinit(gpa);
|
||||
f.err_decls.deinit(gpa);
|
||||
}
|
||||
@ -383,6 +407,7 @@ fn flushErrDecls(self: *C, f: *Flush) FlushDeclError!void {
|
||||
const module = self.base.options.module.?;
|
||||
|
||||
const fwd_decl = &f.err_decls.fwd_decl;
|
||||
const ctypes = &f.err_decls.ctypes;
|
||||
const typedefs = &f.err_decls.typedefs;
|
||||
const code = &f.err_decls.code;
|
||||
|
||||
@ -394,6 +419,7 @@ fn flushErrDecls(self: *C, f: *Flush) FlushDeclError!void {
|
||||
.decl_index = undefined,
|
||||
.decl = undefined,
|
||||
.fwd_decl = fwd_decl.toManaged(module.gpa),
|
||||
.ctypes = ctypes.*,
|
||||
.typedefs = typedefs.promoteContext(module.gpa, .{ .mod = module }),
|
||||
.typedefs_arena = self.arena.allocator(),
|
||||
},
|
||||
@ -403,6 +429,7 @@ fn flushErrDecls(self: *C, f: *Flush) FlushDeclError!void {
|
||||
object.indent_writer = .{ .underlying_writer = object.code.writer() };
|
||||
defer {
|
||||
object.code.deinit();
|
||||
object.dg.ctypes.deinit(module.gpa);
|
||||
for (object.dg.typedefs.values()) |typedef| {
|
||||
module.gpa.free(typedef.rendered);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user