authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-07-13 05:02:27-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-07-19 23:38:40-04:00
log3f46e747a8adc61d0274c1cafa8abe8d02e6b10b
treedb4642853517d69e23ae755597cf3791087fc667
parent8fde3a8f04e393b05879aff7afb9b09aadb4f2e1

llvm: convert basic block creation


3 files changed, 516 insertions(+), 309 deletions(-)

src/codegen/llvm.zig+221-228
...@@ -602,6 +602,7 @@ pub const Object = struct {...@@ -602,6 +602,7 @@ pub const Object = struct {
602 var builder = try Builder.init(.{602 var builder = try Builder.init(.{
603 .allocator = gpa,603 .allocator = gpa,
604 .use_lib_llvm = options.use_lib_llvm,604 .use_lib_llvm = options.use_lib_llvm,
605 .strip = options.strip,
605 .name = options.root_name,606 .name = options.root_name,
606 .target = options.target,607 .target = options.target,
607 .triple = llvm_target_triple,608 .triple = llvm_target_triple,
...@@ -682,7 +683,7 @@ pub const Object = struct {...@@ -682,7 +683,7 @@ pub const Object = struct {
682683
683 target_machine = llvm.TargetMachine.create(684 target_machine = llvm.TargetMachine.create(
684 builder.llvm.target.?,685 builder.llvm.target.?,
685 builder.target_triple.toSlice(&builder).?.ptr,686 builder.target_triple.toSlice(&builder).?,
686 if (options.target.cpu.model.llvm_name) |s| s.ptr else null,687 if (options.target.cpu.model.llvm_name) |s| s.ptr else null,
687 options.llvm_cpu_features,688 options.llvm_cpu_features,
688 opt_level,689 opt_level,
...@@ -749,7 +750,6 @@ pub const Object = struct {...@@ -749,7 +750,6 @@ pub const Object = struct {
749 self.named_enum_map.deinit(gpa);750 self.named_enum_map.deinit(gpa);
750 self.type_map.deinit(gpa);751 self.type_map.deinit(gpa);
751 self.extern_collisions.deinit(gpa);752 self.extern_collisions.deinit(gpa);
752 self.builder.deinit();
753 self.* = undefined;753 self.* = undefined;
754 }754 }
755755
...@@ -850,22 +850,19 @@ pub const Object = struct {...@@ -850,22 +850,19 @@ pub const Object = struct {
850 error_name_table_ptr_global.toLlvm(&o.builder).setInitializer(error_name_table_ptr);850 error_name_table_ptr_global.toLlvm(&o.builder).setInitializer(error_name_table_ptr);
851 }851 }
852852
853 fn genCmpLtErrorsLenFunction(object: *Object) !void {853 fn genCmpLtErrorsLenFunction(o: *Object) !void {
854 // If there is no such function in the module, it means the source code does not need it.854 // If there is no such function in the module, it means the source code does not need it.
855 const llvm_fn = object.llvm_module.getNamedFunction(lt_errors_fn_name) orelse return;855 const name = o.builder.stringIfExists(lt_errors_fn_name) orelse return;
856 const mod = object.module;856 const llvm_fn = o.builder.getGlobal(name) orelse return;
857 const mod = o.module;
857 const errors_len = mod.global_error_set.count();858 const errors_len = mod.global_error_set.count();
858859
859 // Delete previous implementation. We replace it with every flush() because the860 var wip = Builder.WipFunction.init(&o.builder, llvm_fn.ptrConst(&o.builder).kind.function);
860 // total number of errors may have changed.861 defer wip.deinit();
861 while (llvm_fn.getFirstBasicBlock()) |bb| {
862 bb.deleteBasicBlock();
863 }
864862
865 const builder = object.context.createBuilder();863 const builder = wip.llvm.builder;
866864 const entry_block = try wip.block("Entry");
867 const entry_block = object.context.appendBasicBlock(llvm_fn, "Entry");865 builder.positionBuilderAtEnd(entry_block.toLlvm(&wip));
868 builder.positionBuilderAtEnd(entry_block);
869 builder.clearCurrentDebugLocation();866 builder.clearCurrentDebugLocation();
870867
871 // Example source of the following LLVM IR:868 // Example source of the following LLVM IR:
...@@ -873,10 +870,12 @@ pub const Object = struct {...@@ -873,10 +870,12 @@ pub const Object = struct {
873 // return index < total_errors_len;870 // return index < total_errors_len;
874 // }871 // }
875872
876 const lhs = llvm_fn.getParam(0);873 const lhs = llvm_fn.toLlvm(&o.builder).getParam(0);
877 const rhs = try object.builder.intConst(Builder.Type.err_int, errors_len);874 const rhs = try o.builder.intConst(Builder.Type.err_int, errors_len);
878 const is_lt = builder.buildICmp(.ULT, lhs, rhs.toLlvm(&object.builder), "");875 const is_lt = builder.buildICmp(.ULT, lhs, rhs.toLlvm(&o.builder), "");
879 _ = builder.buildRet(is_lt);876 _ = builder.buildRet(is_lt);
877
878 try wip.finish();
880 }879 }
881880
882 fn genModuleLevelAssembly(object: *Object) !void {881 fn genModuleLevelAssembly(object: *Object) !void {
...@@ -1158,11 +1157,14 @@ pub const Object = struct {...@@ -1158,11 +1157,14 @@ pub const Object = struct {
1158 bb.deleteBasicBlock();1157 bb.deleteBasicBlock();
1159 }1158 }
11601159
1161 const builder = o.context.createBuilder();1160 var deinit_wip = true;
1161 var wip = Builder.WipFunction.init(&o.builder, function);
1162 defer if (deinit_wip) wip.deinit();
11621163
1163 function.ptr(&o.builder).body = {};1164 const builder = wip.llvm.builder;
1164 const entry_block = o.context.appendBasicBlock(llvm_func, "Entry");1165 const entry_block = try wip.block("Entry");
1165 builder.positionBuilderAtEnd(entry_block);1166 wip.cursor = .{ .block = entry_block };
1167 builder.positionBuilderAtEnd(entry_block.toLlvm(&wip));
11661168
1167 // This gets the LLVM values from the function and stores them in `dg.args`.1169 // This gets the LLVM values from the function and stores them in `dg.args`.
1168 const fn_info = mod.typeToFunc(decl.ty).?;1170 const fn_info = mod.typeToFunc(decl.ty).?;
...@@ -1260,8 +1262,7 @@ pub const Object = struct {...@@ -1260,8 +1262,7 @@ pub const Object = struct {
1260 llvm_arg_i += 1;1262 llvm_arg_i += 1;
12611263
1262 const param_llvm_ty = (try o.lowerType(param_ty)).toLlvm(&o.builder);1264 const param_llvm_ty = (try o.lowerType(param_ty)).toLlvm(&o.builder);
1263 const abi_size = @as(c_uint, @intCast(param_ty.abiSize(mod)));1265 const int_llvm_ty = (try o.builder.intType(@intCast(param_ty.abiSize(mod) * 8))).toLlvm(&o.builder);
1264 const int_llvm_ty = (try o.builder.intType(@intCast(abi_size * 8))).toLlvm(&o.builder);
1265 const alignment = @max(1266 const alignment = @max(
1266 param_ty.abiAlignment(mod),1267 param_ty.abiAlignment(mod),
1267 o.target_data.abiAlignmentOfType(int_llvm_ty),1268 o.target_data.abiAlignmentOfType(int_llvm_ty),
...@@ -1317,11 +1318,10 @@ pub const Object = struct {...@@ -1317,11 +1318,10 @@ pub const Object = struct {
1317 const param_alignment = param_ty.abiAlignment(mod);1318 const param_alignment = param_ty.abiAlignment(mod);
1318 const arg_ptr = try o.buildAllocaInner(builder, llvm_func, false, param_llvm_ty, param_alignment, target);1319 const arg_ptr = try o.buildAllocaInner(builder, llvm_func, false, param_llvm_ty, param_alignment, target);
1319 const llvm_ty = (try o.builder.structType(.normal, field_types)).toLlvm(&o.builder);1320 const llvm_ty = (try o.builder.structType(.normal, field_types)).toLlvm(&o.builder);
1320 for (0..field_types.len) |field_i_usize| {1321 for (0..field_types.len) |field_i| {
1321 const field_i = @as(c_uint, @intCast(field_i_usize));
1322 const param = llvm_func.getParam(llvm_arg_i);1322 const param = llvm_func.getParam(llvm_arg_i);
1323 llvm_arg_i += 1;1323 llvm_arg_i += 1;
1324 const field_ptr = builder.buildStructGEP(llvm_ty, arg_ptr, field_i, "");1324 const field_ptr = builder.buildStructGEP(llvm_ty, arg_ptr, @intCast(field_i), "");
1325 const store_inst = builder.buildStore(param, field_ptr);1325 const store_inst = builder.buildStore(param, field_ptr);
1326 store_inst.setAlignment(target.ptrBitWidth() / 8);1326 store_inst.setAlignment(target.ptrBitWidth() / 8);
1327 }1327 }
...@@ -1422,6 +1422,7 @@ pub const Object = struct {...@@ -1422,6 +1422,7 @@ pub const Object = struct {
1422 .liveness = liveness,1422 .liveness = liveness,
1423 .context = o.context,1423 .context = o.context,
1424 .dg = &dg,1424 .dg = &dg,
1425 .wip = wip,
1425 .builder = builder,1426 .builder = builder,
1426 .ret_ptr = ret_ptr,1427 .ret_ptr = ret_ptr,
1427 .args = args.items,1428 .args = args.items,
...@@ -1438,6 +1439,7 @@ pub const Object = struct {...@@ -1438,6 +1439,7 @@ pub const Object = struct {
1438 .err_ret_trace = err_ret_trace,1439 .err_ret_trace = err_ret_trace,
1439 };1440 };
1440 defer fg.deinit();1441 defer fg.deinit();
1442 deinit_wip = false;
14411443
1442 fg.genBody(air.getMainBody()) catch |err| switch (err) {1444 fg.genBody(air.getMainBody()) catch |err| switch (err) {
1443 error.CodegenFail => {1445 error.CodegenFail => {
...@@ -1449,6 +1451,8 @@ pub const Object = struct {...@@ -1449,6 +1451,8 @@ pub const Object = struct {
1449 else => |e| return e,1451 else => |e| return e,
1450 };1452 };
14511453
1454 try fg.wip.finish();
1455
1452 try o.updateDeclExports(mod, decl_index, mod.getDeclExports(decl_index));1456 try o.updateDeclExports(mod, decl_index, mod.getDeclExports(decl_index));
1453 }1457 }
14541458
...@@ -1517,11 +1521,11 @@ pub const Object = struct {...@@ -1517,11 +1521,11 @@ pub const Object = struct {
1517 if (self.di_map.get(decl)) |di_node| {1521 if (self.di_map.get(decl)) |di_node| {
1518 const decl_name_slice = decl_name.toSlice(&self.builder).?;1522 const decl_name_slice = decl_name.toSlice(&self.builder).?;
1519 if (try decl.isFunction(mod)) {1523 if (try decl.isFunction(mod)) {
1520 const di_func = @as(*llvm.DISubprogram, @ptrCast(di_node));1524 const di_func: *llvm.DISubprogram = @ptrCast(di_node);
1521 const linkage_name = llvm.MDString.get(self.context, decl_name_slice.ptr, decl_name_slice.len);1525 const linkage_name = llvm.MDString.get(self.context, decl_name_slice.ptr, decl_name_slice.len);
1522 di_func.replaceLinkageName(linkage_name);1526 di_func.replaceLinkageName(linkage_name);
1523 } else {1527 } else {
1524 const di_global = @as(*llvm.DIGlobalVariable, @ptrCast(di_node));1528 const di_global: *llvm.DIGlobalVariable = @ptrCast(di_node);
1525 const linkage_name = llvm.MDString.get(self.context, decl_name_slice.ptr, decl_name_slice.len);1529 const linkage_name = llvm.MDString.get(self.context, decl_name_slice.ptr, decl_name_slice.len);
1526 di_global.replaceLinkageName(linkage_name);1530 di_global.replaceLinkageName(linkage_name);
1527 }1531 }
...@@ -1554,11 +1558,11 @@ pub const Object = struct {...@@ -1554,11 +1558,11 @@ pub const Object = struct {
1554 if (self.di_map.get(decl)) |di_node| {1558 if (self.di_map.get(decl)) |di_node| {
1555 const exp_name_slice = exp_name.toSlice(&self.builder).?;1559 const exp_name_slice = exp_name.toSlice(&self.builder).?;
1556 if (try decl.isFunction(mod)) {1560 if (try decl.isFunction(mod)) {
1557 const di_func = @as(*llvm.DISubprogram, @ptrCast(di_node));1561 const di_func: *llvm.DISubprogram = @ptrCast(di_node);
1558 const linkage_name = llvm.MDString.get(self.context, exp_name_slice.ptr, exp_name_slice.len);1562 const linkage_name = llvm.MDString.get(self.context, exp_name_slice.ptr, exp_name_slice.len);
1559 di_func.replaceLinkageName(linkage_name);1563 di_func.replaceLinkageName(linkage_name);
1560 } else {1564 } else {
1561 const di_global = @as(*llvm.DIGlobalVariable, @ptrCast(di_node));1565 const di_global: *llvm.DIGlobalVariable = @ptrCast(di_node);
1562 const linkage_name = llvm.MDString.get(self.context, exp_name_slice.ptr, exp_name_slice.len);1566 const linkage_name = llvm.MDString.get(self.context, exp_name_slice.ptr, exp_name_slice.len);
1563 di_global.replaceLinkageName(linkage_name);1567 di_global.replaceLinkageName(linkage_name);
1564 }1568 }
...@@ -1661,7 +1665,7 @@ pub const Object = struct {...@@ -1661,7 +1665,7 @@ pub const Object = struct {
1661 const gop = try o.di_map.getOrPut(gpa, file);1665 const gop = try o.di_map.getOrPut(gpa, file);
1662 errdefer assert(o.di_map.remove(file));1666 errdefer assert(o.di_map.remove(file));
1663 if (gop.found_existing) {1667 if (gop.found_existing) {
1664 return @as(*llvm.DIFile, @ptrCast(gop.value_ptr.*));1668 return @ptrCast(gop.value_ptr.*);
1665 }1669 }
1666 const dir_path_z = d: {1670 const dir_path_z = d: {
1667 var buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;1671 var buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;
...@@ -1809,7 +1813,7 @@ pub const Object = struct {...@@ -1809,7 +1813,7 @@ pub const Object = struct {
1809 ty.abiSize(mod) * 8,1813 ty.abiSize(mod) * 8,
1810 ty.abiAlignment(mod) * 8,1814 ty.abiAlignment(mod) * 8,
1811 enumerators.ptr,1815 enumerators.ptr,
1812 @as(c_int, @intCast(enumerators.len)),1816 @intCast(enumerators.len),
1813 try o.lowerDebugType(int_ty, .full),1817 try o.lowerDebugType(int_ty, .full),
1814 "",1818 "",
1815 );1819 );
...@@ -1984,7 +1988,7 @@ pub const Object = struct {...@@ -1984,7 +1988,7 @@ pub const Object = struct {
1984 ty.abiSize(mod) * 8,1988 ty.abiSize(mod) * 8,
1985 ty.abiAlignment(mod) * 8,1989 ty.abiAlignment(mod) * 8,
1986 try o.lowerDebugType(ty.childType(mod), .full),1990 try o.lowerDebugType(ty.childType(mod), .full),
1987 @as(i64, @intCast(ty.arrayLen(mod))),1991 @intCast(ty.arrayLen(mod)),
1988 );1992 );
1989 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1993 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1990 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(array_di_ty));1994 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(array_di_ty));
...@@ -2289,7 +2293,7 @@ pub const Object = struct {...@@ -2289,7 +2293,7 @@ pub const Object = struct {
2289 0, // flags2293 0, // flags
2290 null, // derived from2294 null, // derived from
2291 di_fields.items.ptr,2295 di_fields.items.ptr,
2292 @as(c_int, @intCast(di_fields.items.len)),2296 @intCast(di_fields.items.len),
2293 0, // run time lang2297 0, // run time lang
2294 null, // vtable holder2298 null, // vtable holder
2295 "", // unique id2299 "", // unique id
...@@ -2376,7 +2380,7 @@ pub const Object = struct {...@@ -2376,7 +2380,7 @@ pub const Object = struct {
2376 0, // flags2380 0, // flags
2377 null, // derived from2381 null, // derived from
2378 di_fields.items.ptr,2382 di_fields.items.ptr,
2379 @as(c_int, @intCast(di_fields.items.len)),2383 @intCast(di_fields.items.len),
2380 0, // run time lang2384 0, // run time lang
2381 null, // vtable holder2385 null, // vtable holder
2382 "", // unique id2386 "", // unique id
...@@ -2488,7 +2492,7 @@ pub const Object = struct {...@@ -2488,7 +2492,7 @@ pub const Object = struct {
2488 ty.abiAlignment(mod) * 8, // align in bits2492 ty.abiAlignment(mod) * 8, // align in bits
2489 0, // flags2493 0, // flags
2490 di_fields.items.ptr,2494 di_fields.items.ptr,
2491 @as(c_int, @intCast(di_fields.items.len)),2495 @intCast(di_fields.items.len),
2492 0, // run time lang2496 0, // run time lang
2493 "", // unique id2497 "", // unique id
2494 );2498 );
...@@ -2601,7 +2605,7 @@ pub const Object = struct {...@@ -2601,7 +2605,7 @@ pub const Object = struct {
26012605
2602 const fn_di_ty = dib.createSubroutineType(2606 const fn_di_ty = dib.createSubroutineType(
2603 param_di_types.items.ptr,2607 param_di_types.items.ptr,
2604 @as(c_int, @intCast(param_di_types.items.len)),2608 @intCast(param_di_types.items.len),
2605 0,2609 0,
2606 );2610 );
2607 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.2611 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
...@@ -4248,9 +4252,9 @@ pub const Object = struct {...@@ -4248,9 +4252,9 @@ pub const Object = struct {
4248 ) void {4252 ) void {
4249 const llvm_attr = o.context.createStringAttribute(4253 const llvm_attr = o.context.createStringAttribute(
4250 name.ptr,4254 name.ptr,
4251 @as(c_uint, @intCast(name.len)),4255 @intCast(name.len),
4252 value.ptr,4256 value.ptr,
4253 @as(c_uint, @intCast(value.len)),4257 @intCast(value.len),
4254 );4258 );
4255 val.addAttributeAtIndex(index, llvm_attr);4259 val.addAttributeAtIndex(index, llvm_attr);
4256 }4260 }
...@@ -4364,11 +4368,7 @@ pub const Object = struct {...@@ -4364,11 +4368,7 @@ pub const Object = struct {
4364 }4368 }
43654369
4366 const entry_block = llvm_func.getFirstBasicBlock().?;4370 const entry_block = llvm_func.getFirstBasicBlock().?;
4367 if (entry_block.getFirstInstruction()) |first_inst| {4371 builder.positionBuilder(entry_block, entry_block.getFirstInstruction());
4368 builder.positionBuilder(entry_block, first_inst);
4369 } else {
4370 builder.positionBuilderAtEnd(entry_block);
4371 }
4372 builder.clearCurrentDebugLocation();4372 builder.clearCurrentDebugLocation();
43734373
4374 break :blk builder.buildAllocaInAddressSpace(llvm_ty, @intFromEnum(address_space), "");4374 break :blk builder.buildAllocaInAddressSpace(llvm_ty, @intFromEnum(address_space), "");
...@@ -4502,6 +4502,7 @@ pub const FuncGen = struct {...@@ -4502,6 +4502,7 @@ pub const FuncGen = struct {
4502 dg: *DeclGen,4502 dg: *DeclGen,
4503 air: Air,4503 air: Air,
4504 liveness: Liveness,4504 liveness: Liveness,
4505 wip: Builder.WipFunction,
4505 context: *llvm.Context,4506 context: *llvm.Context,
4506 builder: *llvm.Builder,4507 builder: *llvm.Builder,
4507 di_scope: ?*llvm.DIScope,4508 di_scope: ?*llvm.DIScope,
...@@ -4542,7 +4543,7 @@ pub const FuncGen = struct {...@@ -4542,7 +4543,7 @@ pub const FuncGen = struct {
45424543
4543 /// This data structure is used to implement breaking to blocks.4544 /// This data structure is used to implement breaking to blocks.
4544 blocks: std.AutoHashMapUnmanaged(Air.Inst.Index, struct {4545 blocks: std.AutoHashMapUnmanaged(Air.Inst.Index, struct {
4545 parent_bb: *llvm.BasicBlock,4546 parent_bb: Builder.Function.Block.Index,
4546 breaks: *BreakList,4547 breaks: *BreakList,
4547 }),4548 }),
45484549
...@@ -4555,7 +4556,7 @@ pub const FuncGen = struct {...@@ -4555,7 +4556,7 @@ pub const FuncGen = struct {
4555 });4556 });
45564557
4557 fn deinit(self: *FuncGen) void {4558 fn deinit(self: *FuncGen) void {
4558 self.builder.dispose();4559 self.wip.deinit();
4559 self.dbg_inlined.deinit(self.gpa);4560 self.dbg_inlined.deinit(self.gpa);
4560 self.dbg_block_stack.deinit(self.gpa);4561 self.dbg_block_stack.deinit(self.gpa);
4561 self.func_inst_table.deinit(self.gpa);4562 self.func_inst_table.deinit(self.gpa);
...@@ -4898,7 +4899,7 @@ pub const FuncGen = struct {...@@ -4898,7 +4899,7 @@ pub const FuncGen = struct {
4898 fn airCall(self: *FuncGen, inst: Air.Inst.Index, attr: llvm.CallAttr) !?*llvm.Value {4899 fn airCall(self: *FuncGen, inst: Air.Inst.Index, attr: llvm.CallAttr) !?*llvm.Value {
4899 const pl_op = self.air.instructions.items(.data)[inst].pl_op;4900 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
4900 const extra = self.air.extraData(Air.Call, pl_op.payload);4901 const extra = self.air.extraData(Air.Call, pl_op.payload);
4901 const args = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len]));4902 const args: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len]);
4902 const o = self.dg.object;4903 const o = self.dg.object;
4903 const mod = o.module;4904 const mod = o.module;
4904 const ip = &mod.intern_pool;4905 const ip = &mod.intern_pool;
...@@ -4987,8 +4988,7 @@ pub const FuncGen = struct {...@@ -4987,8 +4988,7 @@ pub const FuncGen = struct {
4987 const arg = args[it.zig_index - 1];4988 const arg = args[it.zig_index - 1];
4988 const param_ty = self.typeOf(arg);4989 const param_ty = self.typeOf(arg);
4989 const llvm_arg = try self.resolveInst(arg);4990 const llvm_arg = try self.resolveInst(arg);
4990 const abi_size = @as(c_uint, @intCast(param_ty.abiSize(mod)));4991 const int_llvm_ty = (try o.builder.intType(@intCast(param_ty.abiSize(mod) * 8))).toLlvm(&o.builder);
4991 const int_llvm_ty = (try o.builder.intType(@intCast(abi_size * 8))).toLlvm(&o.builder);
49924992
4993 if (isByRef(param_ty, mod)) {4993 if (isByRef(param_ty, mod)) {
4994 const alignment = param_ty.abiAlignment(mod);4994 const alignment = param_ty.abiAlignment(mod);
...@@ -5034,9 +5034,8 @@ pub const FuncGen = struct {...@@ -5034,9 +5034,8 @@ pub const FuncGen = struct {
50345034
5035 const llvm_ty = (try o.builder.structType(.normal, llvm_types)).toLlvm(&o.builder);5035 const llvm_ty = (try o.builder.structType(.normal, llvm_types)).toLlvm(&o.builder);
5036 try llvm_args.ensureUnusedCapacity(it.types_len);5036 try llvm_args.ensureUnusedCapacity(it.types_len);
5037 for (llvm_types, 0..) |field_ty, i_usize| {5037 for (llvm_types, 0..) |field_ty, i| {
5038 const i = @as(c_uint, @intCast(i_usize));5038 const field_ptr = self.builder.buildStructGEP(llvm_ty, arg_ptr, @intCast(i), "");
5039 const field_ptr = self.builder.buildStructGEP(llvm_ty, arg_ptr, i, "");
5040 const load_inst = self.builder.buildLoad(field_ty.toLlvm(&o.builder), field_ptr, "");5039 const load_inst = self.builder.buildLoad(field_ty.toLlvm(&o.builder), field_ptr, "");
5041 load_inst.setAlignment(target.ptrBitWidth() / 8);5040 load_inst.setAlignment(target.ptrBitWidth() / 8);
5042 llvm_args.appendAssumeCapacity(load_inst);5041 llvm_args.appendAssumeCapacity(load_inst);
...@@ -5091,7 +5090,7 @@ pub const FuncGen = struct {...@@ -5091,7 +5090,7 @@ pub const FuncGen = struct {
5091 (try o.lowerType(zig_fn_ty)).toLlvm(&o.builder),5090 (try o.lowerType(zig_fn_ty)).toLlvm(&o.builder),
5092 llvm_fn,5091 llvm_fn,
5093 llvm_args.items.ptr,5092 llvm_args.items.ptr,
5094 @as(c_uint, @intCast(llvm_args.items.len)),5093 @intCast(llvm_args.items.len),
5095 toLlvmCallConv(fn_info.cc, target),5094 toLlvmCallConv(fn_info.cc, target),
5096 attr,5095 attr,
5097 "",5096 "",
...@@ -5256,7 +5255,7 @@ pub const FuncGen = struct {...@@ -5256,7 +5255,7 @@ pub const FuncGen = struct {
5256 const operand = try self.resolveInst(un_op);5255 const operand = try self.resolveInst(un_op);
5257 const ptr_ty = try mod.singleMutPtrType(ret_ty);5256 const ptr_ty = try mod.singleMutPtrType(ret_ty);
5258 try self.store(ret_ptr, ptr_ty, operand, .NotAtomic);5257 try self.store(ret_ptr, ptr_ty, operand, .NotAtomic);
5259 _ = self.builder.buildRetVoid();5258 try self.wip.retVoid();
5260 return null;5259 return null;
5261 }5260 }
5262 const fn_info = mod.typeToFunc(self.dg.decl.ty).?;5261 const fn_info = mod.typeToFunc(self.dg.decl.ty).?;
...@@ -5268,7 +5267,7 @@ pub const FuncGen = struct {...@@ -5268,7 +5267,7 @@ pub const FuncGen = struct {
5268 const int = try o.builder.intConst(Builder.Type.err_int, 0);5267 const int = try o.builder.intConst(Builder.Type.err_int, 0);
5269 _ = self.builder.buildRet(int.toLlvm(&o.builder));5268 _ = self.builder.buildRet(int.toLlvm(&o.builder));
5270 } else {5269 } else {
5271 _ = self.builder.buildRetVoid();5270 try self.wip.retVoid();
5272 }5271 }
5273 return null;5272 return null;
5274 }5273 }
...@@ -5316,12 +5315,12 @@ pub const FuncGen = struct {...@@ -5316,12 +5315,12 @@ pub const FuncGen = struct {
5316 const int = try o.builder.intConst(Builder.Type.err_int, 0);5315 const int = try o.builder.intConst(Builder.Type.err_int, 0);
5317 _ = self.builder.buildRet(int.toLlvm(&o.builder));5316 _ = self.builder.buildRet(int.toLlvm(&o.builder));
5318 } else {5317 } else {
5319 _ = self.builder.buildRetVoid();5318 try self.wip.retVoid();
5320 }5319 }
5321 return null;5320 return null;
5322 }5321 }
5323 if (self.ret_ptr != null) {5322 if (self.ret_ptr != null) {
5324 _ = self.builder.buildRetVoid();5323 try self.wip.retVoid();
5325 return null;5324 return null;
5326 }5325 }
5327 const ptr = try self.resolveInst(un_op);5326 const ptr = try self.resolveInst(un_op);
...@@ -5476,33 +5475,33 @@ pub const FuncGen = struct {...@@ -5476,33 +5475,33 @@ pub const FuncGen = struct {
5476 const rhs_non_null_i2 = self.builder.buildZExt(rhs_non_null, llvm_i2.toLlvm(&o.builder), "");5475 const rhs_non_null_i2 = self.builder.buildZExt(rhs_non_null, llvm_i2.toLlvm(&o.builder), "");
5477 const lhs_shifted = self.builder.buildShl(lhs_non_null_i2, (try o.builder.intConst(llvm_i2, 1)).toLlvm(&o.builder), "");5476 const lhs_shifted = self.builder.buildShl(lhs_non_null_i2, (try o.builder.intConst(llvm_i2, 1)).toLlvm(&o.builder), "");
5478 const lhs_rhs_ored = self.builder.buildOr(lhs_shifted, rhs_non_null_i2, "");5477 const lhs_rhs_ored = self.builder.buildOr(lhs_shifted, rhs_non_null_i2, "");
5479 const both_null_block = self.context.appendBasicBlock(self.llvm_func, "BothNull");5478 const both_null_block = try self.wip.block("BothNull");
5480 const mixed_block = self.context.appendBasicBlock(self.llvm_func, "Mixed");5479 const mixed_block = try self.wip.block("Mixed");
5481 const both_pl_block = self.context.appendBasicBlock(self.llvm_func, "BothNonNull");5480 const both_pl_block = try self.wip.block("BothNonNull");
5482 const end_block = self.context.appendBasicBlock(self.llvm_func, "End");5481 const end_block = try self.wip.block("End");
5483 const llvm_switch = self.builder.buildSwitch(lhs_rhs_ored, mixed_block, 2);5482 const llvm_switch = self.builder.buildSwitch(lhs_rhs_ored, mixed_block.toLlvm(&self.wip), 2);
5484 const llvm_i2_00 = try o.builder.intConst(llvm_i2, 0b00);5483 const llvm_i2_00 = try o.builder.intConst(llvm_i2, 0b00);
5485 const llvm_i2_11 = try o.builder.intConst(llvm_i2, 0b11);5484 const llvm_i2_11 = try o.builder.intConst(llvm_i2, 0b11);
5486 llvm_switch.addCase(llvm_i2_00.toLlvm(&o.builder), both_null_block);5485 llvm_switch.addCase(llvm_i2_00.toLlvm(&o.builder), both_null_block.toLlvm(&self.wip));
5487 llvm_switch.addCase(llvm_i2_11.toLlvm(&o.builder), both_pl_block);5486 llvm_switch.addCase(llvm_i2_11.toLlvm(&o.builder), both_pl_block.toLlvm(&self.wip));
54885487
5489 self.builder.positionBuilderAtEnd(both_null_block);5488 self.builder.positionBuilderAtEnd(both_null_block.toLlvm(&self.wip));
5490 _ = self.builder.buildBr(end_block);5489 _ = self.builder.buildBr(end_block.toLlvm(&self.wip));
54915490
5492 self.builder.positionBuilderAtEnd(mixed_block);5491 self.builder.positionBuilderAtEnd(mixed_block.toLlvm(&self.wip));
5493 _ = self.builder.buildBr(end_block);5492 _ = self.builder.buildBr(end_block.toLlvm(&self.wip));
54945493
5495 self.builder.positionBuilderAtEnd(both_pl_block);5494 self.builder.positionBuilderAtEnd(both_pl_block.toLlvm(&self.wip));
5496 const lhs_payload = try self.optPayloadHandle(opt_llvm_ty, lhs, scalar_ty, true);5495 const lhs_payload = try self.optPayloadHandle(opt_llvm_ty, lhs, scalar_ty, true);
5497 const rhs_payload = try self.optPayloadHandle(opt_llvm_ty, rhs, scalar_ty, true);5496 const rhs_payload = try self.optPayloadHandle(opt_llvm_ty, rhs, scalar_ty, true);
5498 const payload_cmp = try self.cmp(lhs_payload, rhs_payload, payload_ty, op);5497 const payload_cmp = try self.cmp(lhs_payload, rhs_payload, payload_ty, op);
5499 _ = self.builder.buildBr(end_block);5498 _ = self.builder.buildBr(end_block.toLlvm(&self.wip));
5500 const both_pl_block_end = self.builder.getInsertBlock();5499 const both_pl_block_end = self.builder.getInsertBlock();
55015500
5502 self.builder.positionBuilderAtEnd(end_block);5501 self.builder.positionBuilderAtEnd(end_block.toLlvm(&self.wip));
5503 const incoming_blocks: [3]*llvm.BasicBlock = .{5502 const incoming_blocks: [3]*llvm.BasicBlock = .{
5504 both_null_block,5503 both_null_block.toLlvm(&self.wip),
5505 mixed_block,5504 mixed_block.toLlvm(&self.wip),
5506 both_pl_block_end,5505 both_pl_block_end,
5507 };5506 };
5508 const llvm_i1_0 = Builder.Constant.false.toLlvm(&o.builder);5507 const llvm_i1_0 = Builder.Constant.false.toLlvm(&o.builder);
...@@ -5552,7 +5551,6 @@ pub const FuncGen = struct {...@@ -5552,7 +5551,6 @@ pub const FuncGen = struct {
5552 const extra = self.air.extraData(Air.Block, ty_pl.payload);5551 const extra = self.air.extraData(Air.Block, ty_pl.payload);
5553 const body = self.air.extra[extra.end..][0..extra.data.body_len];5552 const body = self.air.extra[extra.end..][0..extra.data.body_len];
5554 const inst_ty = self.typeOfIndex(inst);5553 const inst_ty = self.typeOfIndex(inst);
5555 const parent_bb = self.context.createBasicBlock("Block");
55565554
5557 if (inst_ty.isNoReturn(mod)) {5555 if (inst_ty.isNoReturn(mod)) {
5558 try self.genBody(body);5556 try self.genBody(body);
...@@ -5562,6 +5560,7 @@ pub const FuncGen = struct {...@@ -5562,6 +5560,7 @@ pub const FuncGen = struct {
5562 var breaks: BreakList = .{};5560 var breaks: BreakList = .{};
5563 defer breaks.deinit(self.gpa);5561 defer breaks.deinit(self.gpa);
55645562
5563 const parent_bb = try self.wip.block("Block");
5565 try self.blocks.putNoClobber(self.gpa, inst, .{5564 try self.blocks.putNoClobber(self.gpa, inst, .{
5566 .parent_bb = parent_bb,5565 .parent_bb = parent_bb,
5567 .breaks = &breaks,5566 .breaks = &breaks,
...@@ -5570,8 +5569,7 @@ pub const FuncGen = struct {...@@ -5570,8 +5569,7 @@ pub const FuncGen = struct {
55705569
5571 try self.genBody(body);5570 try self.genBody(body);
55725571
5573 self.llvm_func.appendExistingBasicBlock(parent_bb);5572 self.builder.positionBuilderAtEnd(parent_bb.toLlvm(&self.wip));
5574 self.builder.positionBuilderAtEnd(parent_bb);
55755573
5576 // Create a phi node only if the block returns a value.5574 // Create a phi node only if the block returns a value.
5577 const is_body = inst_ty.zigTypeTag(mod) == .Fn;5575 const is_body = inst_ty.zigTypeTag(mod) == .Fn;
...@@ -5585,7 +5583,7 @@ pub const FuncGen = struct {...@@ -5585,7 +5583,7 @@ pub const FuncGen = struct {
5585 // of function pointers, however the phi makes it a runtime value and therefore5583 // of function pointers, however the phi makes it a runtime value and therefore
5586 // the LLVM type has to be wrapped in a pointer.5584 // the LLVM type has to be wrapped in a pointer.
5587 if (is_body or isByRef(inst_ty, mod)) {5585 if (is_body or isByRef(inst_ty, mod)) {
5588 break :ty self.context.pointerType(0);5586 break :ty Builder.Type.ptr.toLlvm(&o.builder);
5589 }5587 }
5590 break :ty raw_llvm_ty;5588 break :ty raw_llvm_ty;
5591 };5589 };
...@@ -5594,7 +5592,7 @@ pub const FuncGen = struct {...@@ -5594,7 +5592,7 @@ pub const FuncGen = struct {
5594 phi_node.addIncoming(5592 phi_node.addIncoming(
5595 breaks.items(.val).ptr,5593 breaks.items(.val).ptr,
5596 breaks.items(.bb).ptr,5594 breaks.items(.bb).ptr,
5597 @as(c_uint, @intCast(breaks.len)),5595 @intCast(breaks.len),
5598 );5596 );
5599 return phi_node;5597 return phi_node;
5600 }5598 }
...@@ -5617,7 +5615,7 @@ pub const FuncGen = struct {...@@ -5617,7 +5615,7 @@ pub const FuncGen = struct {
5617 .val = val,5615 .val = val,
5618 });5616 });
5619 }5617 }
5620 _ = self.builder.buildBr(block.parent_bb);5618 _ = self.builder.buildBr(block.parent_bb.toLlvm(&self.wip));
5621 return null;5619 return null;
5622 }5620 }
56235621
...@@ -5628,14 +5626,14 @@ pub const FuncGen = struct {...@@ -5628,14 +5626,14 @@ pub const FuncGen = struct {
5628 const then_body = self.air.extra[extra.end..][0..extra.data.then_body_len];5626 const then_body = self.air.extra[extra.end..][0..extra.data.then_body_len];
5629 const else_body = self.air.extra[extra.end + then_body.len ..][0..extra.data.else_body_len];5627 const else_body = self.air.extra[extra.end + then_body.len ..][0..extra.data.else_body_len];
56305628
5631 const then_block = self.context.appendBasicBlock(self.llvm_func, "Then");5629 const then_block = try self.wip.block("Then");
5632 const else_block = self.context.appendBasicBlock(self.llvm_func, "Else");5630 const else_block = try self.wip.block("Else");
5633 _ = self.builder.buildCondBr(cond, then_block, else_block);5631 _ = self.builder.buildCondBr(cond, then_block.toLlvm(&self.wip), else_block.toLlvm(&self.wip));
56345632
5635 self.builder.positionBuilderAtEnd(then_block);5633 self.builder.positionBuilderAtEnd(then_block.toLlvm(&self.wip));
5636 try self.genBody(then_body);5634 try self.genBody(then_body);
56375635
5638 self.builder.positionBuilderAtEnd(else_block);5636 self.builder.positionBuilderAtEnd(else_block.toLlvm(&self.wip));
5639 try self.genBody(else_body);5637 try self.genBody(else_body);
56405638
5641 // No need to reset the insert cursor since this instruction is noreturn.5639 // No need to reset the insert cursor since this instruction is noreturn.
...@@ -5707,14 +5705,14 @@ pub const FuncGen = struct {...@@ -5707,14 +5705,14 @@ pub const FuncGen = struct {
5707 break :err fg.builder.buildICmp(.NE, loaded, zero, "");5705 break :err fg.builder.buildICmp(.NE, loaded, zero, "");
5708 };5706 };
57095707
5710 const return_block = fg.context.appendBasicBlock(fg.llvm_func, "TryRet");5708 const return_block = try fg.wip.block("TryRet");
5711 const continue_block = fg.context.appendBasicBlock(fg.llvm_func, "TryCont");5709 const continue_block = try fg.wip.block("TryCont");
5712 _ = fg.builder.buildCondBr(is_err, return_block, continue_block);5710 _ = fg.builder.buildCondBr(is_err, return_block.toLlvm(&fg.wip), continue_block.toLlvm(&fg.wip));
57135711
5714 fg.builder.positionBuilderAtEnd(return_block);5712 fg.builder.positionBuilderAtEnd(return_block.toLlvm(&fg.wip));
5715 try fg.genBody(body);5713 try fg.genBody(body);
57165714
5717 fg.builder.positionBuilderAtEnd(continue_block);5715 fg.builder.positionBuilderAtEnd(continue_block.toLlvm(&fg.wip));
5718 }5716 }
5719 if (is_unused) {5717 if (is_unused) {
5720 return null;5718 return null;
...@@ -5745,24 +5743,24 @@ pub const FuncGen = struct {...@@ -5745,24 +5743,24 @@ pub const FuncGen = struct {
5745 const pl_op = self.air.instructions.items(.data)[inst].pl_op;5743 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
5746 const cond = try self.resolveInst(pl_op.operand);5744 const cond = try self.resolveInst(pl_op.operand);
5747 const switch_br = self.air.extraData(Air.SwitchBr, pl_op.payload);5745 const switch_br = self.air.extraData(Air.SwitchBr, pl_op.payload);
5748 const else_block = self.context.appendBasicBlock(self.llvm_func, "Else");5746 const else_block = try self.wip.block("Else");
5749 const llvm_usize = (try o.lowerType(Type.usize)).toLlvm(&o.builder);5747 const llvm_usize = (try o.lowerType(Type.usize)).toLlvm(&o.builder);
5750 const cond_int = if (cond.typeOf().getTypeKind() == .Pointer)5748 const cond_int = if (cond.typeOf().getTypeKind() == .Pointer)
5751 self.builder.buildPtrToInt(cond, llvm_usize, "")5749 self.builder.buildPtrToInt(cond, llvm_usize, "")
5752 else5750 else
5753 cond;5751 cond;
5754 const llvm_switch = self.builder.buildSwitch(cond_int, else_block, switch_br.data.cases_len);5752 const llvm_switch = self.builder.buildSwitch(cond_int, else_block.toLlvm(&self.wip), switch_br.data.cases_len);
57555753
5756 var extra_index: usize = switch_br.end;5754 var extra_index: usize = switch_br.end;
5757 var case_i: u32 = 0;5755 var case_i: u32 = 0;
57585756
5759 while (case_i < switch_br.data.cases_len) : (case_i += 1) {5757 while (case_i < switch_br.data.cases_len) : (case_i += 1) {
5760 const case = self.air.extraData(Air.SwitchBr.Case, extra_index);5758 const case = self.air.extraData(Air.SwitchBr.Case, extra_index);
5761 const items = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[case.end..][0..case.data.items_len]));5759 const items: []const Air.Inst.Ref = @ptrCast(self.air.extra[case.end..][0..case.data.items_len]);
5762 const case_body = self.air.extra[case.end + items.len ..][0..case.data.body_len];5760 const case_body = self.air.extra[case.end + items.len ..][0..case.data.body_len];
5763 extra_index = case.end + case.data.items_len + case_body.len;5761 extra_index = case.end + case.data.items_len + case_body.len;
57645762
5765 const case_block = self.context.appendBasicBlock(self.llvm_func, "Case");5763 const case_block = try self.wip.block("Case");
57665764
5767 for (items) |item| {5765 for (items) |item| {
5768 const llvm_item = try self.resolveInst(item);5766 const llvm_item = try self.resolveInst(item);
...@@ -5770,14 +5768,14 @@ pub const FuncGen = struct {...@@ -5770,14 +5768,14 @@ pub const FuncGen = struct {
5770 llvm_item.constPtrToInt(llvm_usize)5768 llvm_item.constPtrToInt(llvm_usize)
5771 else5769 else
5772 llvm_item;5770 llvm_item;
5773 llvm_switch.addCase(llvm_int_item, case_block);5771 llvm_switch.addCase(llvm_int_item, case_block.toLlvm(&self.wip));
5774 }5772 }
57755773
5776 self.builder.positionBuilderAtEnd(case_block);5774 self.builder.positionBuilderAtEnd(case_block.toLlvm(&self.wip));
5777 try self.genBody(case_body);5775 try self.genBody(case_body);
5778 }5776 }
57795777
5780 self.builder.positionBuilderAtEnd(else_block);5778 self.builder.positionBuilderAtEnd(else_block.toLlvm(&self.wip));
5781 const else_body = self.air.extra[extra_index..][0..switch_br.data.else_body_len];5779 const else_body = self.air.extra[extra_index..][0..switch_br.data.else_body_len];
5782 if (else_body.len != 0) {5780 if (else_body.len != 0) {
5783 try self.genBody(else_body);5781 try self.genBody(else_body);
...@@ -5795,10 +5793,10 @@ pub const FuncGen = struct {...@@ -5795,10 +5793,10 @@ pub const FuncGen = struct {
5795 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;5793 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
5796 const loop = self.air.extraData(Air.Block, ty_pl.payload);5794 const loop = self.air.extraData(Air.Block, ty_pl.payload);
5797 const body = self.air.extra[loop.end..][0..loop.data.body_len];5795 const body = self.air.extra[loop.end..][0..loop.data.body_len];
5798 const loop_block = self.context.appendBasicBlock(self.llvm_func, "Loop");5796 const loop_block = try self.wip.block("Loop");
5799 _ = self.builder.buildBr(loop_block);5797 _ = self.builder.buildBr(loop_block.toLlvm(&self.wip));
58005798
5801 self.builder.positionBuilderAtEnd(loop_block);5799 self.builder.positionBuilderAtEnd(loop_block.toLlvm(&self.wip));
5802 try self.genBody(body);5800 try self.genBody(body);
58035801
5804 // TODO instead of this logic, change AIR to have the property that5802 // TODO instead of this logic, change AIR to have the property that
...@@ -5808,7 +5806,7 @@ pub const FuncGen = struct {...@@ -5808,7 +5806,7 @@ pub const FuncGen = struct {
5808 // be while(true) instead of for(body), which will eliminate 1 branch on5806 // be while(true) instead of for(body), which will eliminate 1 branch on
5809 // a hot path.5807 // a hot path.
5810 if (body.len == 0 or !self.typeOfIndex(body[body.len - 1]).isNoReturn(mod)) {5808 if (body.len == 0 or !self.typeOfIndex(body[body.len - 1]).isNoReturn(mod)) {
5811 _ = self.builder.buildBr(loop_block);5809 _ = self.builder.buildBr(loop_block.toLlvm(&self.wip));
5812 }5810 }
5813 return null;5811 return null;
5814 }5812 }
...@@ -5858,8 +5856,7 @@ pub const FuncGen = struct {...@@ -5858,8 +5856,7 @@ pub const FuncGen = struct {
5858 }5856 }
5859 }5857 }
58605858
5861 const operand_bits = @as(u16, @intCast(operand_scalar_ty.bitSize(mod)));5859 const rt_int_bits = compilerRtIntBits(@intCast(operand_scalar_ty.bitSize(mod)));
5862 const rt_int_bits = compilerRtIntBits(operand_bits);
5863 const rt_int_ty = try o.builder.intType(rt_int_bits);5860 const rt_int_ty = try o.builder.intType(rt_int_bits);
5864 var extended = e: {5861 var extended = e: {
5865 if (operand_scalar_ty.isSignedInt(mod)) {5862 if (operand_scalar_ty.isSignedInt(mod)) {
...@@ -6193,13 +6190,11 @@ pub const FuncGen = struct {...@@ -6193,13 +6190,11 @@ pub const FuncGen = struct {
6193 const shifted_value = self.builder.buildLShr(containing_int, shift_amt, "");6190 const shifted_value = self.builder.buildLShr(containing_int, shift_amt, "");
6194 const elem_llvm_ty = (try o.lowerType(field_ty)).toLlvm(&o.builder);6191 const elem_llvm_ty = (try o.lowerType(field_ty)).toLlvm(&o.builder);
6195 if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) {6192 if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) {
6196 const elem_bits = @as(c_uint, @intCast(field_ty.bitSize(mod)));6193 const same_size_int = (try o.builder.intType(@intCast(field_ty.bitSize(mod)))).toLlvm(&o.builder);
6197 const same_size_int = (try o.builder.intType(@intCast(elem_bits))).toLlvm(&o.builder);
6198 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");6194 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");
6199 return self.builder.buildBitCast(truncated_int, elem_llvm_ty, "");6195 return self.builder.buildBitCast(truncated_int, elem_llvm_ty, "");
6200 } else if (field_ty.isPtrAtRuntime(mod)) {6196 } else if (field_ty.isPtrAtRuntime(mod)) {
6201 const elem_bits = @as(c_uint, @intCast(field_ty.bitSize(mod)));6197 const same_size_int = (try o.builder.intType(@intCast(field_ty.bitSize(mod)))).toLlvm(&o.builder);
6202 const same_size_int = (try o.builder.intType(@intCast(elem_bits))).toLlvm(&o.builder);
6203 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");6198 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");
6204 return self.builder.buildIntToPtr(truncated_int, elem_llvm_ty, "");6199 return self.builder.buildIntToPtr(truncated_int, elem_llvm_ty, "");
6205 }6200 }
...@@ -6215,13 +6210,11 @@ pub const FuncGen = struct {...@@ -6215,13 +6210,11 @@ pub const FuncGen = struct {
6215 const containing_int = struct_llvm_val;6210 const containing_int = struct_llvm_val;
6216 const elem_llvm_ty = (try o.lowerType(field_ty)).toLlvm(&o.builder);6211 const elem_llvm_ty = (try o.lowerType(field_ty)).toLlvm(&o.builder);
6217 if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) {6212 if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) {
6218 const elem_bits = @as(c_uint, @intCast(field_ty.bitSize(mod)));6213 const same_size_int = (try o.builder.intType(@intCast(field_ty.bitSize(mod)))).toLlvm(&o.builder);
6219 const same_size_int = (try o.builder.intType(@intCast(elem_bits))).toLlvm(&o.builder);
6220 const truncated_int = self.builder.buildTrunc(containing_int, same_size_int, "");6214 const truncated_int = self.builder.buildTrunc(containing_int, same_size_int, "");
6221 return self.builder.buildBitCast(truncated_int, elem_llvm_ty, "");6215 return self.builder.buildBitCast(truncated_int, elem_llvm_ty, "");
6222 } else if (field_ty.isPtrAtRuntime(mod)) {6216 } else if (field_ty.isPtrAtRuntime(mod)) {
6223 const elem_bits = @as(c_uint, @intCast(field_ty.bitSize(mod)));6217 const same_size_int = (try o.builder.intType(@intCast(field_ty.bitSize(mod)))).toLlvm(&o.builder);
6224 const same_size_int = (try o.builder.intType(@intCast(elem_bits))).toLlvm(&o.builder);
6225 const truncated_int = self.builder.buildTrunc(containing_int, same_size_int, "");6218 const truncated_int = self.builder.buildTrunc(containing_int, same_size_int, "");
6226 return self.builder.buildIntToPtr(truncated_int, elem_llvm_ty, "");6219 return self.builder.buildIntToPtr(truncated_int, elem_llvm_ty, "");
6227 }6220 }
...@@ -6310,8 +6303,8 @@ pub const FuncGen = struct {...@@ -6310,8 +6303,8 @@ pub const FuncGen = struct {
6310 fn airDbgStmt(self: *FuncGen, inst: Air.Inst.Index) ?*llvm.Value {6303 fn airDbgStmt(self: *FuncGen, inst: Air.Inst.Index) ?*llvm.Value {
6311 const di_scope = self.di_scope orelse return null;6304 const di_scope = self.di_scope orelse return null;
6312 const dbg_stmt = self.air.instructions.items(.data)[inst].dbg_stmt;6305 const dbg_stmt = self.air.instructions.items(.data)[inst].dbg_stmt;
6313 self.prev_dbg_line = @as(c_uint, @intCast(self.base_line + dbg_stmt.line + 1));6306 self.prev_dbg_line = @intCast(self.base_line + dbg_stmt.line + 1);
6314 self.prev_dbg_column = @as(c_uint, @intCast(dbg_stmt.column + 1));6307 self.prev_dbg_column = @intCast(dbg_stmt.column + 1);
6315 const inlined_at = if (self.dbg_inlined.items.len > 0)6308 const inlined_at = if (self.dbg_inlined.items.len > 0)
6316 self.dbg_inlined.items[self.dbg_inlined.items.len - 1].loc6309 self.dbg_inlined.items[self.dbg_inlined.items.len - 1].loc
6317 else6310 else
...@@ -6491,12 +6484,12 @@ pub const FuncGen = struct {...@@ -6491,12 +6484,12 @@ pub const FuncGen = struct {
6491 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;6484 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
6492 const extra = self.air.extraData(Air.Asm, ty_pl.payload);6485 const extra = self.air.extraData(Air.Asm, ty_pl.payload);
6493 const is_volatile = @as(u1, @truncate(extra.data.flags >> 31)) != 0;6486 const is_volatile = @as(u1, @truncate(extra.data.flags >> 31)) != 0;
6494 const clobbers_len = @as(u31, @truncate(extra.data.flags));6487 const clobbers_len: u31 = @truncate(extra.data.flags);
6495 var extra_i: usize = extra.end;6488 var extra_i: usize = extra.end;
64966489
6497 const outputs = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[extra_i..][0..extra.data.outputs_len]));6490 const outputs: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra_i..][0..extra.data.outputs_len]);
6498 extra_i += outputs.len;6491 extra_i += outputs.len;
6499 const inputs = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[extra_i..][0..extra.data.inputs_len]));6492 const inputs: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra_i..][0..extra.data.inputs_len]);
6500 extra_i += inputs.len;6493 extra_i += inputs.len;
65016494
6502 var llvm_constraints: std.ArrayListUnmanaged(u8) = .{};6495 var llvm_constraints: std.ArrayListUnmanaged(u8) = .{};
...@@ -6779,7 +6772,7 @@ pub const FuncGen = struct {...@@ -6779,7 +6772,7 @@ pub const FuncGen = struct {
6779 const llvm_fn_ty = llvm.functionType(6772 const llvm_fn_ty = llvm.functionType(
6780 ret_llvm_ty.toLlvm(&o.builder),6773 ret_llvm_ty.toLlvm(&o.builder),
6781 llvm_param_types.ptr,6774 llvm_param_types.ptr,
6782 @as(c_uint, @intCast(param_count)),6775 @intCast(param_count),
6783 .False,6776 .False,
6784 );6777 );
6785 const asm_fn = llvm.getInlineAsm(6778 const asm_fn = llvm.getInlineAsm(
...@@ -6797,7 +6790,7 @@ pub const FuncGen = struct {...@@ -6797,7 +6790,7 @@ pub const FuncGen = struct {
6797 llvm_fn_ty,6790 llvm_fn_ty,
6798 asm_fn,6791 asm_fn,
6799 llvm_param_values.ptr,6792 llvm_param_values.ptr,
6800 @as(c_uint, @intCast(param_count)),6793 @intCast(param_count),
6801 .C,6794 .C,
6802 .Auto,6795 .Auto,
6803 "",6796 "",
...@@ -6814,7 +6807,7 @@ pub const FuncGen = struct {...@@ -6814,7 +6807,7 @@ pub const FuncGen = struct {
6814 if (llvm_ret_indirect[i]) continue;6807 if (llvm_ret_indirect[i]) continue;
68156808
6816 const output_value = if (return_count > 1) b: {6809 const output_value = if (return_count > 1) b: {
6817 break :b self.builder.buildExtractValue(call, @as(c_uint, @intCast(llvm_ret_i)), "");6810 break :b self.builder.buildExtractValue(call, @intCast(llvm_ret_i), "");
6818 } else call;6811 } else call;
68196812
6820 if (output != .none) {6813 if (output != .none) {
...@@ -7364,14 +7357,14 @@ pub const FuncGen = struct {...@@ -7364,14 +7357,14 @@ pub const FuncGen = struct {
7364 false => fg.builder.buildOrReduce(overflow_bit),7357 false => fg.builder.buildOrReduce(overflow_bit),
7365 };7358 };
73667359
7367 const fail_block = fg.context.appendBasicBlock(fg.llvm_func, "OverflowFail");7360 const fail_block = try fg.wip.block("OverflowFail");
7368 const ok_block = fg.context.appendBasicBlock(fg.llvm_func, "OverflowOk");7361 const ok_block = try fg.wip.block("OverflowOk");
7369 _ = fg.builder.buildCondBr(scalar_overflow_bit, fail_block, ok_block);7362 _ = fg.builder.buildCondBr(scalar_overflow_bit, fail_block.toLlvm(&fg.wip), ok_block.toLlvm(&fg.wip));
73707363
7371 fg.builder.positionBuilderAtEnd(fail_block);7364 fg.builder.positionBuilderAtEnd(fail_block.toLlvm(&fg.wip));
7372 try fg.buildSimplePanic(.integer_overflow);7365 try fg.buildSimplePanic(.integer_overflow);
73737366
7374 fg.builder.positionBuilderAtEnd(ok_block);7367 fg.builder.positionBuilderAtEnd(ok_block.toLlvm(&fg.wip));
7375 return fg.builder.buildExtractValue(result_struct, 0, "");7368 return fg.builder.buildExtractValue(result_struct, 0, "");
7376 }7369 }
73777370
...@@ -7729,8 +7722,7 @@ pub const FuncGen = struct {...@@ -7729,8 +7722,7 @@ pub const FuncGen = struct {
7729 vector_len: usize,7722 vector_len: usize,
7730 ) !*llvm.Value {7723 ) !*llvm.Value {
7731 const o = self.dg.object;7724 const o = self.dg.object;
7732 const args_len = @as(c_uint, @intCast(args_vectors.len));7725 assert(args_vectors.len <= 3);
7733 assert(args_len <= 3);
77347726
7735 var i: usize = 0;7727 var i: usize = 0;
7736 var result = result_vector;7728 var result = result_vector;
...@@ -7741,7 +7733,7 @@ pub const FuncGen = struct {...@@ -7741,7 +7733,7 @@ pub const FuncGen = struct {
7741 for (args_vectors, 0..) |arg_vector, k| {7733 for (args_vectors, 0..) |arg_vector, k| {
7742 args[k] = self.builder.buildExtractElement(arg_vector, index_i32, "");7734 args[k] = self.builder.buildExtractElement(arg_vector, index_i32, "");
7743 }7735 }
7744 const result_elem = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args_len, .C, .Auto, "");7736 const result_elem = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, @intCast(args_vectors.len), .C, .Auto, "");
7745 result = self.builder.buildInsertElement(result, result_elem, index_i32, "");7737 result = self.builder.buildInsertElement(result, result_elem, index_i32, "");
7746 }7738 }
7747 return result;7739 return result;
...@@ -8744,8 +8736,8 @@ pub const FuncGen = struct {...@@ -8744,8 +8736,8 @@ pub const FuncGen = struct {
8744 return null;8736 return null;
8745 const ordering = toLlvmAtomicOrdering(atomic_load.order);8737 const ordering = toLlvmAtomicOrdering(atomic_load.order);
8746 const abi_ty = try o.getAtomicAbiType(elem_ty, false);8738 const abi_ty = try o.getAtomicAbiType(elem_ty, false);
8747 const ptr_alignment = @as(u32, @intCast(ptr_info.flags.alignment.toByteUnitsOptional() orelse8739 const ptr_alignment: u32 = @intCast(ptr_info.flags.alignment.toByteUnitsOptional() orelse
8748 ptr_info.child.toType().abiAlignment(mod)));8740 ptr_info.child.toType().abiAlignment(mod));
8749 const ptr_volatile = llvm.Bool.fromBool(ptr_info.flags.is_volatile);8741 const ptr_volatile = llvm.Bool.fromBool(ptr_info.flags.is_volatile);
8750 const elem_llvm_ty = (try o.lowerType(elem_ty)).toLlvm(&o.builder);8742 const elem_llvm_ty = (try o.lowerType(elem_ty)).toLlvm(&o.builder);
87518743
...@@ -8887,9 +8879,9 @@ pub const FuncGen = struct {...@@ -8887,9 +8879,9 @@ pub const FuncGen = struct {
8887 // end:8879 // end:
8888 // ...8880 // ...
8889 const entry_block = self.builder.getInsertBlock();8881 const entry_block = self.builder.getInsertBlock();
8890 const loop_block = self.context.appendBasicBlock(self.llvm_func, "InlineMemsetLoop");8882 const loop_block = try self.wip.block("InlineMemsetLoop");
8891 const body_block = self.context.appendBasicBlock(self.llvm_func, "InlineMemsetBody");8883 const body_block = try self.wip.block("InlineMemsetBody");
8892 const end_block = self.context.appendBasicBlock(self.llvm_func, "InlineMemsetEnd");8884 const end_block = try self.wip.block("InlineMemsetEnd");
88938885
8894 const usize_ty = try o.lowerType(Type.usize);8886 const usize_ty = try o.lowerType(Type.usize);
8895 const len = switch (ptr_ty.ptrSize(mod)) {8887 const len = switch (ptr_ty.ptrSize(mod)) {
...@@ -8900,14 +8892,14 @@ pub const FuncGen = struct {...@@ -8900,14 +8892,14 @@ pub const FuncGen = struct {
8900 const elem_llvm_ty = (try o.lowerType(elem_ty)).toLlvm(&o.builder);8892 const elem_llvm_ty = (try o.lowerType(elem_ty)).toLlvm(&o.builder);
8901 const len_gep = [_]*llvm.Value{len};8893 const len_gep = [_]*llvm.Value{len};
8902 const end_ptr = self.builder.buildInBoundsGEP(elem_llvm_ty, dest_ptr, &len_gep, len_gep.len, "");8894 const end_ptr = self.builder.buildInBoundsGEP(elem_llvm_ty, dest_ptr, &len_gep, len_gep.len, "");
8903 _ = self.builder.buildBr(loop_block);8895 _ = self.builder.buildBr(loop_block.toLlvm(&self.wip));
89048896
8905 self.builder.positionBuilderAtEnd(loop_block);8897 self.builder.positionBuilderAtEnd(loop_block.toLlvm(&self.wip));
8906 const it_ptr = self.builder.buildPhi(self.context.pointerType(0), "");8898 const it_ptr = self.builder.buildPhi(Builder.Type.ptr.toLlvm(&o.builder), "");
8907 const end = self.builder.buildICmp(.NE, it_ptr, end_ptr, "");8899 const end = self.builder.buildICmp(.NE, it_ptr, end_ptr, "");
8908 _ = self.builder.buildCondBr(end, body_block, end_block);8900 _ = self.builder.buildCondBr(end, body_block.toLlvm(&self.wip), end_block.toLlvm(&self.wip));
89098901
8910 self.builder.positionBuilderAtEnd(body_block);8902 self.builder.positionBuilderAtEnd(body_block.toLlvm(&self.wip));
8911 const elem_abi_alignment = elem_ty.abiAlignment(mod);8903 const elem_abi_alignment = elem_ty.abiAlignment(mod);
8912 const it_ptr_alignment = @min(elem_abi_alignment, dest_ptr_align);8904 const it_ptr_alignment = @min(elem_abi_alignment, dest_ptr_align);
8913 if (isByRef(elem_ty, mod)) {8905 if (isByRef(elem_ty, mod)) {
...@@ -8928,12 +8920,12 @@ pub const FuncGen = struct {...@@ -8928,12 +8920,12 @@ pub const FuncGen = struct {
8928 (try o.builder.intConst(usize_ty, 1)).toLlvm(&o.builder),8920 (try o.builder.intConst(usize_ty, 1)).toLlvm(&o.builder),
8929 };8921 };
8930 const next_ptr = self.builder.buildInBoundsGEP(elem_llvm_ty, it_ptr, &one_gep, one_gep.len, "");8922 const next_ptr = self.builder.buildInBoundsGEP(elem_llvm_ty, it_ptr, &one_gep, one_gep.len, "");
8931 _ = self.builder.buildBr(loop_block);8923 _ = self.builder.buildBr(loop_block.toLlvm(&self.wip));
89328924
8933 self.builder.positionBuilderAtEnd(end_block);8925 self.builder.positionBuilderAtEnd(end_block.toLlvm(&self.wip));
89348926
8935 const incoming_values: [2]*llvm.Value = .{ next_ptr, dest_ptr };8927 const incoming_values: [2]*llvm.Value = .{ next_ptr, dest_ptr };
8936 const incoming_blocks: [2]*llvm.BasicBlock = .{ body_block, entry_block };8928 const incoming_blocks: [2]*llvm.BasicBlock = .{ body_block.toLlvm(&self.wip), entry_block };
8937 it_ptr.addIncoming(&incoming_values, &incoming_blocks, 2);8929 it_ptr.addIncoming(&incoming_values, &incoming_blocks, 2);
89388930
8939 return null;8931 return null;
...@@ -8950,13 +8942,13 @@ pub const FuncGen = struct {...@@ -8950,13 +8942,13 @@ pub const FuncGen = struct {
8950 const o = self.dg.object;8942 const o = self.dg.object;
8951 const llvm_usize_ty = try o.lowerType(Type.usize);8943 const llvm_usize_ty = try o.lowerType(Type.usize);
8952 const cond = try self.cmp(len, (try o.builder.intConst(llvm_usize_ty, 0)).toLlvm(&o.builder), Type.usize, .neq);8944 const cond = try self.cmp(len, (try o.builder.intConst(llvm_usize_ty, 0)).toLlvm(&o.builder), Type.usize, .neq);
8953 const memset_block = self.context.appendBasicBlock(self.llvm_func, "MemsetTrapSkip");8945 const memset_block = try self.wip.block("MemsetTrapSkip");
8954 const end_block = self.context.appendBasicBlock(self.llvm_func, "MemsetTrapEnd");8946 const end_block = try self.wip.block("MemsetTrapEnd");
8955 _ = self.builder.buildCondBr(cond, memset_block, end_block);8947 _ = self.builder.buildCondBr(cond, memset_block.toLlvm(&self.wip), end_block.toLlvm(&self.wip));
8956 self.builder.positionBuilderAtEnd(memset_block);8948 self.builder.positionBuilderAtEnd(memset_block.toLlvm(&self.wip));
8957 _ = self.builder.buildMemSet(dest_ptr, fill_byte, len, dest_ptr_align, is_volatile);8949 _ = self.builder.buildMemSet(dest_ptr, fill_byte, len, dest_ptr_align, is_volatile);
8958 _ = self.builder.buildBr(end_block);8950 _ = self.builder.buildBr(end_block.toLlvm(&self.wip));
8959 self.builder.positionBuilderAtEnd(end_block);8951 self.builder.positionBuilderAtEnd(end_block.toLlvm(&self.wip));
8960 }8952 }
89618953
8962 fn airMemcpy(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {8954 fn airMemcpy(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
...@@ -8983,10 +8975,10 @@ pub const FuncGen = struct {...@@ -8983,10 +8975,10 @@ pub const FuncGen = struct {
8983 {8975 {
8984 const llvm_usize_ty = try o.lowerType(Type.usize);8976 const llvm_usize_ty = try o.lowerType(Type.usize);
8985 const cond = try self.cmp(len, (try o.builder.intConst(llvm_usize_ty, 0)).toLlvm(&o.builder), Type.usize, .neq);8977 const cond = try self.cmp(len, (try o.builder.intConst(llvm_usize_ty, 0)).toLlvm(&o.builder), Type.usize, .neq);
8986 const memcpy_block = self.context.appendBasicBlock(self.llvm_func, "MemcpyTrapSkip");8978 const memcpy_block = try self.wip.block("MemcpyTrapSkip");
8987 const end_block = self.context.appendBasicBlock(self.llvm_func, "MemcpyTrapEnd");8979 const end_block = try self.wip.block("MemcpyTrapEnd");
8988 _ = self.builder.buildCondBr(cond, memcpy_block, end_block);8980 _ = self.builder.buildCondBr(cond, memcpy_block.toLlvm(&self.wip), end_block.toLlvm(&self.wip));
8989 self.builder.positionBuilderAtEnd(memcpy_block);8981 self.builder.positionBuilderAtEnd(memcpy_block.toLlvm(&self.wip));
8990 _ = self.builder.buildMemCpy(8982 _ = self.builder.buildMemCpy(
8991 dest_ptr,8983 dest_ptr,
8992 dest_ptr_ty.ptrAlignment(mod),8984 dest_ptr_ty.ptrAlignment(mod),
...@@ -8995,8 +8987,8 @@ pub const FuncGen = struct {...@@ -8995,8 +8987,8 @@ pub const FuncGen = struct {
8995 len,8987 len,
8996 is_volatile,8988 is_volatile,
8997 );8989 );
8998 _ = self.builder.buildBr(end_block);8990 _ = self.builder.buildBr(end_block.toLlvm(&self.wip));
8999 self.builder.positionBuilderAtEnd(end_block);8991 self.builder.positionBuilderAtEnd(end_block.toLlvm(&self.wip));
9000 return null;8992 return null;
9001 }8993 }
90028994
...@@ -9179,31 +9171,31 @@ pub const FuncGen = struct {...@@ -9179,31 +9171,31 @@ pub const FuncGen = struct {
9179 const error_set_ty = self.air.getRefType(ty_op.ty);9171 const error_set_ty = self.air.getRefType(ty_op.ty);
91809172
9181 const names = error_set_ty.errorSetNames(mod);9173 const names = error_set_ty.errorSetNames(mod);
9182 const valid_block = self.context.appendBasicBlock(self.llvm_func, "Valid");9174 const valid_block = try self.wip.block("Valid");
9183 const invalid_block = self.context.appendBasicBlock(self.llvm_func, "Invalid");9175 const invalid_block = try self.wip.block("Invalid");
9184 const end_block = self.context.appendBasicBlock(self.llvm_func, "End");9176 const end_block = try self.wip.block("End");
9185 const switch_instr = self.builder.buildSwitch(operand, invalid_block, @as(c_uint, @intCast(names.len)));9177 const switch_instr = self.builder.buildSwitch(operand, invalid_block.toLlvm(&self.wip), @intCast(names.len));
91869178
9187 for (names) |name| {9179 for (names) |name| {
9188 const err_int = @as(Module.ErrorInt, @intCast(mod.global_error_set.getIndex(name).?));9180 const err_int = mod.global_error_set.getIndex(name).?;
9189 const this_tag_int_value =9181 const this_tag_int_value =
9190 try o.lowerValue((try mod.intValue(Type.err_int, err_int)).toIntern());9182 try o.lowerValue((try mod.intValue(Type.err_int, err_int)).toIntern());
9191 switch_instr.addCase(this_tag_int_value.toLlvm(&o.builder), valid_block);9183 switch_instr.addCase(this_tag_int_value.toLlvm(&o.builder), valid_block.toLlvm(&self.wip));
9192 }9184 }
9193 self.builder.positionBuilderAtEnd(valid_block);9185 self.builder.positionBuilderAtEnd(valid_block.toLlvm(&self.wip));
9194 _ = self.builder.buildBr(end_block);9186 _ = self.builder.buildBr(end_block.toLlvm(&self.wip));
91959187
9196 self.builder.positionBuilderAtEnd(invalid_block);9188 self.builder.positionBuilderAtEnd(invalid_block.toLlvm(&self.wip));
9197 _ = self.builder.buildBr(end_block);9189 _ = self.builder.buildBr(end_block.toLlvm(&self.wip));
91989190
9199 self.builder.positionBuilderAtEnd(end_block);9191 self.builder.positionBuilderAtEnd(end_block.toLlvm(&self.wip));
92009192
9201 const incoming_values: [2]*llvm.Value = .{9193 const incoming_values: [2]*llvm.Value = .{
9202 Builder.Constant.true.toLlvm(&o.builder),9194 Builder.Constant.true.toLlvm(&o.builder),
9203 Builder.Constant.false.toLlvm(&o.builder),9195 Builder.Constant.false.toLlvm(&o.builder),
9204 };9196 };
9205 const incoming_blocks: [2]*llvm.BasicBlock = .{9197 const incoming_blocks: [2]*llvm.BasicBlock = .{
9206 valid_block, invalid_block,9198 valid_block.toLlvm(&self.wip), invalid_block.toLlvm(&self.wip),
9207 };9199 };
9208 const phi_node = self.builder.buildPhi(Builder.Type.i1.toLlvm(&o.builder), "");9200 const phi_node = self.builder.buildPhi(Builder.Type.i1.toLlvm(&o.builder), "");
9209 phi_node.addIncoming(&incoming_values, &incoming_blocks, 2);9201 phi_node.addIncoming(&incoming_values, &incoming_blocks, 2);
...@@ -9250,8 +9242,11 @@ pub const FuncGen = struct {...@@ -9250,8 +9242,11 @@ pub const FuncGen = struct {
9250 };9242 };
9251 var function = Builder.Function{9243 var function = Builder.Function{
9252 .global = @enumFromInt(o.builder.globals.count()),9244 .global = @enumFromInt(o.builder.globals.count()),
9253 .body = {},
9254 };9245 };
9246 try o.builder.llvm.globals.append(self.gpa, fn_val);
9247 _ = try o.builder.addGlobal(llvm_fn_name, global);
9248 try o.builder.functions.append(self.gpa, function);
9249 gop.value_ptr.* = global.kind.function;
92559250
9256 const prev_block = self.builder.getInsertBlock();9251 const prev_block = self.builder.getInsertBlock();
9257 const prev_debug_location = self.builder.getCurrentDebugLocation2();9252 const prev_debug_location = self.builder.getCurrentDebugLocation2();
...@@ -9262,31 +9257,30 @@ pub const FuncGen = struct {...@@ -9262,31 +9257,30 @@ pub const FuncGen = struct {
9262 }9257 }
9263 }9258 }
92649259
9265 const entry_block = self.context.appendBasicBlock(fn_val, "Entry");9260 var wip = Builder.WipFunction.init(&o.builder, global.kind.function);
9266 self.builder.positionBuilderAtEnd(entry_block);9261 defer wip.deinit();
9262
9263 const entry_block = try wip.block("Entry");
9264 self.builder.positionBuilderAtEnd(entry_block.toLlvm(&wip));
9267 self.builder.clearCurrentDebugLocation();9265 self.builder.clearCurrentDebugLocation();
92689266
9269 const named_block = self.context.appendBasicBlock(fn_val, "Named");9267 const named_block = try wip.block("Named");
9270 const unnamed_block = self.context.appendBasicBlock(fn_val, "Unnamed");9268 const unnamed_block = try wip.block("Unnamed");
9271 const tag_int_value = fn_val.getParam(0);9269 const tag_int_value = fn_val.getParam(0);
9272 const switch_instr = self.builder.buildSwitch(tag_int_value, unnamed_block, @as(c_uint, @intCast(enum_type.names.len)));9270 const switch_instr = self.builder.buildSwitch(tag_int_value, unnamed_block.toLlvm(&wip), @intCast(enum_type.names.len));
92739271
9274 for (enum_type.names, 0..) |_, field_index_usize| {9272 for (0..enum_type.names.len) |field_index| {
9275 const field_index = @as(u32, @intCast(field_index_usize));
9276 const this_tag_int_value =9273 const this_tag_int_value =
9277 try o.lowerValue((try mod.enumValueFieldIndex(enum_ty, field_index)).toIntern());9274 try o.lowerValue((try mod.enumValueFieldIndex(enum_ty, @intCast(field_index))).toIntern());
9278 switch_instr.addCase(this_tag_int_value.toLlvm(&o.builder), named_block);9275 switch_instr.addCase(this_tag_int_value.toLlvm(&o.builder), named_block.toLlvm(&wip));
9279 }9276 }
9280 self.builder.positionBuilderAtEnd(named_block);9277 self.builder.positionBuilderAtEnd(named_block.toLlvm(&wip));
9281 _ = self.builder.buildRet(Builder.Constant.true.toLlvm(&o.builder));9278 _ = self.builder.buildRet(Builder.Constant.true.toLlvm(&o.builder));
92829279
9283 self.builder.positionBuilderAtEnd(unnamed_block);9280 self.builder.positionBuilderAtEnd(unnamed_block.toLlvm(&wip));
9284 _ = self.builder.buildRet(Builder.Constant.false.toLlvm(&o.builder));9281 _ = self.builder.buildRet(Builder.Constant.false.toLlvm(&o.builder));
92859282
9286 try o.builder.llvm.globals.append(self.gpa, fn_val);9283 try wip.finish();
9287 _ = try o.builder.addGlobal(llvm_fn_name, global);
9288 try o.builder.functions.append(self.gpa, function);
9289 gop.value_ptr.* = global.kind.function;
9290 return fn_val;9284 return fn_val;
9291 }9285 }
92929286
...@@ -9331,8 +9325,10 @@ pub const FuncGen = struct {...@@ -9331,8 +9325,10 @@ pub const FuncGen = struct {
9331 };9325 };
9332 var function = Builder.Function{9326 var function = Builder.Function{
9333 .global = @enumFromInt(o.builder.globals.count()),9327 .global = @enumFromInt(o.builder.globals.count()),
9334 .body = {},
9335 };9328 };
9329 try o.builder.llvm.globals.append(self.gpa, fn_val);
9330 gop.value_ptr.* = try o.builder.addGlobal(llvm_fn_name, global);
9331 try o.builder.functions.append(self.gpa, function);
93369332
9337 const prev_block = self.builder.getInsertBlock();9333 const prev_block = self.builder.getInsertBlock();
9338 const prev_debug_location = self.builder.getCurrentDebugLocation2();9334 const prev_debug_location = self.builder.getCurrentDebugLocation2();
...@@ -9343,16 +9339,18 @@ pub const FuncGen = struct {...@@ -9343,16 +9339,18 @@ pub const FuncGen = struct {
9343 }9339 }
9344 }9340 }
93459341
9346 const entry_block = self.context.appendBasicBlock(fn_val, "Entry");9342 var wip = Builder.WipFunction.init(&o.builder, global.kind.function);
9347 self.builder.positionBuilderAtEnd(entry_block);9343 defer wip.deinit();
9344
9345 const entry_block = try wip.block("Entry");
9346 self.builder.positionBuilderAtEnd(entry_block.toLlvm(&wip));
9348 self.builder.clearCurrentDebugLocation();9347 self.builder.clearCurrentDebugLocation();
93499348
9350 const bad_value_block = self.context.appendBasicBlock(fn_val, "BadValue");9349 const bad_value_block = try wip.block("BadValue");
9351 const tag_int_value = fn_val.getParam(0);9350 const tag_int_value = fn_val.getParam(0);
9352 const switch_instr = self.builder.buildSwitch(tag_int_value, bad_value_block, @as(c_uint, @intCast(enum_type.names.len)));9351 const switch_instr = self.builder.buildSwitch(tag_int_value, bad_value_block.toLlvm(&wip), @intCast(enum_type.names.len));
93539352
9354 for (enum_type.names, 0..) |name_ip, field_index_usize| {9353 for (enum_type.names, 0..) |name_ip, field_index| {
9355 const field_index = @as(u32, @intCast(field_index_usize));
9356 const name = try o.builder.string(mod.intern_pool.stringToSlice(name_ip));9354 const name = try o.builder.string(mod.intern_pool.stringToSlice(name_ip));
9357 const str_init = try o.builder.stringNullConst(name);9355 const str_init = try o.builder.stringNullConst(name);
9358 const str_ty = str_init.typeOf(&o.builder);9356 const str_ty = str_init.typeOf(&o.builder);
...@@ -9384,35 +9382,32 @@ pub const FuncGen = struct {...@@ -9384,35 +9382,32 @@ pub const FuncGen = struct {
9384 try o.builder.intConst(usize_ty, name.toSlice(&o.builder).?.len),9382 try o.builder.intConst(usize_ty, name.toSlice(&o.builder).?.len),
9385 });9383 });
93869384
9387 const return_block = self.context.appendBasicBlock(fn_val, "Name");9385 const return_block = try wip.block("Name");
9388 const this_tag_int_value =9386 const this_tag_int_value =
9389 try o.lowerValue((try mod.enumValueFieldIndex(enum_ty, field_index)).toIntern());9387 try o.lowerValue((try mod.enumValueFieldIndex(enum_ty, @intCast(field_index))).toIntern());
9390 switch_instr.addCase(this_tag_int_value.toLlvm(&o.builder), return_block);9388 switch_instr.addCase(this_tag_int_value.toLlvm(&o.builder), return_block.toLlvm(&wip));
93919389
9392 self.builder.positionBuilderAtEnd(return_block);9390 self.builder.positionBuilderAtEnd(return_block.toLlvm(&wip));
9393 _ = self.builder.buildRet(slice_val.toLlvm(&o.builder));9391 _ = self.builder.buildRet(slice_val.toLlvm(&o.builder));
9394 }9392 }
93959393
9396 self.builder.positionBuilderAtEnd(bad_value_block);9394 self.builder.positionBuilderAtEnd(bad_value_block.toLlvm(&wip));
9397 _ = self.builder.buildUnreachable();9395 _ = self.builder.buildUnreachable();
93989396
9399 try o.builder.llvm.globals.append(self.gpa, fn_val);9397 try wip.finish();
9400 gop.value_ptr.* = try o.builder.addGlobal(llvm_fn_name, global);
9401 try o.builder.functions.append(self.gpa, function);
9402 return fn_val;9398 return fn_val;
9403 }9399 }
94049400
9405 fn getCmpLtErrorsLenFunction(self: *FuncGen) !*llvm.Value {9401 fn getCmpLtErrorsLenFunction(self: *FuncGen) !*llvm.Value {
9406 const o = self.dg.object;9402 const o = self.dg.object;
94079403
9408 if (o.llvm_module.getNamedFunction(lt_errors_fn_name)) |llvm_fn| {9404 const name = try o.builder.string(lt_errors_fn_name);
9409 return llvm_fn;9405 if (o.builder.getGlobal(name)) |llvm_fn| return llvm_fn.toLlvm(&o.builder);
9410 }
94119406
9412 // Function signature: fn (anyerror) bool9407 // Function signature: fn (anyerror) bool
94139408
9414 const fn_type = try o.builder.fnType(.i1, &.{Builder.Type.err_int}, .normal);9409 const fn_type = try o.builder.fnType(.i1, &.{Builder.Type.err_int}, .normal);
9415 const llvm_fn = o.llvm_module.addFunction(lt_errors_fn_name, fn_type.toLlvm(&o.builder));9410 const llvm_fn = o.llvm_module.addFunction(name.toSlice(&o.builder).?, fn_type.toLlvm(&o.builder));
94169411
9417 llvm_fn.setLinkage(.Internal);9412 llvm_fn.setLinkage(.Internal);
9418 llvm_fn.setFunctionCallConv(.Fast);9413 llvm_fn.setFunctionCallConv(.Fast);
...@@ -9425,13 +9420,12 @@ pub const FuncGen = struct {...@@ -9425,13 +9420,12 @@ pub const FuncGen = struct {
9425 };9420 };
9426 var function = Builder.Function{9421 var function = Builder.Function{
9427 .global = @enumFromInt(o.builder.globals.count()),9422 .global = @enumFromInt(o.builder.globals.count()),
9428 .body = {},
9429 };9423 };
94309424
9431 try o.builder.llvm.globals.append(self.gpa, llvm_fn);9425 try o.builder.llvm.globals.append(self.gpa, llvm_fn);
9432 _ = try o.builder.addGlobal(try o.builder.string(lt_errors_fn_name), global);9426 const global_index = try o.builder.addGlobal(name, global);
9433 try o.builder.functions.append(self.gpa, function);9427 try o.builder.functions.append(self.gpa, function);
9434 return llvm_fn;9428 return global_index.toLlvm(&o.builder);
9435 }9429 }
94369430
9437 fn airErrorName(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {9431 fn airErrorName(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
...@@ -9494,7 +9488,7 @@ pub const FuncGen = struct {...@@ -9494,7 +9488,7 @@ pub const FuncGen = struct {
9494 val.* = try o.builder.undefConst(.i32);9488 val.* = try o.builder.undefConst(.i32);
9495 } else {9489 } else {
9496 const int = elem.toSignedInt(mod);9490 const int = elem.toSignedInt(mod);
9497 const unsigned = if (int >= 0) @as(u32, @intCast(int)) else @as(u32, @intCast(~int + a_len));9491 const unsigned: u32 = @intCast(if (int >= 0) int else ~int + a_len);
9498 val.* = try o.builder.intConst(.i32, unsigned);9492 val.* = try o.builder.intConst(.i32, unsigned);
9499 }9493 }
9500 }9494 }
...@@ -9537,21 +9531,21 @@ pub const FuncGen = struct {...@@ -9537,21 +9531,21 @@ pub const FuncGen = struct {
9537 _ = self.builder.buildStore(accum_init, accum_ptr);9531 _ = self.builder.buildStore(accum_init, accum_ptr);
95389532
9539 // Setup the loop9533 // Setup the loop
9540 const loop = self.context.appendBasicBlock(self.llvm_func, "ReduceLoop");9534 const loop = try self.wip.block("ReduceLoop");
9541 const loop_exit = self.context.appendBasicBlock(self.llvm_func, "AfterReduce");9535 const loop_exit = try self.wip.block("AfterReduce");
9542 _ = self.builder.buildBr(loop);9536 _ = self.builder.buildBr(loop.toLlvm(&self.wip));
9543 {9537 {
9544 self.builder.positionBuilderAtEnd(loop);9538 self.builder.positionBuilderAtEnd(loop.toLlvm(&self.wip));
95459539
9546 // while (i < vec.len)9540 // while (i < vec.len)
9547 const i = self.builder.buildLoad(usize_ty.toLlvm(&o.builder), i_ptr, "");9541 const i = self.builder.buildLoad(usize_ty.toLlvm(&o.builder), i_ptr, "");
9548 const cond = self.builder.buildICmp(.ULT, i, llvm_vector_len.toLlvm(&o.builder), "");9542 const cond = self.builder.buildICmp(.ULT, i, llvm_vector_len.toLlvm(&o.builder), "");
9549 const loop_then = self.context.appendBasicBlock(self.llvm_func, "ReduceLoopThen");9543 const loop_then = try self.wip.block("ReduceLoopThen");
95509544
9551 _ = self.builder.buildCondBr(cond, loop_then, loop_exit);9545 _ = self.builder.buildCondBr(cond, loop_then.toLlvm(&self.wip), loop_exit.toLlvm(&self.wip));
95529546
9553 {9547 {
9554 self.builder.positionBuilderAtEnd(loop_then);9548 self.builder.positionBuilderAtEnd(loop_then.toLlvm(&self.wip));
95559549
9556 // accum = f(accum, vec[i]);9550 // accum = f(accum, vec[i]);
9557 const accum = self.builder.buildLoad(llvm_result_ty, accum_ptr, "");9551 const accum = self.builder.buildLoad(llvm_result_ty, accum_ptr, "");
...@@ -9563,11 +9557,11 @@ pub const FuncGen = struct {...@@ -9563,11 +9557,11 @@ pub const FuncGen = struct {
9563 // i += 19557 // i += 1
9564 const new_i = self.builder.buildAdd(i, (try o.builder.intConst(usize_ty, 1)).toLlvm(&o.builder), "");9558 const new_i = self.builder.buildAdd(i, (try o.builder.intConst(usize_ty, 1)).toLlvm(&o.builder), "");
9565 _ = self.builder.buildStore(new_i, i_ptr);9559 _ = self.builder.buildStore(new_i, i_ptr);
9566 _ = self.builder.buildBr(loop);9560 _ = self.builder.buildBr(loop.toLlvm(&self.wip));
9567 }9561 }
9568 }9562 }
95699563
9570 self.builder.positionBuilderAtEnd(loop_exit);9564 self.builder.positionBuilderAtEnd(loop_exit.toLlvm(&self.wip));
9571 return self.builder.buildLoad(llvm_result_ty, accum_ptr, "");9565 return self.builder.buildLoad(llvm_result_ty, accum_ptr, "");
9572 }9566 }
95739567
...@@ -9656,8 +9650,8 @@ pub const FuncGen = struct {...@@ -9656,8 +9650,8 @@ pub const FuncGen = struct {
9656 const mod = o.module;9650 const mod = o.module;
9657 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;9651 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
9658 const result_ty = self.typeOfIndex(inst);9652 const result_ty = self.typeOfIndex(inst);
9659 const len = @as(usize, @intCast(result_ty.arrayLen(mod)));9653 const len: usize = @intCast(result_ty.arrayLen(mod));
9660 const elements = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[ty_pl.payload..][0..len]));9654 const elements: []const Air.Inst.Ref = @ptrCast(self.air.extra[ty_pl.payload..][0..len]);
9661 const llvm_result_ty = (try o.lowerType(result_ty)).toLlvm(&o.builder);9655 const llvm_result_ty = (try o.lowerType(result_ty)).toLlvm(&o.builder);
96629656
9663 switch (result_ty.zigTypeTag(mod)) {9657 switch (result_ty.zigTypeTag(mod)) {
...@@ -9685,8 +9679,8 @@ pub const FuncGen = struct {...@@ -9685,8 +9679,8 @@ pub const FuncGen = struct {
9685 if (!field.ty.hasRuntimeBitsIgnoreComptime(mod)) continue;9679 if (!field.ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
96869680
9687 const non_int_val = try self.resolveInst(elem);9681 const non_int_val = try self.resolveInst(elem);
9688 const ty_bit_size = @as(u16, @intCast(field.ty.bitSize(mod)));9682 const ty_bit_size: u16 = @intCast(field.ty.bitSize(mod));
9689 const small_int_ty = (try o.builder.intType(@intCast(ty_bit_size))).toLlvm(&o.builder);9683 const small_int_ty = (try o.builder.intType(ty_bit_size)).toLlvm(&o.builder);
9690 const small_int_val = if (field.ty.isPtrAtRuntime(mod))9684 const small_int_val = if (field.ty.isPtrAtRuntime(mod))
9691 self.builder.buildPtrToInt(non_int_val, small_int_ty, "")9685 self.builder.buildPtrToInt(non_int_val, small_int_ty, "")
9692 else9686 else
...@@ -9798,8 +9792,7 @@ pub const FuncGen = struct {...@@ -9798,8 +9792,7 @@ pub const FuncGen = struct {
9798 const int_llvm_ty = (try o.builder.intType(@intCast(big_bits))).toLlvm(&o.builder);9792 const int_llvm_ty = (try o.builder.intType(@intCast(big_bits))).toLlvm(&o.builder);
9799 const field = union_obj.fields.values()[extra.field_index];9793 const field = union_obj.fields.values()[extra.field_index];
9800 const non_int_val = try self.resolveInst(extra.init);9794 const non_int_val = try self.resolveInst(extra.init);
9801 const ty_bit_size = @as(u16, @intCast(field.ty.bitSize(mod)));9795 const small_int_ty = (try o.builder.intType(@intCast(field.ty.bitSize(mod)))).toLlvm(&o.builder);
9802 const small_int_ty = (try o.builder.intType(@intCast(ty_bit_size))).toLlvm(&o.builder);
9803 const small_int_val = if (field.ty.isPtrAtRuntime(mod))9796 const small_int_val = if (field.ty.isPtrAtRuntime(mod))
9804 self.builder.buildPtrToInt(non_int_val, small_int_ty, "")9797 self.builder.buildPtrToInt(non_int_val, small_int_ty, "")
9805 else9798 else
...@@ -10273,8 +10266,8 @@ pub const FuncGen = struct {...@@ -10273,8 +10266,8 @@ pub const FuncGen = struct {
10273 const elem_ty = info.child.toType();10266 const elem_ty = info.child.toType();
10274 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) return null;10267 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) return null;
1027510268
10276 const ptr_alignment = @as(u32, @intCast(info.flags.alignment.toByteUnitsOptional() orelse10269 const ptr_alignment: u32 = @intCast(info.flags.alignment.toByteUnitsOptional() orelse
10277 elem_ty.abiAlignment(mod)));10270 elem_ty.abiAlignment(mod));
10278 const ptr_volatile = llvm.Bool.fromBool(info.flags.is_volatile);10271 const ptr_volatile = llvm.Bool.fromBool(info.flags.is_volatile);
1027910272
10280 assert(info.flags.vector_index != .runtime);10273 assert(info.flags.vector_index != .runtime);
...@@ -10306,7 +10299,7 @@ pub const FuncGen = struct {...@@ -10306,7 +10299,7 @@ pub const FuncGen = struct {
10306 containing_int.setAlignment(ptr_alignment);10299 containing_int.setAlignment(ptr_alignment);
10307 containing_int.setVolatile(ptr_volatile);10300 containing_int.setVolatile(ptr_volatile);
1030810301
10309 const elem_bits = @as(c_uint, @intCast(ptr_ty.childType(mod).bitSize(mod)));10302 const elem_bits = ptr_ty.childType(mod).bitSize(mod);
10310 const shift_amt = try o.builder.intConst(containing_int_ty, info.packed_offset.bit_offset);10303 const shift_amt = try o.builder.intConst(containing_int_ty, info.packed_offset.bit_offset);
10311 const shifted_value = self.builder.buildLShr(containing_int, shift_amt.toLlvm(&o.builder), "");10304 const shifted_value = self.builder.buildLShr(containing_int, shift_amt.toLlvm(&o.builder), "");
10312 const elem_llvm_ty = (try o.lowerType(elem_ty)).toLlvm(&o.builder);10305 const elem_llvm_ty = (try o.lowerType(elem_ty)).toLlvm(&o.builder);
...@@ -10379,7 +10372,7 @@ pub const FuncGen = struct {...@@ -10379,7 +10372,7 @@ pub const FuncGen = struct {
10379 assert(ordering == .NotAtomic);10372 assert(ordering == .NotAtomic);
10380 containing_int.setAlignment(ptr_alignment);10373 containing_int.setAlignment(ptr_alignment);
10381 containing_int.setVolatile(ptr_volatile);10374 containing_int.setVolatile(ptr_volatile);
10382 const elem_bits = @as(c_uint, @intCast(ptr_ty.childType(mod).bitSize(mod)));10375 const elem_bits = ptr_ty.childType(mod).bitSize(mod);
10383 const shift_amt = try o.builder.intConst(containing_int_ty, info.packed_offset.bit_offset);10376 const shift_amt = try o.builder.intConst(containing_int_ty, info.packed_offset.bit_offset);
10384 // Convert to equally-sized integer type in order to perform the bit10377 // Convert to equally-sized integer type in order to perform the bit
10385 // operations on the value to store10378 // operations on the value to store
...@@ -10451,11 +10444,11 @@ pub const FuncGen = struct {...@@ -10451,11 +10444,11 @@ pub const FuncGen = struct {
10451 if (!target_util.hasValgrindSupport(target)) return default_value;10444 if (!target_util.hasValgrindSupport(target)) return default_value;
1045210445
10453 const llvm_usize = try o.lowerType(Type.usize);10446 const llvm_usize = try o.lowerType(Type.usize);
10454 const usize_alignment = @as(c_uint, @intCast(Type.usize.abiSize(mod)));10447 const usize_alignment = Type.usize.abiSize(mod);
1045510448
10456 const array_llvm_ty = (try o.builder.arrayType(6, llvm_usize)).toLlvm(&o.builder);10449 const array_llvm_ty = (try o.builder.arrayType(6, llvm_usize)).toLlvm(&o.builder);
10457 const array_ptr = fg.valgrind_client_request_array orelse a: {10450 const array_ptr = fg.valgrind_client_request_array orelse a: {
10458 const array_ptr = try fg.buildAlloca(array_llvm_ty, usize_alignment);10451 const array_ptr = try fg.buildAlloca(array_llvm_ty, @intCast(usize_alignment));
10459 fg.valgrind_client_request_array = array_ptr;10452 fg.valgrind_client_request_array = array_ptr;
10460 break :a array_ptr;10453 break :a array_ptr;
10461 };10454 };
...@@ -10467,7 +10460,7 @@ pub const FuncGen = struct {...@@ -10467,7 +10460,7 @@ pub const FuncGen = struct {
10467 };10460 };
10468 const elem_ptr = fg.builder.buildInBoundsGEP(array_llvm_ty, array_ptr, &indexes, indexes.len, "");10461 const elem_ptr = fg.builder.buildInBoundsGEP(array_llvm_ty, array_ptr, &indexes, indexes.len, "");
10469 const store_inst = fg.builder.buildStore(elem, elem_ptr);10462 const store_inst = fg.builder.buildStore(elem, elem_ptr);
10470 store_inst.setAlignment(usize_alignment);10463 store_inst.setAlignment(@intCast(usize_alignment));
10471 }10464 }
1047210465
10473 const arch_specific: struct {10466 const arch_specific: struct {
...@@ -11642,23 +11635,23 @@ const AnnotatedDITypePtr = enum(usize) {...@@ -11642,23 +11635,23 @@ const AnnotatedDITypePtr = enum(usize) {
11642 fn initFwd(di_type: *llvm.DIType) AnnotatedDITypePtr {11635 fn initFwd(di_type: *llvm.DIType) AnnotatedDITypePtr {
11643 const addr = @intFromPtr(di_type);11636 const addr = @intFromPtr(di_type);
11644 assert(@as(u1, @truncate(addr)) == 0);11637 assert(@as(u1, @truncate(addr)) == 0);
11645 return @as(AnnotatedDITypePtr, @enumFromInt(addr | 1));11638 return @enumFromInt(addr | 1);
11646 }11639 }
1164711640
11648 fn initFull(di_type: *llvm.DIType) AnnotatedDITypePtr {11641 fn initFull(di_type: *llvm.DIType) AnnotatedDITypePtr {
11649 const addr = @intFromPtr(di_type);11642 const addr = @intFromPtr(di_type);
11650 return @as(AnnotatedDITypePtr, @enumFromInt(addr));11643 return @enumFromInt(addr);
11651 }11644 }
1165211645
11653 fn init(di_type: *llvm.DIType, resolve: Object.DebugResolveStatus) AnnotatedDITypePtr {11646 fn init(di_type: *llvm.DIType, resolve: Object.DebugResolveStatus) AnnotatedDITypePtr {
11654 const addr = @intFromPtr(di_type);11647 const addr = @intFromPtr(di_type);
11655 const bit = @intFromBool(resolve == .fwd);11648 const bit = @intFromBool(resolve == .fwd);
11656 return @as(AnnotatedDITypePtr, @enumFromInt(addr | bit));11649 return @enumFromInt(addr | bit);
11657 }11650 }
1165811651
11659 fn toDIType(self: AnnotatedDITypePtr) *llvm.DIType {11652 fn toDIType(self: AnnotatedDITypePtr) *llvm.DIType {
11660 const fixed_addr = @intFromEnum(self) & ~@as(usize, 1);11653 const fixed_addr = @intFromEnum(self) & ~@as(usize, 1);
11661 return @as(*llvm.DIType, @ptrFromInt(fixed_addr));11654 return @ptrFromInt(fixed_addr);
11662 }11655 }
1166311656
11664 fn isFwdOnly(self: AnnotatedDITypePtr) bool {11657 fn isFwdOnly(self: AnnotatedDITypePtr) bool {
src/codegen/llvm/Builder.zig+294-80
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1gpa: Allocator,1gpa: Allocator,
2use_lib_llvm: bool,2use_lib_llvm: bool,
3strip: bool,
34
4llvm: if (build_options.have_llvm) struct {5llvm: if (build_options.have_llvm) struct {
5 context: *llvm.Context,6 context: *llvm.Context,
...@@ -12,33 +13,33 @@ llvm: if (build_options.have_llvm) struct {...@@ -12,33 +13,33 @@ llvm: if (build_options.have_llvm) struct {
12 constants: std.ArrayListUnmanaged(*llvm.Value) = .{},13 constants: std.ArrayListUnmanaged(*llvm.Value) = .{},
13} else void,14} else void,
1415
15source_filename: String = .none,16source_filename: String,
16data_layout: String = .none,17data_layout: String,
17target_triple: String = .none,18target_triple: String,
1819
19string_map: std.AutoArrayHashMapUnmanaged(void, void) = .{},20string_map: std.AutoArrayHashMapUnmanaged(void, void),
20string_bytes: std.ArrayListUnmanaged(u8) = .{},21string_bytes: std.ArrayListUnmanaged(u8),
21string_indices: std.ArrayListUnmanaged(u32) = .{},22string_indices: std.ArrayListUnmanaged(u32),
2223
23types: std.AutoArrayHashMapUnmanaged(String, Type) = .{},24types: std.AutoArrayHashMapUnmanaged(String, Type),
24next_unnamed_type: String = @enumFromInt(0),25next_unnamed_type: String,
25next_unique_type_id: std.AutoHashMapUnmanaged(String, u32) = .{},26next_unique_type_id: std.AutoHashMapUnmanaged(String, u32),
26type_map: std.AutoArrayHashMapUnmanaged(void, void) = .{},27type_map: std.AutoArrayHashMapUnmanaged(void, void),
27type_items: std.ArrayListUnmanaged(Type.Item) = .{},28type_items: std.ArrayListUnmanaged(Type.Item),
28type_extra: std.ArrayListUnmanaged(u32) = .{},29type_extra: std.ArrayListUnmanaged(u32),
2930
30globals: std.AutoArrayHashMapUnmanaged(String, Global) = .{},31globals: std.AutoArrayHashMapUnmanaged(String, Global),
31next_unnamed_global: String = @enumFromInt(0),32next_unnamed_global: String,
32next_replaced_global: String = .none,33next_replaced_global: String,
33next_unique_global_id: std.AutoHashMapUnmanaged(String, u32) = .{},34next_unique_global_id: std.AutoHashMapUnmanaged(String, u32),
34aliases: std.ArrayListUnmanaged(Alias) = .{},35aliases: std.ArrayListUnmanaged(Alias),
35variables: std.ArrayListUnmanaged(Variable) = .{},36variables: std.ArrayListUnmanaged(Variable),
36functions: std.ArrayListUnmanaged(Function) = .{},37functions: std.ArrayListUnmanaged(Function),
3738
38constant_map: std.AutoArrayHashMapUnmanaged(void, void) = .{},39constant_map: std.AutoArrayHashMapUnmanaged(void, void),
39constant_items: std.MultiArrayList(Constant.Item) = .{},40constant_items: std.MultiArrayList(Constant.Item),
40constant_extra: std.ArrayListUnmanaged(u32) = .{},41constant_extra: std.ArrayListUnmanaged(u32),
41constant_limbs: std.ArrayListUnmanaged(std.math.big.Limb) = .{},42constant_limbs: std.ArrayListUnmanaged(std.math.big.Limb),
4243
43pub const expected_fields_len = 32;44pub const expected_fields_len = 32;
44pub const expected_gep_indices_len = 8;45pub const expected_gep_indices_len = 8;
...@@ -46,6 +47,7 @@ pub const expected_gep_indices_len = 8;...@@ -46,6 +47,7 @@ pub const expected_gep_indices_len = 8;
46pub const Options = struct {47pub const Options = struct {
47 allocator: Allocator,48 allocator: Allocator,
48 use_lib_llvm: bool = false,49 use_lib_llvm: bool = false,
50 strip: bool = true,
49 name: []const u8 = &.{},51 name: []const u8 = &.{},
50 target: std.Target = builtin.target,52 target: std.Target = builtin.target,
51 triple: []const u8 = &.{},53 triple: []const u8 = &.{},
...@@ -986,9 +988,11 @@ pub const Variable = struct {...@@ -986,9 +988,11 @@ pub const Variable = struct {
986988
987pub const Function = struct {989pub const Function = struct {
988 global: Global.Index,990 global: Global.Index,
989 body: ?void = null,991 blocks: []const Block = &.{},
990 instructions: std.ArrayListUnmanaged(Instruction) = .{},992 instructions: std.MultiArrayList(Instruction) = .{},
991 blocks: std.ArrayListUnmanaged(Block) = .{},993 names: ?[*]const String = null,
994 metadata: ?[*]const Metadata = null,
995 extra: []const u32 = &.{},
992996
993 pub const Index = enum(u32) {997 pub const Index = enum(u32) {
994 none = std.math.maxInt(u32),998 none = std.math.maxInt(u32),
...@@ -1007,28 +1011,236 @@ pub const Function = struct {...@@ -1007,28 +1011,236 @@ pub const Function = struct {
1007 }1011 }
1008 };1012 };
10091013
1014 pub const Block = struct {
1015 instruction: Instruction.Index,
1016
1017 pub const Index = WipFunction.Block.Index;
1018 };
1019
1010 pub const Instruction = struct {1020 pub const Instruction = struct {
1011 tag: Tag,1021 tag: Tag,
1022 data: u32,
10121023
1013 pub const Tag = enum {1024 pub const Tag = enum {
1014 arg,1025 arg,
1015 block,1026 block,
1027 @"ret void",
1028 ret,
1016 };1029 };
10171030
1018 pub const Index = enum(u32) { _ };1031 pub const Index = enum(u32) {
1032 _,
1033
1034 pub fn name(self: Instruction.Index, function: *const Function) String {
1035 return if (function.names) |names|
1036 names[@intFromEnum(self)]
1037 else
1038 @enumFromInt(@intFromEnum(self));
1039 }
1040 };
1019 };1041 };
10201042
1043 pub fn deinit(self: *Function, gpa: Allocator) void {
1044 gpa.free(self.extra);
1045 if (self.metadata) |metadata| gpa.free(metadata[0..self.instructions.len]);
1046 if (self.names) |names| gpa.free(names[0..self.instructions.len]);
1047 self.instructions.deinit(gpa);
1048 self.* = undefined;
1049 }
1050};
1051
1052pub const WipFunction = struct {
1053 builder: *Builder,
1054 function: Function.Index,
1055 llvm: if (build_options.have_llvm) struct {
1056 builder: *llvm.Builder,
1057 blocks: std.ArrayListUnmanaged(*llvm.BasicBlock),
1058 instructions: std.ArrayListUnmanaged(*llvm.Value),
1059 } else void,
1060 cursor: Cursor,
1061 blocks: std.ArrayListUnmanaged(Block),
1062 instructions: std.MultiArrayList(Instruction),
1063 names: std.ArrayListUnmanaged(String),
1064 metadata: std.ArrayListUnmanaged(Metadata),
1065 extra: std.ArrayListUnmanaged(u32),
1066
1067 pub const Cursor = struct { block: Block.Index, instruction: u32 = 0 };
1068
1021 pub const Block = struct {1069 pub const Block = struct {
1022 body: std.ArrayListUnmanaged(Instruction.Index) = .{},1070 name: String,
1071 incoming: u32,
1072 instructions: std.ArrayListUnmanaged(Instruction.Index),
10231073
1024 pub const Index = enum(u32) { _ };1074 const Index = enum(u32) {
1075 _,
1076
1077 pub fn toLlvm(self: Index, wip: *const WipFunction) *llvm.BasicBlock {
1078 assert(wip.builder.useLibLlvm());
1079 return wip.llvm.blocks.items[@intFromEnum(self)];
1080 }
1081 };
1025 };1082 };
10261083
1027 pub fn deinit(self: *Function, gpa: Allocator) void {1084 pub const Instruction = Function.Instruction;
1028 self.instructions.deinit(gpa);1085
1029 self.blocks.deinit(gpa);1086 pub fn init(builder: *Builder, function: Function.Index) WipFunction {
1087 if (builder.useLibLlvm()) {
1088 const llvm_function = function.toLlvm(builder);
1089 while (llvm_function.getFirstBasicBlock()) |bb| bb.deleteBasicBlock();
1090 }
1091 return .{
1092 .builder = builder,
1093 .function = function,
1094 .llvm = if (builder.useLibLlvm()) .{
1095 .builder = builder.llvm.context.createBuilder(),
1096 .blocks = .{},
1097 .instructions = .{},
1098 } else undefined,
1099 .cursor = undefined,
1100 .blocks = .{},
1101 .instructions = .{},
1102 .names = .{},
1103 .metadata = .{},
1104 .extra = .{},
1105 };
1106 }
1107
1108 pub fn block(self: *WipFunction, name: []const u8) Allocator.Error!Block.Index {
1109 try self.blocks.ensureUnusedCapacity(self.builder.gpa, 1);
1110 if (self.builder.useLibLlvm()) try self.llvm.blocks.ensureUnusedCapacity(self.builder.gpa, 1);
1111
1112 const index: Block.Index = @enumFromInt(self.blocks.items.len);
1113 const final_name = if (self.builder.strip) .empty else try self.builder.string(name);
1114 self.blocks.appendAssumeCapacity(.{ .name = final_name, .incoming = 0, .instructions = .{} });
1115 if (self.builder.useLibLlvm()) self.llvm.blocks.appendAssumeCapacity(
1116 self.builder.llvm.context.appendBasicBlock(
1117 self.function.toLlvm(self.builder),
1118 final_name.toSlice(self.builder).?,
1119 ),
1120 );
1121 return index;
1122 }
1123
1124 pub fn retVoid(self: *WipFunction) Allocator.Error!void {
1125 _ = try self.addInst(.{ .tag = .@"ret void", .data = undefined }, .none);
1126 if (self.builder.useLibLlvm()) self.llvm.instructions.appendAssumeCapacity(
1127 self.llvm.builder.buildRetVoid(),
1128 );
1129 }
1130
1131 pub fn finish(self: *WipFunction) Allocator.Error!void {
1132 const gpa = self.builder.gpa;
1133 const function = self.function.ptr(self.builder);
1134 const final_instructions_len = self.blocks.items.len + self.instructions.len;
1135
1136 const blocks = try gpa.alloc(Function.Block, self.blocks.items.len);
1137 errdefer gpa.free(blocks);
1138
1139 const instructions = try gpa.alloc(Instruction.Index, self.instructions.len);
1140 defer gpa.free(instructions);
1141
1142 const names = if (self.builder.strip) null else try gpa.alloc(String, final_instructions_len);
1143 errdefer if (names) |new_names| gpa.free(new_names);
1144
1145 const metadata =
1146 if (self.builder.strip) null else try gpa.alloc(Metadata, final_instructions_len);
1147 errdefer if (metadata) |new_metadata| gpa.free(new_metadata);
1148
1149 gpa.free(function.blocks);
1150 function.blocks = &.{};
1151 if (function.names) |old_names| gpa.free(old_names[0..function.instructions.len]);
1152 function.names = null;
1153 if (function.metadata) |old_metadata| gpa.free(old_metadata[0..function.instructions.len]);
1154 function.metadata = null;
1155
1156 function.instructions.shrinkRetainingCapacity(0);
1157 try function.instructions.setCapacity(gpa, final_instructions_len);
1158 errdefer function.instructions.shrinkRetainingCapacity(0);
1159
1160 {
1161 var final_instruction: Instruction.Index = @enumFromInt(0);
1162 for (blocks, self.blocks.items) |*final_block, current_block| {
1163 final_block.instruction = final_instruction;
1164 final_instruction = @enumFromInt(@intFromEnum(final_instruction) + 1);
1165 for (current_block.instructions.items) |instruction| {
1166 instructions[@intFromEnum(instruction)] = final_instruction;
1167 final_instruction = @enumFromInt(@intFromEnum(final_instruction) + 1);
1168 }
1169 }
1170 }
1171
1172 var next_name: String = @enumFromInt(0);
1173 for (self.blocks.items) |current_block| {
1174 const block_instruction: Instruction.Index = @enumFromInt(function.instructions.len);
1175 function.instructions.appendAssumeCapacity(.{
1176 .tag = .block,
1177 .data = current_block.incoming,
1178 });
1179 if (names) |new_names|
1180 new_names[@intFromEnum(block_instruction)] = switch (current_block.name) {
1181 .empty => name: {
1182 const name = next_name;
1183 next_name = @enumFromInt(@intFromEnum(name) + 1);
1184 break :name name;
1185 },
1186 else => |name| name,
1187 };
1188 for (current_block.instructions.items) |instruction_index| {
1189 var instruction = self.instructions.get(@intFromEnum(instruction_index));
1190 switch (instruction.tag) {
1191 .block => unreachable,
1192 .@"ret void" => {},
1193 else => unreachable,
1194 }
1195 function.instructions.appendAssumeCapacity(instruction);
1196 }
1197 }
1198
1199 function.extra = try self.extra.toOwnedSlice(gpa);
1200 function.blocks = blocks;
1201 function.names = if (names) |new_names| new_names.ptr else null;
1202 function.metadata = if (metadata) |new_metadata| new_metadata.ptr else null;
1203 }
1204
1205 pub fn deinit(self: *WipFunction) void {
1206 self.extra.deinit(self.builder.gpa);
1207 self.instructions.deinit(self.builder.gpa);
1208 for (self.blocks.items) |*b| b.instructions.deinit(self.builder.gpa);
1209 self.blocks.deinit(self.builder.gpa);
1210 if (self.builder.useLibLlvm()) self.llvm.builder.dispose();
1030 self.* = undefined;1211 self.* = undefined;
1031 }1212 }
1213
1214 fn addInst(
1215 self: *WipFunction,
1216 instruction: Instruction,
1217 name: String,
1218 ) Allocator.Error!Instruction.Index {
1219 const block_instructions = &self.blocks.items[@intFromEnum(self.cursor.block)].instructions;
1220 try self.instructions.ensureUnusedCapacity(self.builder.gpa, 1);
1221 try self.names.ensureUnusedCapacity(self.builder.gpa, 1);
1222 try block_instructions.ensureUnusedCapacity(self.builder.gpa, 1);
1223 if (self.builder.useLibLlvm()) {
1224 try self.llvm.instructions.ensureUnusedCapacity(self.builder.gpa, 1);
1225
1226 if (false) self.llvm.builder.positionBuilder(
1227 self.cursor.block.toLlvm(self),
1228 if (self.cursor.instruction < block_instructions.items.len)
1229 self.llvm.instructions.items[
1230 @intFromEnum(block_instructions.items[self.cursor.instruction])
1231 ]
1232 else
1233 null,
1234 );
1235 }
1236
1237 const index: Instruction.Index = @enumFromInt(self.instructions.len);
1238 self.instructions.appendAssumeCapacity(instruction);
1239 self.names.appendAssumeCapacity(name);
1240 block_instructions.insertAssumeCapacity(self.cursor.instruction, index);
1241 self.cursor.instruction += 1;
1242 return index;
1243 }
1032};1244};
10331245
1034pub const FloatCondition = enum(u4) {1246pub const FloatCondition = enum(u4) {
...@@ -1696,6 +1908,8 @@ pub const Value = enum(u32) {...@@ -1696,6 +1908,8 @@ pub const Value = enum(u32) {
1696 }1908 }
1697};1909};
16981910
1911pub const Metadata = enum(u32) { _ };
1912
1699pub const InitError = error{1913pub const InitError = error{
1700 InvalidLlvmTriple,1914 InvalidLlvmTriple,
1701} || Allocator.Error;1915} || Allocator.Error;
...@@ -1704,7 +1918,37 @@ pub fn init(options: Options) InitError!Builder {...@@ -1704,7 +1918,37 @@ pub fn init(options: Options) InitError!Builder {
1704 var self = Builder{1918 var self = Builder{
1705 .gpa = options.allocator,1919 .gpa = options.allocator,
1706 .use_lib_llvm = options.use_lib_llvm,1920 .use_lib_llvm = options.use_lib_llvm,
1921 .strip = options.strip,
1922
1707 .llvm = undefined,1923 .llvm = undefined,
1924
1925 .source_filename = .none,
1926 .data_layout = .none,
1927 .target_triple = .none,
1928
1929 .string_map = .{},
1930 .string_bytes = .{},
1931 .string_indices = .{},
1932
1933 .types = .{},
1934 .next_unnamed_type = @enumFromInt(0),
1935 .next_unique_type_id = .{},
1936 .type_map = .{},
1937 .type_items = .{},
1938 .type_extra = .{},
1939
1940 .globals = .{},
1941 .next_unnamed_global = @enumFromInt(0),
1942 .next_replaced_global = .none,
1943 .next_unique_global_id = .{},
1944 .aliases = .{},
1945 .variables = .{},
1946 .functions = .{},
1947
1948 .constant_map = .{},
1949 .constant_items = .{},
1950 .constant_extra = .{},
1951 .constant_limbs = .{},
1708 };1952 };
1709 if (self.useLibLlvm()) self.llvm = .{ .context = llvm.Context.create() };1953 if (self.useLibLlvm()) self.llvm = .{ .context = llvm.Context.create() };
1710 errdefer self.deinit();1954 errdefer self.deinit();
...@@ -1726,7 +1970,7 @@ pub fn init(options: Options) InitError!Builder {...@@ -1726,7 +1970,7 @@ pub fn init(options: Options) InitError!Builder {
1726 var error_message: [*:0]const u8 = undefined;1970 var error_message: [*:0]const u8 = undefined;
1727 var target: *llvm.Target = undefined;1971 var target: *llvm.Target = undefined;
1728 if (llvm.Target.getFromTriple(1972 if (llvm.Target.getFromTriple(
1729 self.target_triple.toSlice(&self).?.ptr,1973 self.target_triple.toSlice(&self).?,
1730 &target,1974 &target,
1731 &error_message,1975 &error_message,
1732 ).toBool()) {1976 ).toBool()) {
...@@ -1739,7 +1983,7 @@ pub fn init(options: Options) InitError!Builder {...@@ -1739,7 +1983,7 @@ pub fn init(options: Options) InitError!Builder {
1739 return InitError.InvalidLlvmTriple;1983 return InitError.InvalidLlvmTriple;
1740 }1984 }
1741 self.llvm.target = target;1985 self.llvm.target = target;
1742 self.llvm.module.?.setTarget(self.target_triple.toSlice(&self).?.ptr);1986 self.llvm.module.?.setTarget(self.target_triple.toSlice(&self).?);
1743 }1987 }
1744 }1988 }
17451989
...@@ -2448,7 +2692,7 @@ pub fn dump(self: *Builder, writer: anytype) (@TypeOf(writer).Error || Allocator...@@ -2448,7 +2692,7 @@ pub fn dump(self: *Builder, writer: anytype) (@TypeOf(writer).Error || Allocator
2448 try writer.print(2692 try writer.print(
2449 \\{s}{}{}{}{} {} {}(2693 \\{s}{}{}{}{} {} {}(
2450 , .{2694 , .{
2451 if (function.body) |_| "define" else "declare",2695 if (function.instructions.len > 0) "define" else "declare",
2452 global.linkage,2696 global.linkage,
2453 global.preemption,2697 global.preemption,
2454 global.visibility,2698 global.visibility,
...@@ -2469,48 +2713,18 @@ pub fn dump(self: *Builder, writer: anytype) (@TypeOf(writer).Error || Allocator...@@ -2469,48 +2713,18 @@ pub fn dump(self: *Builder, writer: anytype) (@TypeOf(writer).Error || Allocator
2469 else => unreachable,2713 else => unreachable,
2470 }2714 }
2471 try writer.print("){}{}", .{ global.unnamed_addr, global.alignment });2715 try writer.print("){}{}", .{ global.unnamed_addr, global.alignment });
2472 if (function.body) |_| {2716 if (function.instructions.len > 0) {
2473 try writer.writeAll(" {\n ret ");2717 try writer.writeAll(" {\n");
2474 void: {2718 for (0..function.instructions.len) |index| {
2475 try writer.print("{%}", .{switch (extra.data.ret) {2719 const instruction_index: Function.Instruction.Index = @enumFromInt(index);
2476 .void => |tag| {2720 const instruction = function.instructions.get(index);
2477 try writer.writeAll(@tagName(tag));2721 switch (instruction.tag) {
2478 break :void;2722 .block => try writer.print("{}:\n", .{instruction_index.name(&function).fmt(self)}),
2479 },2723 .@"ret void" => |tag| try writer.print(" {s}\n", .{@tagName(tag)}),
2480 inline .half,2724 else => unreachable,
2481 .bfloat,2725 }
2482 .float,
2483 .double,
2484 .fp128,
2485 .x86_fp80,
2486 => |tag| try @field(Builder, @tagName(tag) ++ "Const")(self, 0.0),
2487 .ppc_fp128 => try self.ppc_fp128Const(.{ 0.0, 0.0 }),
2488 .x86_amx,
2489 .x86_mmx,
2490 .label,
2491 .metadata,
2492 => unreachable,
2493 .token => Constant.none,
2494 else => switch (extra.data.ret.tag(self)) {
2495 .simple,
2496 .function,
2497 .vararg_function,
2498 => unreachable,
2499 .integer => try self.intConst(extra.data.ret, 0),
2500 .pointer => try self.nullConst(extra.data.ret),
2501 .target,
2502 .vector,
2503 .scalable_vector,
2504 .small_array,
2505 .array,
2506 .structure,
2507 .packed_structure,
2508 .named_structure,
2509 => try self.zeroInitConst(extra.data.ret),
2510 },
2511 }.fmt(self)});
2512 }2726 }
2513 try writer.writeAll("\n}");2727 try writer.writeByte('}');
2514 }2728 }
2515 try writer.writeAll("\n\n");2729 try writer.writeAll("\n\n");
2516 }2730 }
src/codegen/llvm/bindings.zig+1-1
...@@ -621,7 +621,7 @@ pub const Builder = opaque {...@@ -621,7 +621,7 @@ pub const Builder = opaque {
621 extern fn LLVMPositionBuilder(621 extern fn LLVMPositionBuilder(
622 Builder: *Builder,622 Builder: *Builder,
623 Block: *BasicBlock,623 Block: *BasicBlock,
624 Instr: *Value,624 Instr: ?*Value,
625 ) void;625 ) void;
626626
627 pub const positionBuilderAtEnd = LLVMPositionBuilderAtEnd;627 pub const positionBuilderAtEnd = LLVMPositionBuilderAtEnd;