Skip to content

Commit 99961f2

Browse files
committed
stage2: enable building compiler_rt when using LLVM backend
* AstGen: fix emitting `store_to_inferred_ptr` when it should be emitting `store` for a variable that has an explicit alignment. * Compilation: fix a couple memory leaks * Sema: implement support for locals that have specified alignment. * Sema: implement `@intCast` when it needs to emit an AIR instruction. * Sema: implement `@alignOf` * Implement debug printing for extended alloc ZIR instructions.
1 parent 33e77f1 commit 99961f2

File tree

8 files changed

+99
-15
lines changed

8 files changed

+99
-15
lines changed

src/AstGen.zig

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2567,7 +2567,11 @@ fn varDecl(
25672567
for (init_scope.instructions.items) |src_inst| {
25682568
if (zir_tags[src_inst] == .store_to_block_ptr) {
25692569
if (zir_datas[src_inst].bin.lhs == init_scope.rl_ptr) {
2570-
zir_tags[src_inst] = .store_to_inferred_ptr;
2570+
if (var_decl.ast.type_node != 0) {
2571+
zir_tags[src_inst] = .store;
2572+
} else {
2573+
zir_tags[src_inst] = .store_to_inferred_ptr;
2574+
}
25712575
}
25722576
}
25732577
parent_zir.appendAssumeCapacity(src_inst);

src/Compilation.zig

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1574,10 +1574,11 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
15741574
// also test the use case of `build-obj -fcompiler-rt` with the self-hosted compiler
15751575
// and make sure the compiler-rt symbols are emitted. Currently this is hooked up for
15761576
// stage1 but not stage2.
1577-
const capable_of_building_compiler_rt = comp.bin_file.options.use_stage1;
1578-
const capable_of_building_ssp = comp.bin_file.options.use_stage1;
1577+
const capable_of_building_compiler_rt = comp.bin_file.options.use_stage1 or
1578+
comp.bin_file.options.use_llvm;
15791579
const capable_of_building_zig_libc = comp.bin_file.options.use_stage1 or
15801580
comp.bin_file.options.use_llvm;
1581+
const capable_of_building_ssp = comp.bin_file.options.use_stage1;
15811582

15821583
if (comp.bin_file.options.include_compiler_rt and capable_of_building_compiler_rt) {
15831584
if (is_exe_or_dyn_lib) {
@@ -1648,6 +1649,9 @@ pub fn destroy(self: *Compilation) void {
16481649
if (self.compiler_rt_static_lib) |*crt_file| {
16491650
crt_file.deinit(gpa);
16501651
}
1652+
if (self.compiler_rt_obj) |*crt_file| {
1653+
crt_file.deinit(gpa);
1654+
}
16511655
if (self.libssp_static_lib) |*crt_file| {
16521656
crt_file.deinit(gpa);
16531657
}
@@ -3977,6 +3981,7 @@ fn buildOutputFromZig(
39773981
},
39783982
.root_src_path = src_basename,
39793983
};
3984+
defer main_pkg.deinitTable(comp.gpa);
39803985
const root_name = src_basename[0 .. src_basename.len - std.fs.path.extension(src_basename).len];
39813986
const target = comp.getTarget();
39823987
const bin_basename = try std.zig.binNameAlloc(comp.gpa, .{

src/Package.zig

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -99,15 +99,18 @@ pub fn destroy(pkg: *Package, gpa: *Allocator) void {
9999
}
100100
}
101101

102-
{
103-
var it = pkg.table.keyIterator();
104-
while (it.next()) |key| {
105-
gpa.free(key.*);
106-
}
102+
pkg.deinitTable(gpa);
103+
gpa.destroy(pkg);
104+
}
105+
106+
/// Only frees memory associated with the table.
107+
pub fn deinitTable(pkg: *Package, gpa: *Allocator) void {
108+
var it = pkg.table.keyIterator();
109+
while (it.next()) |key| {
110+
gpa.free(key.*);
107111
}
108112

109113
pkg.table.deinit(gpa);
110-
gpa.destroy(pkg);
111114
}
112115

113116
pub fn add(pkg: *Package, gpa: *Allocator, name: []const u8, package: *Package) !void {

src/Sema.zig

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1587,7 +1587,42 @@ fn zirAllocExtended(
15871587
) CompileError!Air.Inst.Ref {
15881588
const extra = sema.code.extraData(Zir.Inst.AllocExtended, extended.operand);
15891589
const src: LazySrcLoc = .{ .node_offset = extra.data.src_node };
1590-
return sema.mod.fail(&block.base, src, "TODO implement Sema.zirAllocExtended", .{});
1590+
const ty_src = src; // TODO better source location
1591+
const align_src = src; // TODO better source location
1592+
const small = @bitCast(Zir.Inst.AllocExtended.Small, extended.small);
1593+
1594+
var extra_index: usize = extra.end;
1595+
1596+
const var_ty: Type = if (small.has_type) blk: {
1597+
const type_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
1598+
extra_index += 1;
1599+
break :blk try sema.resolveType(block, ty_src, type_ref);
1600+
} else {
1601+
return sema.mod.fail(&block.base, src, "TODO implement Sema.zirAllocExtended inferred", .{});
1602+
};
1603+
1604+
const alignment: u16 = if (small.has_align) blk: {
1605+
const align_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
1606+
extra_index += 1;
1607+
const alignment = try sema.resolveAlign(block, align_src, align_ref);
1608+
break :blk alignment;
1609+
} else 0;
1610+
1611+
if (small.is_comptime) {
1612+
return sema.mod.fail(&block.base, src, "TODO implement Sema.zirAllocExtended comptime", .{});
1613+
}
1614+
1615+
if (!small.is_const) {
1616+
return sema.mod.fail(&block.base, src, "TODO implement Sema.zirAllocExtended var", .{});
1617+
}
1618+
1619+
const ptr_type = try Type.ptr(sema.arena, .{
1620+
.pointee_type = var_ty,
1621+
.@"align" = alignment,
1622+
.@"addrspace" = target_util.defaultAddressSpace(sema.mod.getTarget(), .local),
1623+
});
1624+
try sema.requireRuntimeBlock(block, src);
1625+
return block.addTy(.alloc, ptr_type);
15911626
}
15921627

15931628
fn zirAllocComptime(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
@@ -4620,7 +4655,8 @@ fn zirIntCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr
46204655
return sema.mod.fail(&block.base, src, "unable to cast runtime value to 'comptime_int'", .{});
46214656
}
46224657

4623-
return sema.mod.fail(&block.base, src, "TODO implement analyze widen or shorten int", .{});
4658+
try sema.requireRuntimeBlock(block, operand_src);
4659+
return block.addTyOp(.intcast, dest_type, operand);
46244660
}
46254661

46264662
fn zirBitcast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
@@ -8257,8 +8293,11 @@ fn zirFrameAddress(
82578293

82588294
fn zirAlignOf(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
82598295
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
8260-
const src = inst_data.src();
8261-
return sema.mod.fail(&block.base, src, "TODO: Sema.zirAlignOf", .{});
8296+
const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
8297+
const ty = try sema.resolveType(block, operand_src, inst_data.operand);
8298+
const target = sema.mod.getTarget();
8299+
const abi_align = ty.abiAlignment(target);
8300+
return sema.addIntUnsigned(Type.comptime_int, abi_align);
82628301
}
82638302

82648303
fn zirBoolToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {

src/Zir.zig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2878,6 +2878,14 @@ pub const Inst = struct {
28782878
/// 1. align_inst: Ref, // if small 0b00X0 is set
28792879
pub const AllocExtended = struct {
28802880
src_node: i32,
2881+
2882+
pub const Small = packed struct {
2883+
has_type: bool,
2884+
has_align: bool,
2885+
is_const: bool,
2886+
is_comptime: bool,
2887+
_: u12 = undefined,
2888+
};
28812889
};
28822890

28832891
pub const Export = struct {

src/link/Elf.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1284,7 +1284,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
12841284
const allow_shlib_undefined = self.base.options.allow_shlib_undefined orelse !self.base.options.is_native_os;
12851285
const compiler_rt_path: ?[]const u8 = if (self.base.options.include_compiler_rt) blk: {
12861286
// TODO: remove when stage2 can build compiler_rt.zig
1287-
if (!build_options.is_stage1 or !self.base.options.use_stage1) break :blk null;
1287+
if (!self.base.options.use_llvm) break :blk null;
12881288

12891289
// In the case of build-obj we include the compiler-rt symbols directly alongside
12901290
// the symbols of the root source file, in the same compilation unit.

src/print_zir.zig

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,7 @@ const Writer = struct {
393393
.@"asm" => try self.writeAsm(stream, extended),
394394
.func => try self.writeFuncExtended(stream, extended),
395395
.variable => try self.writeVarExtended(stream, extended),
396+
.alloc => try self.writeAllocExtended(stream, extended),
396397

397398
.compile_log,
398399
.typeof_peer,
@@ -423,7 +424,6 @@ const Writer = struct {
423424
try stream.writeByte(')');
424425
},
425426

426-
.alloc,
427427
.builtin_extern,
428428
.wasm_memory_size,
429429
.wasm_memory_grow,
@@ -1767,6 +1767,30 @@ const Writer = struct {
17671767
try stream.writeAll("))");
17681768
}
17691769

1770+
fn writeAllocExtended(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {
1771+
const extra = self.code.extraData(Zir.Inst.AllocExtended, extended.operand);
1772+
const small = @bitCast(Zir.Inst.AllocExtended.Small, extended.small);
1773+
const src: LazySrcLoc = .{ .node_offset = extra.data.src_node };
1774+
1775+
var extra_index: usize = extra.end;
1776+
const type_inst: Zir.Inst.Ref = if (!small.has_type) .none else blk: {
1777+
const type_inst = @intToEnum(Zir.Inst.Ref, self.code.extra[extra_index]);
1778+
extra_index += 1;
1779+
break :blk type_inst;
1780+
};
1781+
const align_inst: Zir.Inst.Ref = if (!small.has_align) .none else blk: {
1782+
const align_inst = @intToEnum(Zir.Inst.Ref, self.code.extra[extra_index]);
1783+
extra_index += 1;
1784+
break :blk align_inst;
1785+
};
1786+
try self.writeFlag(stream, ",is_const", small.is_const);
1787+
try self.writeFlag(stream, ",is_comptime", small.is_comptime);
1788+
try self.writeOptionalInstRef(stream, ",ty=", type_inst);
1789+
try self.writeOptionalInstRef(stream, ",align=", align_inst);
1790+
try stream.writeAll(")) ");
1791+
try self.writeSrc(stream, src);
1792+
}
1793+
17701794
fn writeBoolBr(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {
17711795
const inst_data = self.code.instructions.items(.data)[inst].bool_br;
17721796
const extra = self.code.extraData(Zir.Inst.Block, inst_data.payload_index);

src/type.zig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3866,6 +3866,7 @@ pub const Type = extern union {
38663866
};
38673867

38683868
pub const @"bool" = initTag(.bool);
3869+
pub const @"comptime_int" = initTag(.comptime_int);
38693870

38703871
pub fn ptr(arena: *Allocator, d: Payload.Pointer.Data) !Type {
38713872
assert(d.host_size == 0 or d.bit_offset < d.host_size * 8);

0 commit comments

Comments
 (0)