authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-11-13 20:19:46+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-11-16 01:12:27+02:00
log11c64bfe6ec921a481b340392ab1d2377359586d
treeffddeca97330d26e4304be6256d31ebea7364713
parent024bac7f531e75e2428a20aac1a88a883eaa7e8e

llvm: implement arbitrary precision debug enumerators

Closes #645

5 files changed, 54 insertions(+), 12 deletions(-)

src/codegen/llvm.zig+24-5
...@@ -1507,6 +1507,11 @@ pub const Object = struct {...@@ -1507,6 +1507,11 @@ pub const Object = struct {
1507 };1507 };
1508 const field_index_val = Value.initPayload(&buf_field_index.base);1508 const field_index_val = Value.initPayload(&buf_field_index.base);
15091509
1510 var buffer: Type.Payload.Bits = undefined;
1511 const int_ty = ty.intTagType(&buffer);
1512 const int_info = ty.intInfo(target);
1513 assert(int_info.bits != 0);
1514
1510 for (field_names) |field_name, i| {1515 for (field_names) |field_name, i| {
1511 const field_name_z = try gpa.dupeZ(u8, field_name);1516 const field_name_z = try gpa.dupeZ(u8, field_name);
1512 defer gpa.free(field_name_z);1517 defer gpa.free(field_name_z);
...@@ -1514,9 +1519,25 @@ pub const Object = struct {...@@ -1514,9 +1519,25 @@ pub const Object = struct {
1514 buf_field_index.data = @intCast(u32, i);1519 buf_field_index.data = @intCast(u32, i);
1515 var buf_u64: Value.Payload.U64 = undefined;1520 var buf_u64: Value.Payload.U64 = undefined;
1516 const field_int_val = field_index_val.enumToInt(ty, &buf_u64);1521 const field_int_val = field_index_val.enumToInt(ty, &buf_u64);
1517 // See https://github.com/ziglang/zig/issues/6451522
1518 const field_int = field_int_val.toSignedInt();1523 var bigint_space: Value.BigIntSpace = undefined;
1519 enumerators[i] = dib.createEnumerator(field_name_z, field_int);1524 const bigint = field_int_val.toBigInt(&bigint_space, target);
1525
1526 if (bigint.limbs.len == 1) {
1527 enumerators[i] = dib.createEnumerator(field_name_z, bigint.limbs[0], int_info.signedness == .unsigned);
1528 continue;
1529 }
1530 if (@sizeOf(usize) == @sizeOf(u64)) {
1531 enumerators[i] = dib.createEnumerator2(
1532 field_name_z,
1533 @intCast(c_uint, bigint.limbs.len),
1534 bigint.limbs.ptr,
1535 int_info.bits,
1536 int_info.signedness == .unsigned,
1537 );
1538 continue;
1539 }
1540 @panic("TODO implement bigint debug enumerators to llvm int for 32-bit compiler builds");
1520 }1541 }
15211542
1522 const di_file = try o.getDIFile(gpa, owner_decl.src_namespace.file_scope);1543 const di_file = try o.getDIFile(gpa, owner_decl.src_namespace.file_scope);
...@@ -1524,8 +1545,6 @@ pub const Object = struct {...@@ -1524,8 +1545,6 @@ pub const Object = struct {
15241545
1525 const name = try ty.nameAlloc(gpa, o.module);1546 const name = try ty.nameAlloc(gpa, o.module);
1526 defer gpa.free(name);1547 defer gpa.free(name);
1527 var buffer: Type.Payload.Bits = undefined;
1528 const int_ty = ty.intTagType(&buffer);
15291548
1530 const enum_di_ty = dib.createEnumerationType(1549 const enum_di_ty = dib.createEnumerationType(
1531 di_scope,1550 di_scope,
src/codegen/llvm/bindings.zig+12-1
...@@ -1662,7 +1662,18 @@ pub const DIBuilder = opaque {...@@ -1662,7 +1662,18 @@ pub const DIBuilder = opaque {
1662 extern fn ZigLLVMCreateDebugEnumerator(1662 extern fn ZigLLVMCreateDebugEnumerator(
1663 dib: *DIBuilder,1663 dib: *DIBuilder,
1664 name: [*:0]const u8,1664 name: [*:0]const u8,
1665 val: i64,1665 val: u64,
1666 is_unsigned: bool,
1667 ) *DIEnumerator;
1668
1669 pub const createEnumerator2 = ZigLLVMCreateDebugEnumeratorOfArbitraryPrecision;
1670 extern fn ZigLLVMCreateDebugEnumeratorOfArbitraryPrecision(
1671 dib: *DIBuilder,
1672 name: [*:0]const u8,
1673 num_words: c_uint,
1674 words: [*]const u64,
1675 bits: c_uint,
1676 is_unsigned: bool,
1666 ) *DIEnumerator;1677 ) *DIEnumerator;
16671678
1668 pub const createEnumerationType = ZigLLVMCreateDebugEnumerationType;1679 pub const createEnumerationType = ZigLLVMCreateDebugEnumerationType;
src/stage1/analyze.cpp+3-3
...@@ -9117,7 +9117,7 @@ static void resolve_llvm_types_enum(CodeGen *g, ZigType *enum_type, ResolveStatu...@@ -9117,7 +9117,7 @@ static void resolve_llvm_types_enum(CodeGen *g, ZigType *enum_type, ResolveStatu
91179117
9118 // https://github.com/ziglang/zig/issues/6459118 // https://github.com/ziglang/zig/issues/645
9119 di_enumerators[i] = ZigLLVMCreateDebugEnumerator(g->dbuilder, buf_ptr(enum_field->name),9119 di_enumerators[i] = ZigLLVMCreateDebugEnumerator(g->dbuilder, buf_ptr(enum_field->name),
9120 bigint_as_signed(&enum_field->value));9120 bigint_as_signed(&enum_field->value), false);
9121 }9121 }
91229122
9123 ZigType *tag_int_type = enum_type->data.enumeration.tag_int_type;9123 ZigType *tag_int_type = enum_type->data.enumeration.tag_int_type;
...@@ -9728,10 +9728,10 @@ static void resolve_llvm_types_anyerror(CodeGen *g) {...@@ -9728,10 +9728,10 @@ static void resolve_llvm_types_anyerror(CodeGen *g) {
9728 entry->llvm_type = get_llvm_type(g, g->err_tag_type);9728 entry->llvm_type = get_llvm_type(g, g->err_tag_type);
9729 ZigList<ZigLLVMDIEnumerator *> err_enumerators = {};9729 ZigList<ZigLLVMDIEnumerator *> err_enumerators = {};
9730 // reserve index 0 to indicate no error9730 // reserve index 0 to indicate no error
9731 err_enumerators.append(ZigLLVMCreateDebugEnumerator(g->dbuilder, "(none)", 0));9731 err_enumerators.append(ZigLLVMCreateDebugEnumerator(g->dbuilder, "(none)", 0, false));
9732 for (size_t i = 1; i < g->errors_by_index.length; i += 1) {9732 for (size_t i = 1; i < g->errors_by_index.length; i += 1) {
9733 ErrorTableEntry *error_entry = g->errors_by_index.at(i);9733 ErrorTableEntry *error_entry = g->errors_by_index.at(i);
9734 err_enumerators.append(ZigLLVMCreateDebugEnumerator(g->dbuilder, buf_ptr(&error_entry->name), i));9734 err_enumerators.append(ZigLLVMCreateDebugEnumerator(g->dbuilder, buf_ptr(&error_entry->name), i, false));
9735 }9735 }
97369736
9737 // create debug type for error sets9737 // create debug type for error sets
src/zig_llvm.cpp+10-2
...@@ -594,8 +594,16 @@ ZigLLVMDIType *ZigLLVMCreateDebugArrayType(ZigLLVMDIBuilder *dibuilder, uint64_t...@@ -594,8 +594,16 @@ ZigLLVMDIType *ZigLLVMCreateDebugArrayType(ZigLLVMDIBuilder *dibuilder, uint64_t
594 return reinterpret_cast<ZigLLVMDIType*>(di_type);594 return reinterpret_cast<ZigLLVMDIType*>(di_type);
595}595}
596596
597ZigLLVMDIEnumerator *ZigLLVMCreateDebugEnumerator(ZigLLVMDIBuilder *dibuilder, const char *name, int64_t val) {597ZigLLVMDIEnumerator *ZigLLVMCreateDebugEnumerator(ZigLLVMDIBuilder *dibuilder, const char *name, uint64_t val, bool isUnsigned) {
598 DIEnumerator *di_enumerator = reinterpret_cast<DIBuilder*>(dibuilder)->createEnumerator(name, val);598 DIEnumerator *di_enumerator = reinterpret_cast<DIBuilder*>(dibuilder)->createEnumerator(name, val, isUnsigned);
599 return reinterpret_cast<ZigLLVMDIEnumerator*>(di_enumerator);
600}
601
602ZigLLVMDIEnumerator *ZigLLVMCreateDebugEnumeratorOfArbitraryPrecision(ZigLLVMDIBuilder *dibuilder,
603 const char *name, unsigned NumWords, const uint64_t Words[], unsigned int bits, bool isUnsigned)
604{
605 DIEnumerator *di_enumerator = reinterpret_cast<DIBuilder*>(dibuilder)->createEnumerator(name,
606 APSInt(APInt(bits, makeArrayRef(Words, NumWords)), isUnsigned));
599 return reinterpret_cast<ZigLLVMDIEnumerator*>(di_enumerator);607 return reinterpret_cast<ZigLLVMDIEnumerator*>(di_enumerator);
600}608}
601609
src/zig_llvm.h+5-1
...@@ -176,7 +176,11 @@ ZIG_EXTERN_C struct ZigLLVMDIType *ZigLLVMCreateDebugArrayType(struct ZigLLVMDIB...@@ -176,7 +176,11 @@ ZIG_EXTERN_C struct ZigLLVMDIType *ZigLLVMCreateDebugArrayType(struct ZigLLVMDIB
176 int elem_count);176 int elem_count);
177177
178ZIG_EXTERN_C struct ZigLLVMDIEnumerator *ZigLLVMCreateDebugEnumerator(struct ZigLLVMDIBuilder *dibuilder,178ZIG_EXTERN_C struct ZigLLVMDIEnumerator *ZigLLVMCreateDebugEnumerator(struct ZigLLVMDIBuilder *dibuilder,
179 const char *name, int64_t val);179 const char *name, uint64_t val, bool isUnsigned);
180
181
182ZIG_EXTERN_C struct ZigLLVMDIEnumerator *ZigLLVMCreateDebugEnumeratorOfArbitraryPrecision(struct ZigLLVMDIBuilder *dibuilder,
183 const char *name, unsigned NumWords, const uint64_t Words[], unsigned int bits, bool isUnsigned);
180184
181ZIG_EXTERN_C struct ZigLLVMDIType *ZigLLVMCreateDebugEnumerationType(struct ZigLLVMDIBuilder *dibuilder,185ZIG_EXTERN_C struct ZigLLVMDIType *ZigLLVMCreateDebugEnumerationType(struct ZigLLVMDIBuilder *dibuilder,
182 struct ZigLLVMDIScope *scope, const char *name, struct ZigLLVMDIFile *file, unsigned line_number,186 struct ZigLLVMDIScope *scope, const char *name, struct ZigLLVMDIFile *file, unsigned line_number,