authorgravatar for timonkruiper@gmail.comTimon Kruiper <timonkruiper@gmail.com> 2021-03-23 14:23:51+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-03-23 11:42:46-07:00
logd73b0473a1df98703d5c742d59e57e225cfa7ba4
tree0610e8c2ed10434c315e4c89b0d2ce102944792e
parent668148549a822c7fa680cf08999dd845bde765aa

stage2: rename fail to todo in LLVM backend

This way we don't have to pass src to every function and we can simply use the first node as the lazy source location for all the todo errors.

1 files changed, 48 insertions(+), 50 deletions(-)

src/codegen/llvm.zig+48-50
......@@ -305,11 +305,11 @@ pub const DeclGen = struct {
305305
306306 gpa: *Allocator,
307307
308 fn fail(self: *DeclGen, src: LazySrcLoc, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } {
308 fn todo(self: *DeclGen, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } {
309309 @setCold(true);
310310 assert(self.err_msg == null);
311 const src_loc = src.toSrcLocWithDecl(self.decl);
312 self.err_msg = try Module.ErrorMsg.create(self.gpa, src_loc, format, args);
311 const src_loc = @as(LazySrcLoc, .{ .node_offset = 0 }).toSrcLocWithDecl(self.decl);
312 self.err_msg = try Module.ErrorMsg.create(self.gpa, src_loc, "TODO (LLVM): " ++ format, args);
313313 return error.CodegenFail;
314314 }
315315
......@@ -325,14 +325,12 @@ pub const DeclGen = struct {
325325 const decl = self.decl;
326326 const typed_value = decl.typed_value.most_recent.typed_value;
327327
328 const src = decl.srcLoc().lazy;
329
330328 log.debug("gen: {s} type: {}, value: {}", .{ decl.name, typed_value.ty, typed_value.val });
331329
332330 if (typed_value.val.castTag(.function)) |func_payload| {
333331 const func = func_payload.data;
334332
335 const llvm_func = try self.resolveLLVMFunction(func.owner_decl, src);
333 const llvm_func = try self.resolveLLVMFunction(func.owner_decl);
336334
337335 // This gets the LLVM values from the function and stores them in `self.args`.
338336 const fn_param_len = func.owner_decl.typed_value.most_recent.typed_value.ty.fnParamLen();
......@@ -369,14 +367,14 @@ pub const DeclGen = struct {
369367
370368 try fg.genBody(func.body);
371369 } else if (typed_value.val.castTag(.extern_fn)) |extern_fn| {
372 _ = try self.resolveLLVMFunction(extern_fn.data, src);
370 _ = try self.resolveLLVMFunction(extern_fn.data);
373371 } else {
374 _ = try self.resolveGlobalDecl(decl, src);
372 _ = try self.resolveGlobalDecl(decl);
375373 }
376374 }
377375
378376 /// If the llvm function does not exist, create it
379 fn resolveLLVMFunction(self: *DeclGen, func: *Module.Decl, src: LazySrcLoc) !*const llvm.Value {
377 fn resolveLLVMFunction(self: *DeclGen, func: *Module.Decl) !*const llvm.Value {
380378 // TODO: do we want to store this in our own datastructure?
381379 if (self.llvmModule().getNamedFunction(func.name)) |llvm_fn| return llvm_fn;
382380
......@@ -393,11 +391,11 @@ pub const DeclGen = struct {
393391 defer self.gpa.free(llvm_param);
394392
395393 for (fn_param_types) |fn_param, i| {
396 llvm_param[i] = try self.getLLVMType(fn_param, src);
394 llvm_param[i] = try self.getLLVMType(fn_param);
397395 }
398396
399397 const fn_type = llvm.Type.functionType(
400 try self.getLLVMType(return_type, src),
398 try self.getLLVMType(return_type),
401399 if (fn_param_len == 0) null else llvm_param.ptr,
402400 @intCast(c_uint, fn_param_len),
403401 .False,
......@@ -411,15 +409,15 @@ pub const DeclGen = struct {
411409 return llvm_fn;
412410 }
413411
414 fn resolveGlobalDecl(self: *DeclGen, decl: *Module.Decl, src: LazySrcLoc) error{ OutOfMemory, CodegenFail }!*const llvm.Value {
412 fn resolveGlobalDecl(self: *DeclGen, decl: *Module.Decl) error{ OutOfMemory, CodegenFail }!*const llvm.Value {
415413 // TODO: do we want to store this in our own datastructure?
416414 if (self.llvmModule().getNamedGlobal(decl.name)) |val| return val;
417415
418416 const typed_value = decl.typed_value.most_recent.typed_value;
419417
420418 // TODO: remove this redundant `getLLVMType`, it is also called in `genTypedValue`.
421 const llvm_type = try self.getLLVMType(typed_value.ty, src);
422 const val = try self.genTypedValue(src, typed_value, null);
419 const llvm_type = try self.getLLVMType(typed_value.ty);
420 const val = try self.genTypedValue(typed_value, null);
423421 const global = self.llvmModule().addGlobal(llvm_type, decl.name);
424422 llvm.setInitializer(global, val);
425423
......@@ -429,7 +427,7 @@ pub const DeclGen = struct {
429427 return global;
430428 }
431429
432 fn getLLVMType(self: *DeclGen, t: Type, src: LazySrcLoc) error{ OutOfMemory, CodegenFail }!*const llvm.Type {
430 fn getLLVMType(self: *DeclGen, t: Type) error{ OutOfMemory, CodegenFail }!*const llvm.Type {
433431 switch (t.zigTypeTag()) {
434432 .Void => return self.context().voidType(),
435433 .NoReturn => return self.context().voidType(),
......@@ -440,14 +438,14 @@ pub const DeclGen = struct {
440438 .Bool => return self.context().intType(1),
441439 .Pointer => {
442440 if (t.isSlice()) {
443 return self.fail(src, "TODO: LLVM backend: implement slices", .{});
441 return self.todo("implement slices", .{});
444442 } else {
445 const elem_type = try self.getLLVMType(t.elemType(), src);
443 const elem_type = try self.getLLVMType(t.elemType());
446444 return elem_type.pointerType(0);
447445 }
448446 },
449447 .Array => {
450 const elem_type = try self.getLLVMType(t.elemType(), src);
448 const elem_type = try self.getLLVMType(t.elemType());
451449 return elem_type.arrayType(@intCast(c_uint, t.abiSize(self.module.getTarget())));
452450 },
453451 .Optional => {
......@@ -456,21 +454,21 @@ pub const DeclGen = struct {
456454 const child_type = t.optionalChild(&buf);
457455
458456 var optional_types: [2]*const llvm.Type = .{
459 try self.getLLVMType(child_type, src),
457 try self.getLLVMType(child_type),
460458 self.context().intType(1),
461459 };
462460 return self.context().structType(&optional_types, 2, .False);
463461 } else {
464 return self.fail(src, "TODO implement optional pointers as actual pointers", .{});
462 return self.todo("implement optional pointers as actual pointers", .{});
465463 }
466464 },
467 else => return self.fail(src, "TODO implement getLLVMType for type '{}'", .{t}),
465 else => return self.todo("implement getLLVMType for type '{}'", .{t}),
468466 }
469467 }
470468
471469 // TODO: figure out a way to remove the FuncGen argument
472 fn genTypedValue(self: *DeclGen, src: LazySrcLoc, tv: TypedValue, fg: ?*FuncGen) error{ OutOfMemory, CodegenFail }!*const llvm.Value {
473 const llvm_type = try self.getLLVMType(tv.ty, src);
470 fn genTypedValue(self: *DeclGen, tv: TypedValue, fg: ?*FuncGen) error{ OutOfMemory, CodegenFail }!*const llvm.Value {
471 const llvm_type = try self.getLLVMType(tv.ty);
474472
475473 if (tv.val.isUndef())
476474 return llvm_type.getUndef();
......@@ -484,7 +482,7 @@ pub const DeclGen = struct {
484482 if (bigint.eqZero()) return llvm_type.constNull();
485483
486484 if (bigint.limbs.len != 1) {
487 return self.fail(src, "TODO implement bigger bigint", .{});
485 return self.todo("implement bigger bigint", .{});
488486 }
489487 const llvm_int = llvm_type.constInt(bigint.limbs[0], .False);
490488 if (!bigint.positive) {
......@@ -495,9 +493,9 @@ pub const DeclGen = struct {
495493 .Pointer => switch (tv.val.tag()) {
496494 .decl_ref => {
497495 const decl = tv.val.castTag(.decl_ref).?.data;
498 const val = try self.resolveGlobalDecl(decl, src);
496 const val = try self.resolveGlobalDecl(decl);
499497
500 const usize_type = try self.getLLVMType(Type.initTag(.usize), src);
498 const usize_type = try self.getLLVMType(Type.initTag(.usize));
501499
502500 // TODO: second index should be the index into the memory!
503501 var indices: [2]*const llvm.Value = .{
......@@ -511,29 +509,29 @@ pub const DeclGen = struct {
511509 .ref_val => {
512510 const elem_value = tv.val.castTag(.ref_val).?.data;
513511 const elem_type = tv.ty.castPointer().?.data;
514 const alloca = fg.?.buildAlloca(try self.getLLVMType(elem_type, src));
515 _ = fg.?.builder.buildStore(try self.genTypedValue(src, .{ .ty = elem_type, .val = elem_value }, fg), alloca);
512 const alloca = fg.?.buildAlloca(try self.getLLVMType(elem_type));
513 _ = fg.?.builder.buildStore(try self.genTypedValue(.{ .ty = elem_type, .val = elem_value }, fg), alloca);
516514 return alloca;
517515 },
518 else => return self.fail(src, "TODO implement const of pointer type '{}'", .{tv.ty}),
516 else => return self.todo("implement const of pointer type '{}'", .{tv.ty}),
519517 },
520518 .Array => {
521519 if (tv.val.castTag(.bytes)) |payload| {
522520 const zero_sentinel = if (tv.ty.sentinel()) |sentinel| blk: {
523521 if (sentinel.tag() == .zero) break :blk true;
524 return self.fail(src, "TODO handle other sentinel values", .{});
522 return self.todo("handle other sentinel values", .{});
525523 } else false;
526524
527525 return self.context().constString(payload.data.ptr, @intCast(c_uint, payload.data.len), llvm.Bool.fromBool(!zero_sentinel));
528526 } else {
529 return self.fail(src, "TODO handle more array values", .{});
527 return self.todo("handle more array values", .{});
530528 }
531529 },
532530 .Optional => {
533531 if (!tv.ty.isPtrLikeOptional()) {
534532 var buf: Type.Payload.ElemType = undefined;
535533 const child_type = tv.ty.optionalChild(&buf);
536 const llvm_child_type = try self.getLLVMType(child_type, src);
534 const llvm_child_type = try self.getLLVMType(child_type);
537535
538536 if (tv.val.tag() == .null_value) {
539537 var optional_values: [2]*const llvm.Value = .{
......@@ -543,16 +541,16 @@ pub const DeclGen = struct {
543541 return self.context().constStruct(&optional_values, 2, .False);
544542 } else {
545543 var optional_values: [2]*const llvm.Value = .{
546 try self.genTypedValue(src, .{ .ty = child_type, .val = tv.val }, fg),
544 try self.genTypedValue(.{ .ty = child_type, .val = tv.val }, fg),
547545 self.context().intType(1).constAllOnes(),
548546 };
549547 return self.context().constStruct(&optional_values, 2, .False);
550548 }
551549 } else {
552 return self.fail(src, "TODO implement const of optional pointer", .{});
550 return self.todo("implement const of optional pointer", .{});
553551 }
554552 },
555 else => return self.fail(src, "TODO implement const of type '{}'", .{tv.ty}),
553 else => return self.todo("implement const of type '{}'", .{tv.ty}),
556554 }
557555 }
558556
......@@ -609,9 +607,9 @@ pub const FuncGen = struct {
609607 self.blocks.deinit(self.gpa());
610608 }
611609
612 fn fail(self: *FuncGen, src: LazySrcLoc, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } {
610 fn todo(self: *FuncGen, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } {
613611 @setCold(true);
614 return self.dg.fail(src, format, args);
612 return self.dg.todo(format, args);
615613 }
616614
617615 fn llvmModule(self: *FuncGen) *const llvm.Module {
......@@ -628,11 +626,11 @@ pub const FuncGen = struct {
628626
629627 fn resolveInst(self: *FuncGen, inst: *ir.Inst) !*const llvm.Value {
630628 if (inst.value()) |val| {
631 return self.dg.genTypedValue(inst.src, .{ .ty = inst.ty, .val = val }, self);
629 return self.dg.genTypedValue(.{ .ty = inst.ty, .val = val }, self);
632630 }
633631 if (self.func_inst_table.get(inst)) |value| return value;
634632
635 return self.fail(inst.src, "TODO implement global llvm values (or the value is not in the func_inst_table table)", .{});
633 return self.todo("implement global llvm values (or the value is not in the func_inst_table table)", .{});
636634 }
637635
638636 fn genBody(self: *FuncGen, body: ir.Body) error{ OutOfMemory, CodegenFail }!void {
......@@ -673,7 +671,7 @@ pub const FuncGen = struct {
673671 // TODO: implement debug info
674672 break :blk null;
675673 },
676 else => |tag| return self.fail(inst.src, "TODO implement LLVM codegen for Zir instruction: {}", .{tag}),
674 else => |tag| return self.todo("implement TZIR instruction: {}", .{tag}),
677675 };
678676 if (opt_value) |val| try self.func_inst_table.putNoClobber(self.gpa(), inst, val);
679677 }
......@@ -689,7 +687,7 @@ pub const FuncGen = struct {
689687 unreachable;
690688
691689 const zig_fn_type = fn_decl.typed_value.most_recent.typed_value.ty;
692 const llvm_fn = try self.dg.resolveLLVMFunction(fn_decl, inst.base.src);
690 const llvm_fn = try self.dg.resolveLLVMFunction(fn_decl);
693691
694692 const num_args = inst.args.len;
695693
......@@ -719,7 +717,7 @@ pub const FuncGen = struct {
719717
720718 return call;
721719 } else {
722 return self.fail(inst.base.src, "TODO implement calling runtime known function pointer LLVM backend", .{});
720 return self.todo("implement calling runtime known function pointer", .{});
723721 }
724722 }
725723
......@@ -739,7 +737,7 @@ pub const FuncGen = struct {
739737
740738 if (!inst.base.ty.isInt())
741739 if (inst.base.ty.tag() != .bool)
742 return self.fail(inst.base.src, "TODO implement 'genCmp' for type {}", .{inst.base.ty});
740 return self.todo("implement 'genCmp' for type {}", .{inst.base.ty});
743741
744742 const is_signed = inst.base.ty.isSignedInt();
745743 const operation = switch (op) {
......@@ -779,7 +777,7 @@ pub const FuncGen = struct {
779777 // If the block does not return a value, we dont have to create a phi node.
780778 if (!inst.base.ty.hasCodeGenBits()) return null;
781779
782 const phi_node = self.builder.buildPhi(try self.dg.getLLVMType(inst.base.ty, inst.base.src), "");
780 const phi_node = self.builder.buildPhi(try self.dg.getLLVMType(inst.base.ty), "");
783781 phi_node.addIncoming(
784782 break_vals.items.ptr,
785783 break_bbs.items.ptr,
......@@ -897,7 +895,7 @@ pub const FuncGen = struct {
897895 const rhs = try self.resolveInst(inst.rhs);
898896
899897 if (!inst.base.ty.isInt())
900 return self.fail(inst.base.src, "TODO implement 'genAdd' for type {}", .{inst.base.ty});
898 return self.todo("implement 'genAdd' for type {}", .{inst.base.ty});
901899
902900 return if (inst.base.ty.isSignedInt())
903901 self.builder.buildNSWAdd(lhs, rhs, "")
......@@ -910,7 +908,7 @@ pub const FuncGen = struct {
910908 const rhs = try self.resolveInst(inst.rhs);
911909
912910 if (!inst.base.ty.isInt())
913 return self.fail(inst.base.src, "TODO implement 'genSub' for type {}", .{inst.base.ty});
911 return self.todo("implement 'genSub' for type {}", .{inst.base.ty});
914912
915913 return if (inst.base.ty.isSignedInt())
916914 self.builder.buildNSWSub(lhs, rhs, "")
......@@ -924,12 +922,12 @@ pub const FuncGen = struct {
924922 const signed = inst.base.ty.isSignedInt();
925923 // TODO: Should we use intcast here or just a simple bitcast?
926924 // LLVM does truncation vs bitcast (+signed extension) in the intcast depending on the sizes
927 return self.builder.buildIntCast2(val, try self.dg.getLLVMType(inst.base.ty, inst.base.src), llvm.Bool.fromBool(signed), "");
925 return self.builder.buildIntCast2(val, try self.dg.getLLVMType(inst.base.ty), llvm.Bool.fromBool(signed), "");
928926 }
929927
930928 fn genBitCast(self: *FuncGen, inst: *Inst.UnOp) !?*const llvm.Value {
931929 const val = try self.resolveInst(inst.operand);
932 const dest_type = try self.dg.getLLVMType(inst.base.ty, inst.base.src);
930 const dest_type = try self.dg.getLLVMType(inst.base.ty);
933931
934932 return self.builder.buildBitCast(val, dest_type, "");
935933 }
......@@ -938,7 +936,7 @@ pub const FuncGen = struct {
938936 const arg_val = self.args[self.arg_index];
939937 self.arg_index += 1;
940938
941 const ptr_val = self.buildAlloca(try self.dg.getLLVMType(inst.base.ty, inst.base.src));
939 const ptr_val = self.buildAlloca(try self.dg.getLLVMType(inst.base.ty));
942940 _ = self.builder.buildStore(arg_val, ptr_val);
943941 return self.builder.buildLoad(ptr_val, "");
944942 }
......@@ -950,7 +948,7 @@ pub const FuncGen = struct {
950948
951949 // TODO: figure out a way to get the name of the var decl.
952950 // TODO: set alignment and volatile
953 return self.buildAlloca(try self.dg.getLLVMType(pointee_type, inst.base.src));
951 return self.buildAlloca(try self.dg.getLLVMType(pointee_type));
954952 }
955953
956954 /// Use this instead of builder.buildAlloca, because this function makes sure to