authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-09-29 00:13:21-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-09-29 00:13:21-07:00
log99961f22dca7e01b85b7819dcea814ad01b65af5
tree9c788bb803cf52cbb9928137b811b915097b46a7
parent33e77f127d8237088b561fae2ca0f4412bc1d6c9

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.

8 files changed, 99 insertions(+), 15 deletions(-)

src/AstGen.zig+5-1
...@@ -2567,7 +2567,11 @@ fn varDecl(...@@ -2567,7 +2567,11 @@ fn varDecl(
2567 for (init_scope.instructions.items) |src_inst| {2567 for (init_scope.instructions.items) |src_inst| {
2568 if (zir_tags[src_inst] == .store_to_block_ptr) {2568 if (zir_tags[src_inst] == .store_to_block_ptr) {
2569 if (zir_datas[src_inst].bin.lhs == init_scope.rl_ptr) {2569 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 }
2571 }2575 }
2572 }2576 }
2573 parent_zir.appendAssumeCapacity(src_inst);2577 parent_zir.appendAssumeCapacity(src_inst);
src/Compilation.zig+7-2
...@@ -1574,10 +1574,11 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {...@@ -1574,10 +1574,11 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
1574 // also test the use case of `build-obj -fcompiler-rt` with the self-hosted compiler1574 // also test the use case of `build-obj -fcompiler-rt` with the self-hosted compiler
1575 // and make sure the compiler-rt symbols are emitted. Currently this is hooked up for1575 // and make sure the compiler-rt symbols are emitted. Currently this is hooked up for
1576 // stage1 but not stage2.1576 // stage1 but not stage2.
1577 const capable_of_building_compiler_rt = comp.bin_file.options.use_stage1;1577 const capable_of_building_compiler_rt = comp.bin_file.options.use_stage1 or
1578 const capable_of_building_ssp = comp.bin_file.options.use_stage1;1578 comp.bin_file.options.use_llvm;
1579 const capable_of_building_zig_libc = comp.bin_file.options.use_stage1 or1579 const capable_of_building_zig_libc = comp.bin_file.options.use_stage1 or
1580 comp.bin_file.options.use_llvm;1580 comp.bin_file.options.use_llvm;
1581 const capable_of_building_ssp = comp.bin_file.options.use_stage1;
15811582
1582 if (comp.bin_file.options.include_compiler_rt and capable_of_building_compiler_rt) {1583 if (comp.bin_file.options.include_compiler_rt and capable_of_building_compiler_rt) {
1583 if (is_exe_or_dyn_lib) {1584 if (is_exe_or_dyn_lib) {
...@@ -1648,6 +1649,9 @@ pub fn destroy(self: *Compilation) void {...@@ -1648,6 +1649,9 @@ pub fn destroy(self: *Compilation) void {
1648 if (self.compiler_rt_static_lib) |*crt_file| {1649 if (self.compiler_rt_static_lib) |*crt_file| {
1649 crt_file.deinit(gpa);1650 crt_file.deinit(gpa);
1650 }1651 }
1652 if (self.compiler_rt_obj) |*crt_file| {
1653 crt_file.deinit(gpa);
1654 }
1651 if (self.libssp_static_lib) |*crt_file| {1655 if (self.libssp_static_lib) |*crt_file| {
1652 crt_file.deinit(gpa);1656 crt_file.deinit(gpa);
1653 }1657 }
...@@ -3977,6 +3981,7 @@ fn buildOutputFromZig(...@@ -3977,6 +3981,7 @@ fn buildOutputFromZig(
3977 },3981 },
3978 .root_src_path = src_basename,3982 .root_src_path = src_basename,
3979 };3983 };
3984 defer main_pkg.deinitTable(comp.gpa);
3980 const root_name = src_basename[0 .. src_basename.len - std.fs.path.extension(src_basename).len];3985 const root_name = src_basename[0 .. src_basename.len - std.fs.path.extension(src_basename).len];
3981 const target = comp.getTarget();3986 const target = comp.getTarget();
3982 const bin_basename = try std.zig.binNameAlloc(comp.gpa, .{3987 const bin_basename = try std.zig.binNameAlloc(comp.gpa, .{
src/Package.zig+9-6
...@@ -99,15 +99,18 @@ pub fn destroy(pkg: *Package, gpa: *Allocator) void {...@@ -99,15 +99,18 @@ pub fn destroy(pkg: *Package, gpa: *Allocator) void {
99 }99 }
100 }100 }
101101
102 {102 pkg.deinitTable(gpa);
103 var it = pkg.table.keyIterator();103 gpa.destroy(pkg);
104 while (it.next()) |key| {104}
105 gpa.free(key.*);105
106 }106/// Only frees memory associated with the table.
107pub fn deinitTable(pkg: *Package, gpa: *Allocator) void {
108 var it = pkg.table.keyIterator();
109 while (it.next()) |key| {
110 gpa.free(key.*);
107 }111 }
108112
109 pkg.table.deinit(gpa);113 pkg.table.deinit(gpa);
110 gpa.destroy(pkg);
111}114}
112115
113pub fn add(pkg: *Package, gpa: *Allocator, name: []const u8, package: *Package) !void {116pub fn add(pkg: *Package, gpa: *Allocator, name: []const u8, package: *Package) !void {
src/Sema.zig+43-4
...@@ -1587,7 +1587,42 @@ fn zirAllocExtended(...@@ -1587,7 +1587,42 @@ fn zirAllocExtended(
1587) CompileError!Air.Inst.Ref {1587) CompileError!Air.Inst.Ref {
1588 const extra = sema.code.extraData(Zir.Inst.AllocExtended, extended.operand);1588 const extra = sema.code.extraData(Zir.Inst.AllocExtended, extended.operand);
1589 const src: LazySrcLoc = .{ .node_offset = extra.data.src_node };1589 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);
1591}1626}
15921627
1593fn zirAllocComptime(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {1628fn 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...@@ -4620,7 +4655,8 @@ fn zirIntCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr
4620 return sema.mod.fail(&block.base, src, "unable to cast runtime value to 'comptime_int'", .{});4655 return sema.mod.fail(&block.base, src, "unable to cast runtime value to 'comptime_int'", .{});
4621 }4656 }
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);
4624}4660}
46254661
4626fn zirBitcast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {4662fn zirBitcast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -8257,8 +8293,11 @@ fn zirFrameAddress(...@@ -8257,8 +8293,11 @@ fn zirFrameAddress(
82578293
8258fn zirAlignOf(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {8294fn zirAlignOf(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
8259 const inst_data = sema.code.instructions.items(.data)[inst].un_node;8295 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
8260 const src = inst_data.src();8296 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
8261 return sema.mod.fail(&block.base, src, "TODO: Sema.zirAlignOf", .{});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);
8262}8301}
82638302
8264fn zirBoolToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {8303fn zirBoolToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
src/Zir.zig+8
...@@ -2878,6 +2878,14 @@ pub const Inst = struct {...@@ -2878,6 +2878,14 @@ pub const Inst = struct {
2878 /// 1. align_inst: Ref, // if small 0b00X0 is set2878 /// 1. align_inst: Ref, // if small 0b00X0 is set
2879 pub const AllocExtended = struct {2879 pub const AllocExtended = struct {
2880 src_node: i32,2880 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 };
2881 };2889 };
28822890
2883 pub const Export = struct {2891 pub const Export = struct {
src/link/Elf.zig+1-1
...@@ -1284,7 +1284,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {...@@ -1284,7 +1284,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
1284 const allow_shlib_undefined = self.base.options.allow_shlib_undefined orelse !self.base.options.is_native_os;1284 const allow_shlib_undefined = self.base.options.allow_shlib_undefined orelse !self.base.options.is_native_os;
1285 const compiler_rt_path: ?[]const u8 = if (self.base.options.include_compiler_rt) blk: {1285 const compiler_rt_path: ?[]const u8 = if (self.base.options.include_compiler_rt) blk: {
1286 // TODO: remove when stage2 can build compiler_rt.zig1286 // 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
1289 // In the case of build-obj we include the compiler-rt symbols directly alongside1289 // In the case of build-obj we include the compiler-rt symbols directly alongside
1290 // the symbols of the root source file, in the same compilation unit.1290 // the symbols of the root source file, in the same compilation unit.
src/print_zir.zig+25-1
...@@ -393,6 +393,7 @@ const Writer = struct {...@@ -393,6 +393,7 @@ const Writer = struct {
393 .@"asm" => try self.writeAsm(stream, extended),393 .@"asm" => try self.writeAsm(stream, extended),
394 .func => try self.writeFuncExtended(stream, extended),394 .func => try self.writeFuncExtended(stream, extended),
395 .variable => try self.writeVarExtended(stream, extended),395 .variable => try self.writeVarExtended(stream, extended),
396 .alloc => try self.writeAllocExtended(stream, extended),
396397
397 .compile_log,398 .compile_log,
398 .typeof_peer,399 .typeof_peer,
...@@ -423,7 +424,6 @@ const Writer = struct {...@@ -423,7 +424,6 @@ const Writer = struct {
423 try stream.writeByte(')');424 try stream.writeByte(')');
424 },425 },
425426
426 .alloc,
427 .builtin_extern,427 .builtin_extern,
428 .wasm_memory_size,428 .wasm_memory_size,
429 .wasm_memory_grow,429 .wasm_memory_grow,
...@@ -1767,6 +1767,30 @@ const Writer = struct {...@@ -1767,6 +1767,30 @@ const Writer = struct {
1767 try stream.writeAll("))");1767 try stream.writeAll("))");
1768 }1768 }
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
1770 fn writeBoolBr(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {1794 fn writeBoolBr(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {
1771 const inst_data = self.code.instructions.items(.data)[inst].bool_br;1795 const inst_data = self.code.instructions.items(.data)[inst].bool_br;
1772 const extra = self.code.extraData(Zir.Inst.Block, inst_data.payload_index);1796 const extra = self.code.extraData(Zir.Inst.Block, inst_data.payload_index);
src/type.zig+1
...@@ -3866,6 +3866,7 @@ pub const Type = extern union {...@@ -3866,6 +3866,7 @@ pub const Type = extern union {
3866 };3866 };
38673867
3868 pub const @"bool" = initTag(.bool);3868 pub const @"bool" = initTag(.bool);
3869 pub const @"comptime_int" = initTag(.comptime_int);
38693870
3870 pub fn ptr(arena: *Allocator, d: Payload.Pointer.Data) !Type {3871 pub fn ptr(arena: *Allocator, d: Payload.Pointer.Data) !Type {
3871 assert(d.host_size == 0 or d.bit_offset < d.host_size * 8);3872 assert(d.host_size == 0 or d.bit_offset < d.host_size * 8);