From ca2b2c498e446895412bf297de0770a0bab839f7 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 13 Dec 2023 16:47:34 +0000 Subject: Add `-obfuscate-source-code-locations` --- src/llvm_backend_const.cpp | 41 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) (limited to 'src/llvm_backend_const.cpp') diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp index 7584df3ee..2291f24ac 100644 --- a/src/llvm_backend_const.cpp +++ b/src/llvm_backend_const.cpp @@ -287,11 +287,44 @@ gb_internal lbValue lb_expr_untyped_const_to_typed(lbModule *m, Ast *expr, Type return lb_const_value(m, t, tv.value); } -gb_internal lbValue lb_const_source_code_location_const(lbModule *m, String const &procedure, TokenPos const &pos) { +gb_internal String lb_obfuscate_string(String const &s, char const *prefix) { + if (s.len == 0) { + return {}; + } + GB_ASSERT(prefix != nullptr); + u64 hash = gb_fnv64a(s.text, s.len); + gbString res = gb_string_make(temporary_allocator(), prefix); + res = gb_string_append_fmt(res, "x%llx", cast(long long unsigned)hash); + return make_string_c(res); +} + +gb_internal i32 lb_obfuscate_i32(i32 i) { + i32 x = cast(i32)gb_fnv64a(&i, sizeof(i)); + if (x < 0) { + x = 1-x; + } + return cast(i32)x; +} + +gb_internal lbValue lb_const_source_code_location_const(lbModule *m, String const &procedure_, TokenPos const &pos) { + String file = get_file_path_string(pos.file_id); + String procedure = procedure_; + + i32 line = pos.line; + i32 column = pos.column; + + if (build_context.obfuscate_source_code_locations) { + file = lb_obfuscate_string(file, "F"); + procedure = lb_obfuscate_string(procedure, "P"); + + line = lb_obfuscate_i32(line); + column = lb_obfuscate_i32(column); + } + LLVMValueRef fields[4] = {}; - fields[0]/*file*/ = lb_find_or_add_entity_string(m, get_file_path_string(pos.file_id)).value; - fields[1]/*line*/ = lb_const_int(m, t_i32, pos.line).value; - fields[2]/*column*/ = lb_const_int(m, t_i32, pos.column).value; + fields[0]/*file*/ = lb_find_or_add_entity_string(m, file).value; + fields[1]/*line*/ = lb_const_int(m, t_i32, line).value; + fields[2]/*column*/ = lb_const_int(m, t_i32, column).value; fields[3]/*procedure*/ = lb_find_or_add_entity_string(m, procedure).value; lbValue res = {}; -- cgit v1.2.3 From a750fc0ba63c9f1461bba4cc0446b1b4c2d2b3a9 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 19 Mar 2024 21:05:23 +0000 Subject: Add `#row_major matrix[R, C]T` As well as `#column_major matrix[R, C]T` as an alias for just `matrix[R, C]T`. This is because some libraries require a row_major internal layout but still want to be used with row or major oriented vectors. --- base/runtime/core.odin | 4 ++++ core/fmt/fmt.odin | 12 ++++++++++-- core/reflect/types.odin | 4 ++++ src/check_expr.cpp | 12 +++++++++--- src/check_type.cpp | 2 +- src/llvm_backend_const.cpp | 4 ++-- src/llvm_backend_expr.cpp | 39 +++++++++++++++++++++++++++++---------- src/llvm_backend_type.cpp | 3 ++- src/llvm_backend_utility.cpp | 22 +++++++++++++++------- src/parser.cpp | 13 +++++++++++++ src/parser.hpp | 1 + src/types.cpp | 19 +++++++++++++++---- 12 files changed, 105 insertions(+), 30 deletions(-) (limited to 'src/llvm_backend_const.cpp') diff --git a/base/runtime/core.odin b/base/runtime/core.odin index 8f27ca674..7ad3ef1d6 100644 --- a/base/runtime/core.odin +++ b/base/runtime/core.odin @@ -177,6 +177,10 @@ Type_Info_Matrix :: struct { row_count: int, column_count: int, // Total element count = column_count * elem_stride + layout: enum u8 { + Column_Major, // array of column vectors + Row_Major, // array of row vectors + }, } Type_Info_Soa_Pointer :: struct { elem: ^Type_Info, diff --git a/core/fmt/fmt.odin b/core/fmt/fmt.odin index 02803f882..6f9801bc8 100644 --- a/core/fmt/fmt.odin +++ b/core/fmt/fmt.odin @@ -2396,7 +2396,11 @@ fmt_matrix :: proc(fi: ^Info, v: any, verb: rune, info: runtime.Type_Info_Matrix for col in 0.. 0 { io.write_string(fi.writer, ", ", &fi.n) } - offset := (row + col*info.elem_stride)*info.elem_size + offset: int + switch info.layout { + case .Column_Major: offset = (row + col*info.elem_stride)*info.elem_size + case .Row_Major: offset = (col + row*info.elem_stride)*info.elem_size + } data := uintptr(v.data) + uintptr(offset) fmt_arg(fi, any{rawptr(data), info.elem.id}, verb) @@ -2410,7 +2414,11 @@ fmt_matrix :: proc(fi: ^Info, v: any, verb: rune, info: runtime.Type_Info_Matrix for col in 0.. 0 { io.write_string(fi.writer, ", ", &fi.n) } - offset := (row + col*info.elem_stride)*info.elem_size + offset: int + switch info.layout { + case .Column_Major: offset = (row + col*info.elem_stride)*info.elem_size + case .Row_Major: offset = (col + row*info.elem_stride)*info.elem_size + } data := uintptr(v.data) + uintptr(offset) fmt_arg(fi, any{rawptr(data), info.elem.id}, verb) diff --git a/core/reflect/types.odin b/core/reflect/types.odin index 2b96dd4fb..9cff46a00 100644 --- a/core/reflect/types.odin +++ b/core/reflect/types.odin @@ -173,6 +173,7 @@ are_types_identical :: proc(a, b: ^Type_Info) -> bool { y := b.variant.(Type_Info_Matrix) or_return if x.row_count != y.row_count { return false } if x.column_count != y.column_count { return false } + if x.layout != y.layout { return false } return are_types_identical(x.elem, y.elem) case Type_Info_Bit_Field: @@ -689,6 +690,9 @@ write_type_writer :: proc(w: io.Writer, ti: ^Type_Info, n_written: ^int = nil) - write_type(w, info.pointer, &n) or_return case Type_Info_Matrix: + if info.layout == .Row_Major { + io.write_string(w, "#row_major ", &n) or_return + } io.write_string(w, "matrix[", &n) or_return io.write_i64(w, i64(info.row_count), 10, &n) or_return io.write_string(w, ", ", &n) or_return diff --git a/src/check_expr.cpp b/src/check_expr.cpp index f359d5a54..67c7f1a04 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -3431,6 +3431,11 @@ gb_internal void check_binary_matrix(CheckerContext *c, Token const &op, Operand if (xt->Matrix.column_count != yt->Matrix.row_count) { goto matrix_error; } + + if (xt->Matrix.is_row_major != yt->Matrix.is_row_major) { + goto matrix_error; + } + x->mode = Addressing_Value; if (are_types_identical(xt, yt)) { if (!is_type_named(x->type) && is_type_named(y->type)) { @@ -3438,7 +3443,8 @@ gb_internal void check_binary_matrix(CheckerContext *c, Token const &op, Operand x->type = y->type; } } else { - x->type = alloc_type_matrix(xt->Matrix.elem, xt->Matrix.row_count, yt->Matrix.column_count); + bool is_row_major = xt->Matrix.is_row_major && yt->Matrix.is_row_major; + x->type = alloc_type_matrix(xt->Matrix.elem, xt->Matrix.row_count, yt->Matrix.column_count, nullptr, nullptr, is_row_major); } goto matrix_success; } else if (yt->kind == Type_Array) { @@ -3452,7 +3458,7 @@ gb_internal void check_binary_matrix(CheckerContext *c, Token const &op, Operand // Treat arrays as column vectors x->mode = Addressing_Value; - if (type_hint == nullptr && xt->Matrix.row_count == yt->Array.count) { + if (xt->Matrix.row_count == yt->Array.count) { x->type = y->type; } else { x->type = alloc_type_matrix(xt->Matrix.elem, xt->Matrix.row_count, 1); @@ -3483,7 +3489,7 @@ gb_internal void check_binary_matrix(CheckerContext *c, Token const &op, Operand // Treat arrays as row vectors x->mode = Addressing_Value; - if (type_hint == nullptr && yt->Matrix.column_count == xt->Array.count) { + if (yt->Matrix.column_count == xt->Array.count) { x->type = x->type; } else { x->type = alloc_type_matrix(yt->Matrix.elem, 1, yt->Matrix.column_count); diff --git a/src/check_type.cpp b/src/check_type.cpp index d5cf187a4..3fe633892 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -2658,7 +2658,7 @@ gb_internal void check_matrix_type(CheckerContext *ctx, Type **type, Ast *node) } type_assign:; - *type = alloc_type_matrix(elem, row_count, column_count, generic_row, generic_column); + *type = alloc_type_matrix(elem, row_count, column_count, generic_row, generic_column, mt->is_row_major); return; } diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp index 2291f24ac..bbb0b8387 100644 --- a/src/llvm_backend_const.cpp +++ b/src/llvm_backend_const.cpp @@ -1302,11 +1302,11 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo GB_ASSERT_MSG(elem_count == max_count, "%td != %td", elem_count, max_count); LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, cast(isize)total_count); - for_array(i, cl->elems) { TypeAndValue tav = cl->elems[i]->tav; GB_ASSERT(tav.mode != Addressing_Invalid); - i64 offset = matrix_row_major_index_to_offset(type, i); + i64 offset = 0; + offset = matrix_row_major_index_to_offset(type, i); values[offset] = lb_const_value(m, elem_type, tav.value, allow_local).value; } for (isize i = 0; i < total_count; i++) { diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index 98618798b..6eb8fdcc6 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -684,12 +684,6 @@ gb_internal lbValue lb_emit_matrix_flatten(lbProcedure *p, lbValue m, Type *type Type *mt = base_type(m.type); GB_ASSERT(mt->kind == Type_Matrix); - // TODO(bill): Determine why this fails on Windows sometimes - if (false && lb_is_matrix_simdable(mt)) { - LLVMValueRef vector = lb_matrix_to_trimmed_vector(p, m); - return lb_matrix_cast_vector_to_type(p, vector, type); - } - lbAddr res = lb_add_local_generated(p, type, true); i64 row_count = mt->Matrix.row_count; @@ -763,6 +757,7 @@ gb_internal lbValue lb_emit_matrix_mul(lbProcedure *p, lbValue lhs, lbValue rhs, GB_ASSERT(is_type_matrix(yt)); GB_ASSERT(xt->Matrix.column_count == yt->Matrix.row_count); GB_ASSERT(are_types_identical(xt->Matrix.elem, yt->Matrix.elem)); + GB_ASSERT(xt->Matrix.is_row_major == yt->Matrix.is_row_major); Type *elem = xt->Matrix.elem; @@ -770,7 +765,7 @@ gb_internal lbValue lb_emit_matrix_mul(lbProcedure *p, lbValue lhs, lbValue rhs, unsigned inner = cast(unsigned)xt->Matrix.column_count; unsigned outer_columns = cast(unsigned)yt->Matrix.column_count; - if (lb_is_matrix_simdable(xt)) { + if (!xt->Matrix.is_row_major && lb_is_matrix_simdable(xt)) { unsigned x_stride = cast(unsigned)matrix_type_stride_in_elems(xt); unsigned y_stride = cast(unsigned)matrix_type_stride_in_elems(yt); @@ -812,7 +807,7 @@ gb_internal lbValue lb_emit_matrix_mul(lbProcedure *p, lbValue lhs, lbValue rhs, return lb_addr_load(p, res); } - { + if (!xt->Matrix.is_row_major) { lbAddr res = lb_add_local_generated(p, type, true); auto inners = slice_make(permanent_allocator(), inner); @@ -835,6 +830,30 @@ gb_internal lbValue lb_emit_matrix_mul(lbProcedure *p, lbValue lhs, lbValue rhs, } } + return lb_addr_load(p, res); + } else { + lbAddr res = lb_add_local_generated(p, type, true); + + auto inners = slice_make(permanent_allocator(), inner); + + for (unsigned i = 0; i < outer_rows; i++) { + for (unsigned j = 0; j < outer_columns; j++) { + lbValue dst = lb_emit_matrix_epi(p, res.addr, i, j); + for (unsigned k = 0; k < inner; k++) { + inners[k][0] = lb_emit_matrix_ev(p, lhs, i, k); + inners[k][1] = lb_emit_matrix_ev(p, rhs, k, j); + } + + lbValue sum = lb_const_nil(p->module, elem); + for (unsigned k = 0; k < inner; k++) { + lbValue a = inners[k][0]; + lbValue b = inners[k][1]; + sum = lb_emit_mul_add(p, a, b, sum, elem); + } + lb_emit_store(p, dst, sum); + } + } + return lb_addr_load(p, res); } } @@ -855,7 +874,7 @@ gb_internal lbValue lb_emit_matrix_mul_vector(lbProcedure *p, lbValue lhs, lbVal Type *elem = mt->Matrix.elem; - if (lb_is_matrix_simdable(mt)) { + if (!mt->Matrix.is_row_major && lb_is_matrix_simdable(mt)) { unsigned stride = cast(unsigned)matrix_type_stride_in_elems(mt); unsigned row_count = cast(unsigned)mt->Matrix.row_count; @@ -924,7 +943,7 @@ gb_internal lbValue lb_emit_vector_mul_matrix(lbProcedure *p, lbValue lhs, lbVal Type *elem = mt->Matrix.elem; - if (lb_is_matrix_simdable(mt)) { + if (!mt->Matrix.is_row_major && lb_is_matrix_simdable(mt)) { unsigned stride = cast(unsigned)matrix_type_stride_in_elems(mt); unsigned row_count = cast(unsigned)mt->Matrix.row_count; diff --git a/src/llvm_backend_type.cpp b/src/llvm_backend_type.cpp index aec1fb201..de83f5058 100644 --- a/src/llvm_backend_type.cpp +++ b/src/llvm_backend_type.cpp @@ -979,12 +979,13 @@ gb_internal void lb_setup_type_info_data_giant_array(lbModule *m, i64 global_typ tag_type = t_type_info_matrix; i64 ez = type_size_of(t->Matrix.elem); - LLVMValueRef vals[5] = { + LLVMValueRef vals[6] = { get_type_info_ptr(m, t->Matrix.elem), lb_const_int(m, t_int, ez).value, lb_const_int(m, t_int, matrix_type_stride_in_elems(t)).value, lb_const_int(m, t_int, t->Matrix.row_count).value, lb_const_int(m, t_int, t->Matrix.column_count).value, + lb_const_int(m, t_u8, cast(u8)t->Matrix.is_row_major).value, }; variant_value = llvm_const_named_struct(m, tag_type, vals, gb_count_of(vals)); diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp index f18aa5521..fb61c41c3 100644 --- a/src/llvm_backend_utility.cpp +++ b/src/llvm_backend_utility.cpp @@ -1464,14 +1464,16 @@ gb_internal lbValue lb_emit_matrix_epi(lbProcedure *p, lbValue s, isize row, isi Type *t = s.type; GB_ASSERT(is_type_pointer(t)); Type *mt = base_type(type_deref(t)); - if (column == 0) { - GB_ASSERT_MSG(is_type_matrix(mt) || is_type_array_like(mt), "%s", type_to_string(mt)); - return lb_emit_epi(p, s, row); - } else if (row == 0 && is_type_array_like(mt)) { - return lb_emit_epi(p, s, column); + + if (!mt->Matrix.is_row_major) { + if (column == 0) { + GB_ASSERT_MSG(is_type_matrix(mt) || is_type_array_like(mt), "%s", type_to_string(mt)); + return lb_emit_epi(p, s, row); + } else if (row == 0 && is_type_array_like(mt)) { + return lb_emit_epi(p, s, column); + } } - GB_ASSERT_MSG(is_type_matrix(mt), "%s", type_to_string(mt)); isize offset = matrix_indices_to_offset(mt, row, column); @@ -1491,7 +1493,13 @@ gb_internal lbValue lb_emit_matrix_ep(lbProcedure *p, lbValue s, lbValue row, lb row = lb_emit_conv(p, row, t_int); column = lb_emit_conv(p, column, t_int); - LLVMValueRef index = LLVMBuildAdd(p->builder, row.value, LLVMBuildMul(p->builder, column.value, stride_elems, ""), ""); + LLVMValueRef index = nullptr; + + if (mt->Matrix.is_row_major) { + index = LLVMBuildAdd(p->builder, column.value, LLVMBuildMul(p->builder, row.value, stride_elems, ""), ""); + } else { + index = LLVMBuildAdd(p->builder, row.value, LLVMBuildMul(p->builder, column.value, stride_elems, ""), ""); + } LLVMValueRef indices[2] = { LLVMConstInt(lb_type(p->module, t_int), 0, false), diff --git a/src/parser.cpp b/src/parser.cpp index 1aa40ccbf..eb9e73342 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -2329,6 +2329,19 @@ gb_internal Ast *parse_operand(AstFile *f, bool lhs) { break; } return original_type; + } else if (name.string == "row_major" || + name.string == "column_major") { + Ast *original_type = parse_type(f); + Ast *type = unparen_expr(original_type); + switch (type->kind) { + case Ast_MatrixType: + type->MatrixType.is_row_major = (name.string == "row_major"); + break; + default: + syntax_error(type, "Expected a matrix type after #%.*s, got %.*s", LIT(name.string), LIT(ast_strings[type->kind])); + break; + } + return original_type; } else if (name.string == "partial") { Ast *tag = ast_basic_directive(f, token, name); Ast *original_expr = parse_expr(f, lhs); diff --git a/src/parser.hpp b/src/parser.hpp index f5997c4bd..ff3c5eb34 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -772,6 +772,7 @@ AST_KIND(_TypeBegin, "", bool) \ Ast *row_count; \ Ast *column_count; \ Ast *elem; \ + bool is_row_major; \ }) \ AST_KIND(_TypeEnd, "", bool) diff --git a/src/types.cpp b/src/types.cpp index 5a3ad5d6b..ab5e4de03 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -281,6 +281,7 @@ struct TypeProc { Type *generic_row_count; \ Type *generic_column_count; \ i64 stride_in_bytes; \ + bool is_row_major; \ }) \ TYPE_KIND(BitField, struct { \ Scope * scope; \ @@ -1002,7 +1003,7 @@ gb_internal Type *alloc_type_array(Type *elem, i64 count, Type *generic_count = return t; } -gb_internal Type *alloc_type_matrix(Type *elem, i64 row_count, i64 column_count, Type *generic_row_count = nullptr, Type *generic_column_count = nullptr) { +gb_internal Type *alloc_type_matrix(Type *elem, i64 row_count, i64 column_count, Type *generic_row_count = nullptr, Type *generic_column_count = nullptr, bool is_row_major = false) { if (generic_row_count != nullptr || generic_column_count != nullptr) { Type *t = alloc_type(Type_Matrix); t->Matrix.elem = elem; @@ -1010,12 +1011,14 @@ gb_internal Type *alloc_type_matrix(Type *elem, i64 row_count, i64 column_count, t->Matrix.column_count = column_count; t->Matrix.generic_row_count = generic_row_count; t->Matrix.generic_column_count = generic_column_count; + t->Matrix.is_row_major = is_row_major; return t; } Type *t = alloc_type(Type_Matrix); t->Matrix.elem = elem; t->Matrix.row_count = row_count; t->Matrix.column_count = column_count; + t->Matrix.is_row_major = is_row_major; return t; } @@ -1512,14 +1515,18 @@ gb_internal i64 matrix_indices_to_offset(Type *t, i64 row_index, i64 column_inde GB_ASSERT(0 <= row_index && row_index < t->Matrix.row_count); GB_ASSERT(0 <= column_index && column_index < t->Matrix.column_count); i64 stride_elems = matrix_type_stride_in_elems(t); - // NOTE(bill): Column-major layout internally - return row_index + stride_elems*column_index; + if (t->Matrix.is_row_major) { + return column_index + stride_elems*row_index; + } else { + // NOTE(bill): Column-major layout internally + return row_index + stride_elems*column_index; + } } gb_internal i64 matrix_row_major_index_to_offset(Type *t, i64 index) { t = base_type(t); GB_ASSERT(t->kind == Type_Matrix); - + i64 row_index = index/t->Matrix.column_count; i64 column_index = index%t->Matrix.column_count; return matrix_indices_to_offset(t, row_index, column_index); @@ -2690,6 +2697,7 @@ gb_internal bool are_types_identical_internal(Type *x, Type *y, bool check_tuple case Type_Matrix: return x->Matrix.row_count == y->Matrix.row_count && x->Matrix.column_count == y->Matrix.column_count && + x->Matrix.is_row_major == y->Matrix.is_row_major && are_types_identical(x->Matrix.elem, y->Matrix.elem); case Type_DynamicArray: @@ -4735,6 +4743,9 @@ gb_internal gbString write_type_to_string(gbString str, Type *type, bool shortha break; case Type_Matrix: + if (type->Matrix.is_row_major) { + str = gb_string_appendc(str, "#row_major "); + } str = gb_string_appendc(str, gb_bprintf("matrix[%d, %d]", cast(int)type->Matrix.row_count, cast(int)type->Matrix.column_count)); str = write_type_to_string(str, type->Matrix.elem); break; -- cgit v1.2.3 From e1b545860f06f31f073c7142e3df8a2c1177776b Mon Sep 17 00:00:00 2001 From: rick-masters Date: Fri, 29 Mar 2024 11:05:27 +0000 Subject: Implement endian conversions for smaller float types. --- src/llvm_backend_const.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'src/llvm_backend_const.cpp') diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp index bbb0b8387..1ca5f4965 100644 --- a/src/llvm_backend_const.cpp +++ b/src/llvm_backend_const.cpp @@ -730,9 +730,21 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo return res; case ExactValue_Float: if (is_type_different_to_arch_endianness(type)) { - u64 u = bit_cast(value.value_float); - u = gb_endian_swap64(u); - res.value = LLVMConstReal(lb_type(m, original_type), bit_cast(u)); + if (type->Basic.kind == Basic_f32le || type->Basic.kind == Basic_f32be) { + f32 f = static_cast(value.value_float); + u32 u = bit_cast(f); + u = gb_endian_swap32(u); + res.value = LLVMConstReal(lb_type(m, original_type), bit_cast(u)); + } else if (type->Basic.kind == Basic_f16le || type->Basic.kind == Basic_f16be) { + f32 f = static_cast(value.value_float); + u16 u = f32_to_f16(f); + u = gb_endian_swap16(u); + res.value = LLVMConstReal(lb_type(m, original_type), f16_to_f32(u)); + } else { + u64 u = bit_cast(value.value_float); + u = gb_endian_swap64(u); + res.value = LLVMConstReal(lb_type(m, original_type), bit_cast(u)); + } } else { res.value = LLVMConstReal(lb_type(m, original_type), value.value_float); } -- cgit v1.2.3 From 810cf22e5ddd772ee214eec306b1ba148623302c Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 8 Apr 2024 16:08:35 +0100 Subject: Obfuscate `#file` and `#procedure` when `-obfuscate-source-code-locations` is enabled --- src/check_expr.cpp | 12 ++++++++++-- src/common.cpp | 13 +++++++++++++ src/llvm_backend_const.cpp | 15 ++------------- 3 files changed, 25 insertions(+), 15 deletions(-) (limited to 'src/llvm_backend_const.cpp') diff --git a/src/check_expr.cpp b/src/check_expr.cpp index fe8c9599f..7d8e0f829 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -8157,8 +8157,12 @@ gb_internal ExprKind check_basic_directive_expr(CheckerContext *c, Operand *o, A o->mode = Addressing_Constant; String name = bd->name.string; if (name == "file") { + String file = get_file_path_string(bd->token.pos.file_id); + if (build_context.obfuscate_source_code_locations) { + file = obfuscate_string(file, "F"); + } o->type = t_untyped_string; - o->value = exact_value_string(get_file_path_string(bd->token.pos.file_id)); + o->value = exact_value_string(file); } else if (name == "line") { o->type = t_untyped_integer; o->value = exact_value_i64(bd->token.pos.line); @@ -8168,8 +8172,12 @@ gb_internal ExprKind check_basic_directive_expr(CheckerContext *c, Operand *o, A o->type = t_untyped_string; o->value = exact_value_string(str_lit("")); } else { + String p = c->proc_name; + if (build_context.obfuscate_source_code_locations) { + p = obfuscate_string(p, "P"); + } o->type = t_untyped_string; - o->value = exact_value_string(c->proc_name); + o->value = exact_value_string(p); } } else if (name == "caller_location") { init_core_source_code_location(c->checker); diff --git a/src/common.cpp b/src/common.cpp index aad420325..6a53332d9 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -353,6 +353,19 @@ gb_global bool global_module_path_set = false; #include "thread_pool.cpp" +gb_internal String obfuscate_string(String const &s, char const *prefix) { + if (s.len == 0) { + return {}; + } + GB_ASSERT(prefix != nullptr); + u64 hash = gb_fnv64a(s.text, s.len); + gbString res = gb_string_make(temporary_allocator(), prefix); + res = gb_string_append_fmt(res, "x%llx", cast(long long unsigned)hash); + return make_string_c(res); +} + + + struct StringIntern { StringIntern *next; isize len; diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp index 1ca5f4965..5b2af1049 100644 --- a/src/llvm_backend_const.cpp +++ b/src/llvm_backend_const.cpp @@ -287,17 +287,6 @@ gb_internal lbValue lb_expr_untyped_const_to_typed(lbModule *m, Ast *expr, Type return lb_const_value(m, t, tv.value); } -gb_internal String lb_obfuscate_string(String const &s, char const *prefix) { - if (s.len == 0) { - return {}; - } - GB_ASSERT(prefix != nullptr); - u64 hash = gb_fnv64a(s.text, s.len); - gbString res = gb_string_make(temporary_allocator(), prefix); - res = gb_string_append_fmt(res, "x%llx", cast(long long unsigned)hash); - return make_string_c(res); -} - gb_internal i32 lb_obfuscate_i32(i32 i) { i32 x = cast(i32)gb_fnv64a(&i, sizeof(i)); if (x < 0) { @@ -314,8 +303,8 @@ gb_internal lbValue lb_const_source_code_location_const(lbModule *m, String cons i32 column = pos.column; if (build_context.obfuscate_source_code_locations) { - file = lb_obfuscate_string(file, "F"); - procedure = lb_obfuscate_string(procedure, "P"); + file = obfuscate_string(file, "F"); + procedure = obfuscate_string(procedure, "P"); line = lb_obfuscate_i32(line); column = lb_obfuscate_i32(column); -- cgit v1.2.3 From ec455046316ba1bf44a6f2118512341a3f68b10c Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 8 Apr 2024 16:14:47 +0100 Subject: Obfuscate `#line` --- src/check_expr.cpp | 6 +++++- src/common.cpp | 8 ++++++++ src/llvm_backend_const.cpp | 11 ++--------- 3 files changed, 15 insertions(+), 10 deletions(-) (limited to 'src/llvm_backend_const.cpp') diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 7d8e0f829..b893b3a00 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -8164,8 +8164,12 @@ gb_internal ExprKind check_basic_directive_expr(CheckerContext *c, Operand *o, A o->type = t_untyped_string; o->value = exact_value_string(file); } else if (name == "line") { + i32 line = bd->token.pos.line; + if (build_context.obfuscate_source_code_locations) { + line = obfuscate_i32(line); + } o->type = t_untyped_integer; - o->value = exact_value_i64(bd->token.pos.line); + o->value = exact_value_i64(line); } else if (name == "procedure") { if (c->curr_proc_decl == nullptr) { error(node, "#procedure may only be used within procedures"); diff --git a/src/common.cpp b/src/common.cpp index 6a53332d9..e0a579c5d 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -364,6 +364,14 @@ gb_internal String obfuscate_string(String const &s, char const *prefix) { return make_string_c(res); } +gb_internal i32 obfuscate_i32(i32 i) { + i32 x = cast(i32)gb_fnv64a(&i, sizeof(i)); + if (x < 0) { + x = 1-x; + } + return cast(i32)x; +} + struct StringIntern { diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp index 5b2af1049..8035336d3 100644 --- a/src/llvm_backend_const.cpp +++ b/src/llvm_backend_const.cpp @@ -287,13 +287,6 @@ gb_internal lbValue lb_expr_untyped_const_to_typed(lbModule *m, Ast *expr, Type return lb_const_value(m, t, tv.value); } -gb_internal i32 lb_obfuscate_i32(i32 i) { - i32 x = cast(i32)gb_fnv64a(&i, sizeof(i)); - if (x < 0) { - x = 1-x; - } - return cast(i32)x; -} gb_internal lbValue lb_const_source_code_location_const(lbModule *m, String const &procedure_, TokenPos const &pos) { String file = get_file_path_string(pos.file_id); @@ -306,8 +299,8 @@ gb_internal lbValue lb_const_source_code_location_const(lbModule *m, String cons file = obfuscate_string(file, "F"); procedure = obfuscate_string(procedure, "P"); - line = lb_obfuscate_i32(line); - column = lb_obfuscate_i32(column); + line = obfuscate_i32(line); + column = obfuscate_i32(column); } LLVMValueRef fields[4] = {}; -- cgit v1.2.3 From 330d6117e356fe961fa7688c918e58c7a6917e9e Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 16 May 2024 15:43:08 +0100 Subject: Fix #3589 --- src/llvm_backend_const.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/llvm_backend_const.cpp') diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp index 8035336d3..3ed8d72d9 100644 --- a/src/llvm_backend_const.cpp +++ b/src/llvm_backend_const.cpp @@ -539,7 +539,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo LLVMValueRef ptr = LLVMBuildInBoundsGEP2(p->builder, llvm_type, array_data, indices, 2, ""); LLVMValueRef len = LLVMConstInt(lb_type(m, t_int), count, true); - lbAddr slice = lb_add_local_generated(p, type, false); + lbAddr slice = lb_add_local_generated(p, original_type, false); map_set(&m->exact_value_compound_literal_addr_map, value.value_compound, slice); lb_fill_slice(p, slice, {ptr, alloc_type_pointer(elem)}, {len, t_int}); -- cgit v1.2.3 From 723314909679b89e159cb4cb05d250d12ac64436 Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Tue, 2 Jul 2024 01:25:52 +0200 Subject: fix llvm assertion failure when const initializer is not the same type --- src/llvm_backend_const.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/llvm_backend_const.cpp') diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp index 3ed8d72d9..81fe624ff 100644 --- a/src/llvm_backend_const.cpp +++ b/src/llvm_backend_const.cpp @@ -94,9 +94,6 @@ gb_internal LLVMValueRef llvm_const_cast(LLVMValueRef val, LLVMTypeRef dst) { LLVMTypeKind kind = LLVMGetTypeKind(dst); switch (kind) { case LLVMPointerTypeKind: - if (LB_USE_NEW_PASS_SYSTEM) { - return val; - } return LLVMConstPointerCast(val, dst); case LLVMStructTypeKind: // GB_PANIC("%s -> %s", LLVMPrintValueToString(val), LLVMPrintTypeToString(dst)); @@ -179,6 +176,7 @@ gb_internal LLVMValueRef llvm_const_named_struct_internal(LLVMTypeRef t, LLVMVal for (unsigned i = 0; i < elem_count; i++) { LLVMTypeRef elem_type = LLVMStructGetTypeAtIndex(t, i); values[i] = llvm_const_cast(values[i], elem_type); + GB_ASSERT_MSG(elem_type == LLVMTypeOf(values[i]), "%s != %s", LLVMPrintTypeToString(LLVMTypeOf(values[i])), LLVMPrintTypeToString(elem_type)); } return LLVMConstNamedStruct(t, values, value_count); } -- cgit v1.2.3 From 1bd9fe04c4baf9fba32a38b94d564f0253b320d1 Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Thu, 4 Jul 2024 23:55:21 +0200 Subject: Fix assertion false positive Assertion was added in #3855 - https://github.com/odin-lang/Odin/pull/3855/commits/723314909679b89e159cb4cb05d250d12ac64436 to mimic LLVM's own internal assertion for this, turns out their assertion is more sophisticated than an `==` so lets just remove it. To be clear their internal assertion is not hit while this one is, which defeats the purpose of ours. --- src/llvm_backend_const.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/llvm_backend_const.cpp') diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp index 81fe624ff..9cc0552de 100644 --- a/src/llvm_backend_const.cpp +++ b/src/llvm_backend_const.cpp @@ -176,7 +176,6 @@ gb_internal LLVMValueRef llvm_const_named_struct_internal(LLVMTypeRef t, LLVMVal for (unsigned i = 0; i < elem_count; i++) { LLVMTypeRef elem_type = LLVMStructGetTypeAtIndex(t, i); values[i] = llvm_const_cast(values[i], elem_type); - GB_ASSERT_MSG(elem_type == LLVMTypeOf(values[i]), "%s != %s", LLVMPrintTypeToString(LLVMTypeOf(values[i])), LLVMPrintTypeToString(elem_type)); } return LLVMConstNamedStruct(t, values, value_count); } -- cgit v1.2.3 From 399c3ab067d0bbacbf9732107b932d5bb910b67f Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 14 Jul 2024 21:37:35 +0100 Subject: Reduce the size of `runtime.Type_Info` --- base/runtime/core.odin | 50 +++++++++++++++++++++-------------- base/runtime/print.odin | 11 ++++---- core/encoding/cbor/marshal.odin | 6 ++--- core/encoding/cbor/unmarshal.odin | 2 +- core/encoding/json/marshal.odin | 2 +- core/encoding/json/unmarshal.odin | 2 +- core/fmt/fmt.odin | 16 ++++++------ core/reflect/reflect.odin | 26 +++++++++--------- core/reflect/types.odin | 27 +++++++++---------- src/llvm_backend_const.cpp | 9 +++++++ src/llvm_backend_type.cpp | 55 ++++++++++++++++++++------------------- 11 files changed, 113 insertions(+), 93 deletions(-) (limited to 'src/llvm_backend_const.cpp') diff --git a/base/runtime/core.odin b/base/runtime/core.odin index a758a2fdd..f9bf57259 100644 --- a/base/runtime/core.odin +++ b/base/runtime/core.odin @@ -66,7 +66,7 @@ Type_Info_Named :: struct { name: string, base: ^Type_Info, pkg: string, - loc: Source_Code_Location, + loc: ^Source_Code_Location, } Type_Info_Integer :: struct {signed: bool, endianness: Platform_Endianness} Type_Info_Rune :: struct {} @@ -112,23 +112,32 @@ Type_Info_Parameters :: struct { // Only used for procedures parameters and resu } Type_Info_Tuple :: Type_Info_Parameters // Will be removed eventually +Type_Info_Struct_Flags :: distinct bit_set[Type_Info_Struct_Flag; u8] +Type_Info_Struct_Flag :: enum u8 { + packed = 0, + raw_union = 1, + no_copy = 2, + align = 3, +} + Type_Info_Struct :: struct { - types: []^Type_Info, - names: []string, - offsets: []uintptr, - usings: []bool, - tags: []string, - is_packed: bool, - is_raw_union: bool, - is_no_copy: bool, - custom_align: bool, + // Slice these with `field_count` + types: [^]^Type_Info, + names: [^]string, + offsets: [^]uintptr, + usings: [^]bool, + tags: [^]string, - equal: Equal_Proc, // set only when the struct has .Comparable set but does not have .Simple_Compare set + field_count: i32, + + flags: Type_Info_Struct_Flags, // These are only set iff this structure is an SOA structure soa_kind: Type_Info_Struct_Soa_Kind, + soa_len: i32, soa_base_type: ^Type_Info, - soa_len: int, + + equal: Equal_Proc, // set only when the struct has .Comparable set but does not have .Simple_Compare set } Type_Info_Union :: struct { variants: []^Type_Info, @@ -142,9 +151,9 @@ Type_Info_Union :: struct { shared_nil: bool, } Type_Info_Enum :: struct { - base: ^Type_Info, - names: []string, - values: []Type_Info_Enum_Value, + base: ^Type_Info, + names: []string, + values: []Type_Info_Enum_Value, } Type_Info_Map :: struct { key: ^Type_Info, @@ -187,11 +196,12 @@ Type_Info_Soa_Pointer :: struct { } Type_Info_Bit_Field :: struct { backing_type: ^Type_Info, - names: []string, - types: []^Type_Info, - bit_sizes: []uintptr, - bit_offsets: []uintptr, - tags: []string, + names: [^]string, + types: [^]^Type_Info, + bit_sizes: [^]uintptr, + bit_offsets: [^]uintptr, + tags: [^]string, + field_count: int, } Type_Info_Flag :: enum u8 { diff --git a/base/runtime/print.odin b/base/runtime/print.odin index 0262e8ef6..45f6f01ef 100644 --- a/base/runtime/print.odin +++ b/base/runtime/print.odin @@ -401,15 +401,16 @@ print_type :: #force_no_inline proc "contextless" (ti: ^Type_Info) { } print_string("struct ") - if info.is_packed { print_string("#packed ") } - if info.is_raw_union { print_string("#raw_union ") } - if info.custom_align { + if .packed in info.flags { print_string("#packed ") } + if .raw_union in info.flags { print_string("#raw_union ") } + if .no_copy in info.flags { print_string("#no_copy ") } + if .align in info.flags { print_string("#align(") print_u64(u64(ti.align)) print_string(") ") } print_byte('{') - for name, i in info.names { + for name, i in info.names[:info.field_count] { if i > 0 { print_string(", ") } print_string(name) print_string(": ") @@ -469,7 +470,7 @@ print_type :: #force_no_inline proc "contextless" (ti: ^Type_Info) { print_string("bit_field ") print_type(info.backing_type) print_string(" {") - for name, i in info.names { + for name, i in info.names[:info.field_count] { if i > 0 { print_string(", ") } print_string(name) print_string(": ") diff --git a/core/encoding/cbor/marshal.odin b/core/encoding/cbor/marshal.odin index 2cdf384c3..022e297e9 100644 --- a/core/encoding/cbor/marshal.odin +++ b/core/encoding/cbor/marshal.odin @@ -506,7 +506,7 @@ _marshal_into_encoder :: proc(e: Encoder, v: any, ti: ^runtime.Type_Info) -> (er } n: u64; { - for _, i in info.names { + for _, i in info.names[:info.field_count] { if field_name(info, i) != "-" { n += 1 } @@ -522,7 +522,7 @@ _marshal_into_encoder :: proc(e: Encoder, v: any, ti: ^runtime.Type_Info) -> (er entries := make([dynamic]Name, 0, n, e.temp_allocator) or_return defer delete(entries) - for _, i in info.names { + for _, i in info.names[:info.field_count] { fname := field_name(info, i) if fname == "-" { continue @@ -540,7 +540,7 @@ _marshal_into_encoder :: proc(e: Encoder, v: any, ti: ^runtime.Type_Info) -> (er marshal_entry(e, info, v, entry.name, entry.field) or_return } } else { - for _, i in info.names { + for _, i in info.names[:info.field_count] { fname := field_name(info, i) if fname == "-" { continue diff --git a/core/encoding/cbor/unmarshal.odin b/core/encoding/cbor/unmarshal.odin index 13350bb85..4da2d5a93 100644 --- a/core/encoding/cbor/unmarshal.odin +++ b/core/encoding/cbor/unmarshal.odin @@ -618,7 +618,7 @@ _unmarshal_map :: proc(d: Decoder, v: any, ti: ^reflect.Type_Info, hdr: Header, #partial switch t in ti.variant { case reflect.Type_Info_Struct: - if t.is_raw_union { + if .raw_union in t.flags { return _unsupported(v, hdr) } diff --git a/core/encoding/json/marshal.odin b/core/encoding/json/marshal.odin index 30426f911..fa86d3468 100644 --- a/core/encoding/json/marshal.odin +++ b/core/encoding/json/marshal.odin @@ -406,7 +406,7 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err: ti := runtime.type_info_base(type_info_of(v.id)) info := ti.variant.(runtime.Type_Info_Struct) first_iteration := true - for name, i in info.names { + for name, i in info.names[:info.field_count] { omitempty := false json_name, extra := json_name_from_tag_value(reflect.struct_tag_get(reflect.Struct_Tag(info.tags[i]), "json")) diff --git a/core/encoding/json/unmarshal.odin b/core/encoding/json/unmarshal.odin index eb59e7838..344d2973e 100644 --- a/core/encoding/json/unmarshal.odin +++ b/core/encoding/json/unmarshal.odin @@ -368,7 +368,7 @@ unmarshal_object :: proc(p: ^Parser, v: any, end_token: Token_Kind) -> (err: Unm #partial switch t in ti.variant { case reflect.Type_Info_Struct: - if t.is_raw_union { + if .raw_union in t.flags { return UNSUPPORTED_TYPE } diff --git a/core/fmt/fmt.odin b/core/fmt/fmt.odin index 234f4afbd..ef0647462 100644 --- a/core/fmt/fmt.odin +++ b/core/fmt/fmt.odin @@ -1861,7 +1861,7 @@ handle_tag :: proc(state: ^Info_State, data: rawptr, info: reflect.Type_Info_Str if optional_len == nil { return } - for f, i in info.names { + for f, i in info.names[:info.field_count] { if f != field_name { continue } @@ -1965,7 +1965,7 @@ fmt_struct :: proc(fi: ^Info, v: any, the_verb: rune, info: runtime.Type_Info_St fmt_bad_verb(fi, the_verb) return } - if info.is_raw_union { + if .raw_union in info.flags { if type_name == "" { io.write_string(fi.writer, "(raw union)", &fi.n) } else { @@ -1989,7 +1989,7 @@ fmt_struct :: proc(fi: ^Info, v: any, the_verb: rune, info: runtime.Type_Info_St // fi.hash = false; fi.indent += 1 - is_empty := len(info.names) == 0 + is_empty := info.field_count == 0 if !is_soa && hash && !is_empty { io.write_byte(fi.writer, '\n', &fi.n) @@ -2010,17 +2010,17 @@ fmt_struct :: proc(fi: ^Info, v: any, the_verb: rune, info: runtime.Type_Info_St base_type_name = v.name } - actual_field_count := len(info.names) + actual_field_count := info.field_count n := uintptr(info.soa_len) if info.soa_kind == .Slice { - actual_field_count = len(info.names)-1 // len + actual_field_count = info.field_count-1 // len n = uintptr((^int)(uintptr(v.data) + info.offsets[actual_field_count])^) } else if info.soa_kind == .Dynamic { - actual_field_count = len(info.names)-3 // len, cap, allocator + actual_field_count = info.field_count-3 // len, cap, allocator n = uintptr((^int)(uintptr(v.data) + info.offsets[actual_field_count])^) } @@ -2099,7 +2099,7 @@ fmt_struct :: proc(fi: ^Info, v: any, the_verb: rune, info: runtime.Type_Info_St } } else { field_count := -1 - for name, i in info.names { + for name, i in info.names[:info.field_count] { optional_len: int = -1 use_nul_termination: bool = false verb := the_verb if the_verb == 'w' else 'v' @@ -2605,7 +2605,7 @@ fmt_bit_field :: proc(fi: ^Info, v: any, verb: rune, info: runtime.Type_Info_Bit field_count := -1 - for name, i in info.names { + for name, i in info.names[:info.field_count] { field_verb := verb if handle_bit_field_tag(v.data, info, i, &field_verb) { continue diff --git a/core/reflect/reflect.odin b/core/reflect/reflect.odin index 332d91c6e..e6d2bc87a 100644 --- a/core/reflect/reflect.odin +++ b/core/reflect/reflect.odin @@ -391,7 +391,7 @@ Struct_Field :: struct { struct_field_at :: proc(T: typeid, i: int) -> (field: Struct_Field) { ti := runtime.type_info_base(type_info_of(T)) if s, ok := ti.variant.(runtime.Type_Info_Struct); ok { - if 0 <= i && i < len(s.names) { + if 0 <= i && i < int(s.field_count) { field.name = s.names[i] field.type = s.types[i] field.tag = Struct_Tag(s.tags[i]) @@ -406,7 +406,7 @@ struct_field_at :: proc(T: typeid, i: int) -> (field: Struct_Field) { struct_field_by_name :: proc(T: typeid, name: string) -> (field: Struct_Field) { ti := runtime.type_info_base(type_info_of(T)) if s, ok := ti.variant.(runtime.Type_Info_Struct); ok { - for fname, i in s.names { + for fname, i in s.names[:s.field_count] { if fname == name { field.name = s.names[i] field.type = s.types[i] @@ -427,7 +427,7 @@ struct_field_value_by_name :: proc(a: any, field: string, allow_using := false) ti := runtime.type_info_base(type_info_of(a.id)) if s, ok := ti.variant.(runtime.Type_Info_Struct); ok { - for name, i in s.names { + for name, i in s.names[:s.field_count] { if name == field { return any{ rawptr(uintptr(a.data) + s.offsets[i]), @@ -463,7 +463,7 @@ struct_field_value :: proc(a: any, field: Struct_Field) -> any { struct_field_names :: proc(T: typeid) -> []string { ti := runtime.type_info_base(type_info_of(T)) if s, ok := ti.variant.(runtime.Type_Info_Struct); ok { - return s.names + return s.names[:s.field_count] } return nil } @@ -472,7 +472,7 @@ struct_field_names :: proc(T: typeid) -> []string { struct_field_types :: proc(T: typeid) -> []^Type_Info { ti := runtime.type_info_base(type_info_of(T)) if s, ok := ti.variant.(runtime.Type_Info_Struct); ok { - return s.types + return s.types[:s.field_count] } return nil } @@ -482,7 +482,7 @@ struct_field_types :: proc(T: typeid) -> []^Type_Info { struct_field_tags :: proc(T: typeid) -> []Struct_Tag { ti := runtime.type_info_base(type_info_of(T)) if s, ok := ti.variant.(runtime.Type_Info_Struct); ok { - return transmute([]Struct_Tag)s.tags + return transmute([]Struct_Tag)s.tags[:s.field_count] } return nil } @@ -491,7 +491,7 @@ struct_field_tags :: proc(T: typeid) -> []Struct_Tag { struct_field_offsets :: proc(T: typeid) -> []uintptr { ti := runtime.type_info_base(type_info_of(T)) if s, ok := ti.variant.(runtime.Type_Info_Struct); ok { - return s.offsets + return s.offsets[:s.field_count] } return nil } @@ -501,11 +501,11 @@ struct_fields_zipped :: proc(T: typeid) -> (fields: #soa[]Struct_Field) { ti := runtime.type_info_base(type_info_of(T)) if s, ok := ti.variant.(runtime.Type_Info_Struct); ok { return soa_zip( - name = s.names, - type = s.types, - tag = transmute([]Struct_Tag)s.tags, - offset = s.offsets, - is_using = s.usings, + name = s.names[:s.field_count], + type = s.types[:s.field_count], + tag = ([^]Struct_Tag)(s.tags)[:s.field_count], + offset = s.offsets[:s.field_count], + is_using = s.usings[:s.field_count], ) } return nil @@ -1569,7 +1569,7 @@ equal :: proc(a, b: any, including_indirect_array_recursion := false, recursion_ if v.equal != nil { return v.equal(a.data, b.data) } else { - for offset, i in v.offsets { + for offset, i in v.offsets[:v.field_count] { x := rawptr(uintptr(a.data) + offset) y := rawptr(uintptr(b.data) + offset) id := v.types[i].id diff --git a/core/reflect/types.odin b/core/reflect/types.odin index 04dd8a52d..c92d39410 100644 --- a/core/reflect/types.odin +++ b/core/reflect/types.odin @@ -115,16 +115,14 @@ are_types_identical :: proc(a, b: ^Type_Info) -> bool { case Type_Info_Struct: y := b.variant.(Type_Info_Struct) or_return switch { - case len(x.types) != len(y.types), - x.is_packed != y.is_packed, - x.is_raw_union != y.is_raw_union, - x.custom_align != y.custom_align, + case x.field_count != y.field_count, + x.flags != y.flags, x.soa_kind != y.soa_kind, x.soa_base_type != y.soa_base_type, x.soa_len != y.soa_len: return false } - for _, i in x.types { + for i in 0.. bool { case Type_Info_Bit_Field: y := b.variant.(Type_Info_Bit_Field) or_return if !are_types_identical(x.backing_type, y.backing_type) { return false } - if len(x.names) != len(y.names) { return false } - for _, i in x.names { + if x.field_count != y.field_count { return false } + for _, i in x.names[:x.field_count] { if x.names[i] != y.names[i] { return false } @@ -368,13 +366,13 @@ is_tuple :: proc(info: ^Type_Info) -> bool { is_struct :: proc(info: ^Type_Info) -> bool { if info == nil { return false } s, ok := type_info_base(info).variant.(Type_Info_Struct) - return ok && !s.is_raw_union + return ok && .raw_union not_in s.flags } @(require_results) is_raw_union :: proc(info: ^Type_Info) -> bool { if info == nil { return false } s, ok := type_info_base(info).variant.(Type_Info_Struct) - return ok && s.is_raw_union + return ok && .raw_union in s.flags } @(require_results) is_union :: proc(info: ^Type_Info) -> bool { @@ -656,15 +654,16 @@ write_type_writer :: proc(w: io.Writer, ti: ^Type_Info, n_written: ^int = nil) - } io.write_string(w, "struct ", &n) or_return - if info.is_packed { io.write_string(w, "#packed ", &n) or_return } - if info.is_raw_union { io.write_string(w, "#raw_union ", &n) or_return } - if info.custom_align { + if .packed in info.flags { io.write_string(w, "#packed ", &n) or_return } + if .raw_union in info.flags { io.write_string(w, "#raw_union ", &n) or_return } + if .no_copy in info.flags { io.write_string(w, "#no_copy ", &n) or_return } + if .align in info.flags { io.write_string(w, "#align(", &n) or_return io.write_i64(w, i64(ti.align), 10, &n) or_return io.write_string(w, ") ", &n) or_return } io.write_byte(w, '{', &n) or_return - for name, i in info.names { + for name, i in info.names[:info.field_count] { if i > 0 { io.write_string(w, ", ", &n) or_return } io.write_string(w, name, &n) or_return io.write_string(w, ": ", &n) or_return @@ -722,7 +721,7 @@ write_type_writer :: proc(w: io.Writer, ti: ^Type_Info, n_written: ^int = nil) - io.write_string(w, "bit_field ", &n) or_return write_type(w, info.backing_type, &n) or_return io.write_string(w, " {", &n) or_return - for name, i in info.names { + for name, i in info.names[:info.field_count] { if i > 0 { io.write_string(w, ", ", &n) or_return } io.write_string(w, name, &n) or_return io.write_string(w, ": ", &n) or_return diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp index 9cc0552de..5d9caeba1 100644 --- a/src/llvm_backend_const.cpp +++ b/src/llvm_backend_const.cpp @@ -338,6 +338,15 @@ gb_internal lbValue lb_emit_source_code_location_as_global_ptr(lbProcedure *p, S return addr.addr; } +gb_internal lbValue lb_const_source_code_location_as_global_ptr(lbModule *m, String const &procedure, TokenPos const &pos) { + lbValue loc = lb_const_source_code_location_const(m, procedure, pos); + lbAddr addr = lb_add_global_generated(m, loc.type, loc, nullptr); + lb_make_global_private_const(addr); + return addr.addr; +} + + + gb_internal lbValue lb_emit_source_code_location_as_global_ptr(lbProcedure *p, Ast *node) { lbValue loc = lb_emit_source_code_location_const(p, node); diff --git a/src/llvm_backend_type.cpp b/src/llvm_backend_type.cpp index 2c4abbb4d..6565717a7 100644 --- a/src/llvm_backend_type.cpp +++ b/src/llvm_backend_type.cpp @@ -421,7 +421,7 @@ gb_internal void lb_setup_type_info_data_giant_array(lbModule *m, i64 global_typ } TokenPos pos = t->Named.type_name->token.pos; - lbValue loc = lb_const_source_code_location_const(m, proc_name, pos); + lbValue loc = lb_const_source_code_location_as_global_ptr(m, proc_name, pos); LLVMValueRef vals[4] = { lb_const_string(m, t->Named.type_name->token.string).value, @@ -810,19 +810,18 @@ gb_internal void lb_setup_type_info_data_giant_array(lbModule *m, i64 global_typ case Type_Struct: { tag_type = t_type_info_struct; - LLVMValueRef vals[13] = {}; + LLVMValueRef vals[11] = {}; { - lbValue is_packed = lb_const_bool(m, t_bool, t->Struct.is_packed); - lbValue is_raw_union = lb_const_bool(m, t_bool, t->Struct.is_raw_union); - lbValue is_no_copy = lb_const_bool(m, t_bool, t->Struct.is_no_copy); - lbValue is_custom_align = lb_const_bool(m, t_bool, t->Struct.custom_align != 0); - vals[5] = is_packed.value; - vals[6] = is_raw_union.value; - vals[7] = is_no_copy.value; - vals[8] = is_custom_align.value; + u8 flags = 0; + if (t->Struct.is_packed) flags |= 1<<0; + if (t->Struct.is_raw_union) flags |= 1<<1; + if (t->Struct.is_no_copy) flags |= 1<<2; + if (t->Struct.custom_align) flags |= 1<<3; + + vals[6] = lb_const_int(m, t_u8, flags).value; if (is_type_comparable(t) && !is_type_simple_compare(t)) { - vals[9] = lb_equal_proc_for_type(m, t).value; + vals[10] = lb_equal_proc_for_type(m, t).value; } @@ -831,11 +830,11 @@ gb_internal void lb_setup_type_info_data_giant_array(lbModule *m, i64 global_typ lbValue soa_kind = lb_const_value(m, kind_type, exact_value_i64(t->Struct.soa_kind)); LLVMValueRef soa_type = get_type_info_ptr(m, t->Struct.soa_elem); - lbValue soa_len = lb_const_int(m, t_int, t->Struct.soa_count); + lbValue soa_len = lb_const_int(m, t_u16, t->Struct.soa_count); - vals[10] = soa_kind.value; - vals[11] = soa_type; - vals[12] = soa_len.value; + vals[7] = soa_kind.value; + vals[8] = soa_len.value; + vals[9] = soa_type; } } @@ -882,12 +881,13 @@ gb_internal void lb_setup_type_info_data_giant_array(lbModule *m, i64 global_typ } - lbValue cv = lb_const_int(m, t_int, count); - vals[0] = llvm_const_slice(m, memory_types, cv); - vals[1] = llvm_const_slice(m, memory_names, cv); - vals[2] = llvm_const_slice(m, memory_offsets, cv); - vals[3] = llvm_const_slice(m, memory_usings, cv); - vals[4] = llvm_const_slice(m, memory_tags, cv); + lbValue cv = lb_const_int(m, t_i32, count); + vals[0] = memory_types.value; + vals[1] = memory_names.value; + vals[2] = memory_offsets.value; + vals[3] = memory_usings.value; + vals[4] = memory_tags.value; + vals[5] = cv.value; } for (isize i = 0; i < gb_count_of(vals); i++) { if (vals[i] == nullptr) { @@ -994,7 +994,7 @@ gb_internal void lb_setup_type_info_data_giant_array(lbModule *m, i64 global_typ { tag_type = t_type_info_bit_field; - LLVMValueRef vals[6] = {}; + LLVMValueRef vals[7] = {}; vals[0] = get_type_info_ptr(m, t->BitField.backing_type); isize count = t->BitField.fields.count; if (count > 0) { @@ -1035,11 +1035,12 @@ gb_internal void lb_setup_type_info_data_giant_array(lbModule *m, i64 global_typ } lbValue cv = lb_const_int(m, t_int, count); - vals[1] = llvm_const_slice(m, memory_names, cv); - vals[2] = llvm_const_slice(m, memory_types, cv); - vals[3] = llvm_const_slice(m, memory_bit_sizes, cv); - vals[4] = llvm_const_slice(m, memory_bit_offsets, cv); - vals[5] = llvm_const_slice(m, memory_tags, cv); + vals[1] = memory_names.value; + vals[2] = memory_types.value; + vals[3] = memory_bit_sizes.value; + vals[4] = memory_bit_offsets.value; + vals[5] = memory_tags.value; + vals[6] = cv.value; } -- cgit v1.2.3 From 1e37eaf54daf885636ea3ad9606a2b54e01721f9 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 15 Jul 2024 14:49:20 +0100 Subject: Begin work for `bit_set[...; [N]T]` (not working) --- src/build_settings.cpp | 2 + src/check_expr.cpp | 6 ++- src/check_type.cpp | 21 ++------ src/llvm_backend_const.cpp | 2 + src/llvm_backend_expr.cpp | 120 ++++++++++++++++++++++++++++++++++--------- src/llvm_backend_general.cpp | 2 + src/llvm_backend_proc.cpp | 5 ++ src/main.cpp | 5 ++ src/types.cpp | 21 ++++++++ 9 files changed, 141 insertions(+), 43 deletions(-) (limited to 'src/llvm_backend_const.cpp') diff --git a/src/build_settings.cpp b/src/build_settings.cpp index e0e7810e6..49bb83b22 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -440,6 +440,8 @@ struct BuildContext { bool cached; BuildCacheData build_cache_data; + bool internal_no_inline; + bool no_threaded_checker; bool show_debug_messages; diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 3fcfe29f5..01ff9da5b 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -9947,10 +9947,14 @@ gb_internal ExprKind check_compound_literal(CheckerContext *c, Operand *o, Ast * } Type *et = base_type(t->BitSet.elem); isize field_count = 0; - if (et->kind == Type_Enum) { + if (et != nullptr && et->kind == Type_Enum) { field_count = et->Enum.fields.count; } + if (is_type_array(bit_set_to_int(t))) { + is_constant = false; + } + if (cl->elems[0]->kind == Ast_FieldValue) { error(cl->elems[0], "'field = value' in a bit_set a literal is not allowed"); is_constant = false; diff --git a/src/check_type.cpp b/src/check_type.cpp index fea937e4e..e3609970a 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -939,22 +939,6 @@ gb_internal void check_enum_type(CheckerContext *ctx, Type *enum_type, Type *nam enum_type->Enum.max_value_index = max_value_index; } -gb_internal bool is_valid_bit_field_backing_type(Type *type) { - if (type == nullptr) { - return false; - } - type = base_type(type); - if (is_type_untyped(type)) { - return false; - } - if (is_type_integer(type)) { - return true; - } - if (type->kind == Type_Array) { - return is_type_integer(type->Array.elem); - } - return false; -} gb_internal void check_bit_field_type(CheckerContext *ctx, Type *bit_field_type, Type *named_type, Ast *node) { ast_node(bf, BitFieldType, node); @@ -1268,11 +1252,14 @@ gb_internal void check_bit_set_type(CheckerContext *c, Type *type, Type *named_t Type *t = default_type(lhs.type); if (bs->underlying != nullptr) { Type *u = check_type(c, bs->underlying); + // if (!is_valid_bit_field_backing_type(u)) { if (!is_type_integer(u)) { gbString ts = type_to_string(u); error(bs->underlying, "Expected an underlying integer for the bit set, got %s", ts); gb_string_free(ts); - return; + if (!is_valid_bit_field_backing_type(u)) { + return; + } } type->BitSet.underlying = u; } diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp index 5d9caeba1..12bcc4e1f 100644 --- a/src/llvm_backend_const.cpp +++ b/src/llvm_backend_const.cpp @@ -434,6 +434,8 @@ gb_internal LLVMValueRef lb_big_int_to_llvm(lbModule *m, Type *original_type, Bi } } + GB_ASSERT(!is_type_array(original_type)); + LLVMValueRef value = LLVMConstIntOfArbitraryPrecision(lb_type(m, original_type), cast(unsigned)((sz+7)/8), cast(u64 *)rop); if (big_int_is_neg(a)) { value = LLVMConstNeg(value); diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index bcacc0537..dfb7e162e 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -296,12 +296,6 @@ gb_internal bool lb_try_direct_vector_arith(lbProcedure *p, TokenKind op, lbValu GB_ASSERT(vector_type0 == vector_type1); LLVMTypeRef vector_type = vector_type0; - LLVMValueRef lhs_vp = LLVMBuildPointerCast(p->builder, lhs_ptr.value, LLVMPointerType(vector_type, 0), ""); - LLVMValueRef rhs_vp = LLVMBuildPointerCast(p->builder, rhs_ptr.value, LLVMPointerType(vector_type, 0), ""); - LLVMValueRef x = LLVMBuildLoad2(p->builder, vector_type, lhs_vp, ""); - LLVMValueRef y = LLVMBuildLoad2(p->builder, vector_type, rhs_vp, ""); - LLVMValueRef z = nullptr; - Type *integral_type = base_type(elem_type); if (is_type_simd_vector(integral_type)) { integral_type = core_array_type(integral_type); @@ -311,8 +305,18 @@ gb_internal bool lb_try_direct_vector_arith(lbProcedure *p, TokenKind op, lbValu case Token_Add: op = Token_Or; break; case Token_Sub: op = Token_AndNot; break; } + Type *u = bit_set_to_int(type); + if (is_type_array(u)) { + return false; + } } + LLVMValueRef lhs_vp = LLVMBuildPointerCast(p->builder, lhs_ptr.value, LLVMPointerType(vector_type, 0), ""); + LLVMValueRef rhs_vp = LLVMBuildPointerCast(p->builder, rhs_ptr.value, LLVMPointerType(vector_type, 0), ""); + LLVMValueRef x = LLVMBuildLoad2(p->builder, vector_type, lhs_vp, ""); + LLVMValueRef y = LLVMBuildLoad2(p->builder, vector_type, rhs_vp, ""); + LLVMValueRef z = nullptr; + if (is_type_float(integral_type)) { switch (op) { case Token_Add: @@ -1286,6 +1290,14 @@ handle_op:; case Token_Add: op = Token_Or; break; case Token_Sub: op = Token_AndNot; break; } + Type *u = bit_set_to_int(type); + if (is_type_array(u)) { + lhs.type = u; + rhs.type = u; + res = lb_emit_arith(p, op, lhs, rhs, u); + res.type = type; + return res; + } } Type *integral_type = type; @@ -1441,6 +1453,7 @@ gb_internal lbValue lb_build_binary_in(lbProcedure *p, lbValue left, lbValue rig GB_ASSERT(are_types_identical(left.type, key_type)); Type *it = bit_set_to_int(rt); + left = lb_emit_conv(p, left, it); if (is_type_different_to_arch_endianness(it)) { left = lb_emit_byte_swap(p, left, integer_endian_type_to_platform_type(it)); @@ -2054,6 +2067,26 @@ gb_internal lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) { } } + // bit_set <-> backing type + if (is_type_bit_set(src)) { + Type *backing = bit_set_to_int(src); + if (are_types_identical(backing, dst)) { + lbValue res = {}; + res.type = t; + res.value = value.value; + return res; + } + } + if (is_type_bit_set(dst)) { + Type *backing = bit_set_to_int(dst); + if (are_types_identical(src, backing)) { + lbValue res = {}; + res.type = t; + res.value = value.value; + return res; + } + } + // Pointer <-> uintptr if (is_type_pointer(src) && is_type_uintptr(dst)) { @@ -2951,13 +2984,32 @@ gb_internal lbValue lb_emit_comp_against_nil(lbProcedure *p, TokenKind op_kind, case Type_Pointer: case Type_MultiPointer: case Type_Proc: - case Type_BitSet: if (op_kind == Token_CmpEq) { res.value = LLVMBuildIsNull(p->builder, x.value, ""); } else if (op_kind == Token_NotEq) { res.value = LLVMBuildIsNotNull(p->builder, x.value, ""); } return res; + case Type_BitSet: + { + Type *u = bit_set_to_int(bt); + if (is_type_array(u)) { + auto args = array_make(permanent_allocator(), 2); + lbValue lhs = lb_address_from_load_or_generate_local(p, x); + args[0] = lb_emit_conv(p, lhs, t_rawptr); + args[1] = lb_const_int(p->module, t_int, type_size_of(t)); + lbValue val = lb_emit_runtime_call(p, "memory_compare_zero", args); + lbValue res = lb_emit_comp(p, op_kind, val, lb_const_int(p->module, t_int, 0)); + return res; + } else { + if (op_kind == Token_CmpEq) { + res.value = LLVMBuildIsNull(p->builder, x.value, ""); + } else if (op_kind == Token_NotEq) { + res.value = LLVMBuildIsNotNull(p->builder, x.value, ""); + } + } + return res; + } case Type_Slice: { @@ -4878,29 +4930,47 @@ gb_internal lbAddr lb_build_addr_compound_lit(lbProcedure *p, Ast *expr) { case Type_BitSet: { i64 sz = type_size_of(type); if (cl->elems.count > 0 && sz > 0) { - lb_addr_store(p, v, lb_const_value(p->module, type, exact_value_compound(expr))); - lbValue lower = lb_const_value(p->module, t_int, exact_value_i64(bt->BitSet.lower)); - for (Ast *elem : cl->elems) { - GB_ASSERT(elem->kind != Ast_FieldValue); - if (lb_is_elem_const(elem, et)) { - continue; + Type *backing = bit_set_to_int(type); + if (is_type_array(backing)) { + GB_PANIC("TODO: bit_set [N]T"); + Type *base_it = core_array_type(backing); + i64 bits_per_elem = 8*type_size_of(base_it); + gb_unused(bits_per_elem); + lbValue one = lb_const_value(p->module, t_i64, exact_value_i64(1)); + for (Ast *elem : cl->elems) { + GB_ASSERT(elem->kind != Ast_FieldValue); + lbValue expr = lb_build_expr(p, elem); + GB_ASSERT(expr.type->kind != Type_Tuple); + + lbValue e = lb_emit_conv(p, expr, t_i64); + e = lb_emit_arith(p, Token_Sub, e, lower, t_i64); + // lbValue idx = lb_emit_arith(p, Token_Div, e, bits_per_elem, t_i64); + // lbValue val = lb_emit_arith(p, Token_Div, e, bits_per_elem, t_i64); } - - lbValue expr = lb_build_expr(p, elem); - GB_ASSERT(expr.type->kind != Type_Tuple); - + } else { Type *it = bit_set_to_int(bt); lbValue one = lb_const_value(p->module, it, exact_value_i64(1)); - lbValue e = lb_emit_conv(p, expr, it); - e = lb_emit_arith(p, Token_Sub, e, lower, it); - e = lb_emit_arith(p, Token_Shl, one, e, it); - - lbValue old_value = lb_emit_transmute(p, lb_addr_load(p, v), it); - lbValue new_value = lb_emit_arith(p, Token_Or, old_value, e, it); - new_value = lb_emit_transmute(p, new_value, type); - lb_addr_store(p, v, new_value); + for (Ast *elem : cl->elems) { + GB_ASSERT(elem->kind != Ast_FieldValue); + + if (lb_is_elem_const(elem, et)) { + continue; + } + + lbValue expr = lb_build_expr(p, elem); + GB_ASSERT(expr.type->kind != Type_Tuple); + + lbValue e = lb_emit_conv(p, expr, it); + e = lb_emit_arith(p, Token_Sub, e, lower, it); + e = lb_emit_arith(p, Token_Shl, one, e, it); + + lbValue old_value = lb_emit_transmute(p, lb_addr_load(p, v), it); + lbValue new_value = lb_emit_arith(p, Token_Or, old_value, e, it); + new_value = lb_emit_transmute(p, new_value, type); + lb_addr_store(p, v, new_value); + } } } break; diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index bb04fc746..a91c1d1fe 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -1023,6 +1023,8 @@ gb_internal void lb_emit_store(lbProcedure *p, lbValue ptr, lbValue value) { LLVMTypeRef rawptr_type = lb_type(p->module, t_rawptr); LLVMTypeRef rawptr_ptr_type = LLVMPointerType(rawptr_type, 0); LLVMBuildStore(p->builder, LLVMConstNull(rawptr_type), LLVMBuildBitCast(p->builder, ptr.value, rawptr_ptr_type, "")); + } else if (is_type_bit_set(a)) { + lb_mem_zero_ptr(p, ptr.value, a, 1); } else if (lb_sizeof(src_t) <= lb_max_zero_init_size()) { LLVMBuildStore(p->builder, LLVMConstNull(src_t), ptr.value); } else { diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index eefe1c422..4ee4fb769 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -159,6 +159,11 @@ gb_internal lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool i case ProcInlining_no_inline: lb_add_attribute_to_proc(m, p->value, "noinline"); break; + default: + if (build_context.internal_no_inline) { + lb_add_attribute_to_proc(m, p->value, "noinline"); + break; + } } switch (entity->Procedure.optimization_mode) { diff --git a/src/main.cpp b/src/main.cpp index 0c3ef1399..e7f4ccc0a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -394,6 +394,7 @@ enum BuildFlagKind { BuildFlag_InternalIgnorePanic, BuildFlag_InternalModulePerFile, BuildFlag_InternalCached, + BuildFlag_InternalNoInline, BuildFlag_Tilde, @@ -598,6 +599,7 @@ gb_internal bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_InternalIgnorePanic, str_lit("internal-ignore-panic"), BuildFlagParam_None, Command_all); add_flag(&build_flags, BuildFlag_InternalModulePerFile, str_lit("internal-module-per-file"), BuildFlagParam_None, Command_all); add_flag(&build_flags, BuildFlag_InternalCached, str_lit("internal-cached"), BuildFlagParam_None, Command_all); + add_flag(&build_flags, BuildFlag_InternalNoInline, str_lit("internal-no-inline"), BuildFlagParam_None, Command_all); #if ALLOW_TILDE add_flag(&build_flags, BuildFlag_Tilde, str_lit("tilde"), BuildFlagParam_None, Command__does_build); @@ -1422,6 +1424,9 @@ gb_internal bool parse_build_flags(Array args) { build_context.cached = true; build_context.use_separate_modules = true; break; + case BuildFlag_InternalNoInline: + build_context.internal_no_inline = true; + break; case BuildFlag_Tilde: build_context.tilde_backend = true; diff --git a/src/types.cpp b/src/types.cpp index fdc174d81..3f86d4c50 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -2011,6 +2011,24 @@ gb_internal bool is_type_valid_bit_set_elem(Type *t) { return false; } + +gb_internal bool is_valid_bit_field_backing_type(Type *type) { + if (type == nullptr) { + return false; + } + type = base_type(type); + if (is_type_untyped(type)) { + return false; + } + if (is_type_integer(type)) { + return true; + } + if (type->kind == Type_Array) { + return is_type_integer(type->Array.elem); + } + return false; +} + gb_internal Type *bit_set_to_int(Type *t) { GB_ASSERT(is_type_bit_set(t)); Type *bt = base_type(t); @@ -2018,6 +2036,9 @@ gb_internal Type *bit_set_to_int(Type *t) { if (underlying != nullptr && is_type_integer(underlying)) { return underlying; } + if (underlying != nullptr && is_valid_bit_field_backing_type(underlying)) { + return underlying; + } i64 sz = type_size_of(t); switch (sz) { -- cgit v1.2.3 From bc5b41938ec29cbc7678c0307e7571a02b3d84b1 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 23 Jul 2024 02:40:51 +0100 Subject: Fix #3964 --- src/llvm_backend.cpp | 5 +++-- src/llvm_backend.hpp | 2 +- src/llvm_backend_const.cpp | 6 +++++- 3 files changed, 9 insertions(+), 4 deletions(-) (limited to 'src/llvm_backend_const.cpp') diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 62909dafb..9fa570eaf 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -3288,11 +3288,12 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { if (!is_type_any(e->type) && !is_type_union(e->type)) { if (tav.mode != Addressing_Invalid) { if (tav.value.kind != ExactValue_Invalid) { + bool is_rodata = e->kind == Entity_Variable && e->Variable.is_rodata; ExactValue v = tav.value; - lbValue init = lb_const_value(m, tav.type, v); + lbValue init = lb_const_value(m, tav.type, v, false, is_rodata); LLVMSetInitializer(g.value, init.value); var.is_initialized = true; - if (e->kind == Entity_Variable && e->Variable.is_rodata) { + if (is_rodata) { LLVMSetGlobalConstant(g.value, true); } } diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index 806864c7c..02daecf6b 100644 --- a/src/llvm_backend.hpp +++ b/src/llvm_backend.hpp @@ -398,7 +398,7 @@ gb_internal lbBlock *lb_create_block(lbProcedure *p, char const *name, bool appe gb_internal lbValue lb_const_nil(lbModule *m, Type *type); gb_internal lbValue lb_const_undef(lbModule *m, Type *type); -gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_local=true); +gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_local=true, bool is_rodata=false); gb_internal lbValue lb_const_bool(lbModule *m, Type *type, bool value); gb_internal lbValue lb_const_int(lbModule *m, Type *type, u64 value); diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp index 12bcc4e1f..4f9ca8714 100644 --- a/src/llvm_backend_const.cpp +++ b/src/llvm_backend_const.cpp @@ -470,7 +470,7 @@ gb_internal bool lb_is_nested_possibly_constant(Type *ft, Selection const &sel, return lb_is_elem_const(elem, ft); } -gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_local) { +gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_local, bool is_rodata) { LLVMContextRef ctx = m->ctx; type = default_type(type); @@ -565,6 +565,10 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo array_data = LLVMAddGlobal(m->mod, lb_type(m, t), str); LLVMSetInitializer(array_data, backing_array.value); + if (is_rodata) { + LLVMSetGlobalConstant(array_data, true); + } + lbValue g = {}; g.value = array_data; g.type = t; -- cgit v1.2.3 From b0fe777eded8da007aa76a6c46c0f0d3b02cb8ca Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 23 Jul 2024 03:01:09 +0100 Subject: Propagate `rodata` a bit more in `lb_const_value` --- src/llvm_backend_const.cpp | 64 ++++++++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 28 deletions(-) (limited to 'src/llvm_backend_const.cpp') diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp index 4f9ca8714..6a6b119aa 100644 --- a/src/llvm_backend_const.cpp +++ b/src/llvm_backend_const.cpp @@ -365,7 +365,11 @@ gb_internal lbValue lb_emit_source_code_location_as_global(lbProcedure *p, Ast * -gb_internal LLVMValueRef lb_build_constant_array_values(lbModule *m, Type *type, Type *elem_type, isize count, LLVMValueRef *values, bool allow_local) { +gb_internal LLVMValueRef lb_build_constant_array_values(lbModule *m, Type *type, Type *elem_type, isize count, LLVMValueRef *values, bool allow_local, bool is_rodata) { + if (allow_local) { + is_rodata = false; + } + bool is_local = allow_local && m->curr_procedure != nullptr; bool is_const = true; if (is_local) { @@ -471,6 +475,10 @@ gb_internal bool lb_is_nested_possibly_constant(Type *ft, Selection const &sel, } gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_local, bool is_rodata) { + if (allow_local) { + is_rodata = false; + } + LLVMContextRef ctx = m->ctx; type = default_type(type); @@ -528,7 +536,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo count = gb_max(cast(isize)cl->max_count, count); Type *elem = base_type(type)->Slice.elem; Type *t = alloc_type_array(elem, count); - lbValue backing_array = lb_const_value(m, t, value, allow_local); + lbValue backing_array = lb_const_value(m, t, value, allow_local, is_rodata); LLVMValueRef array_data = nullptr; @@ -616,7 +624,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo } // NOTE(bill, 2021-10-07): Allow for array programming value constants Type *core_elem = core_array_type(type); - return lb_const_value(m, core_elem, value, allow_local); + return lb_const_value(m, core_elem, value, allow_local, is_rodata); } else if (is_type_u8_array(type) && value.kind == ExactValue_String) { GB_ASSERT(type->Array.count == value.value_string.len); LLVMValueRef data = LLVMConstStringInContext(ctx, @@ -634,7 +642,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo Type *elem = type->Array.elem; - lbValue single_elem = lb_const_value(m, elem, value, allow_local); + lbValue single_elem = lb_const_value(m, elem, value, allow_local, is_rodata); LLVMValueRef *elems = gb_alloc_array(permanent_allocator(), LLVMValueRef, cast(isize)count); for (i64 i = 0; i < count; i++) { @@ -652,7 +660,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo Type *elem = type->Matrix.elem; - lbValue single_elem = lb_const_value(m, elem, value, allow_local); + lbValue single_elem = lb_const_value(m, elem, value, allow_local, is_rodata); single_elem.value = llvm_const_cast(single_elem.value, lb_type(m, elem)); i64 total_elem_count = matrix_type_total_internal_elems(type); @@ -674,7 +682,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo i64 count = type->SimdVector.count; Type *elem = type->SimdVector.elem; - lbValue single_elem = lb_const_value(m, elem, value, allow_local); + lbValue single_elem = lb_const_value(m, elem, value, allow_local, is_rodata); single_elem.value = llvm_const_cast(single_elem.value, lb_type(m, elem)); LLVMValueRef *elems = gb_alloc_array(permanent_allocator(), LLVMValueRef, count); @@ -803,7 +811,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo case ExactValue_Compound: if (is_type_slice(type)) { - return lb_const_value(m, type, value, allow_local); + return lb_const_value(m, type, value, allow_local, is_rodata); } else if (is_type_array(type)) { ast_node(cl, CompoundLit, value.value_compound); Type *elem_type = type->Array.elem; @@ -837,7 +845,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo } if (lo == i) { TypeAndValue tav = fv->value->tav; - LLVMValueRef val = lb_const_value(m, elem_type, tav.value, allow_local).value; + LLVMValueRef val = lb_const_value(m, elem_type, tav.value, allow_local, is_rodata).value; for (i64 k = lo; k < hi; k++) { values[value_index++] = val; } @@ -852,7 +860,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo i64 index = exact_value_to_i64(index_tav.value); if (index == i) { TypeAndValue tav = fv->value->tav; - LLVMValueRef val = lb_const_value(m, elem_type, tav.value, allow_local).value; + LLVMValueRef val = lb_const_value(m, elem_type, tav.value, allow_local, is_rodata).value; values[value_index++] = val; found = true; break; @@ -865,7 +873,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo } } - res.value = lb_build_constant_array_values(m, type, elem_type, cast(isize)type->Array.count, values, allow_local); + res.value = lb_build_constant_array_values(m, type, elem_type, cast(isize)type->Array.count, values, allow_local, is_rodata); return res; } else { GB_ASSERT_MSG(elem_count == type->Array.count, "%td != %td", elem_count, type->Array.count); @@ -875,13 +883,13 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo for (isize i = 0; i < elem_count; i++) { TypeAndValue tav = cl->elems[i]->tav; GB_ASSERT(tav.mode != Addressing_Invalid); - values[i] = lb_const_value(m, elem_type, tav.value, allow_local).value; + values[i] = lb_const_value(m, elem_type, tav.value, allow_local, is_rodata).value; } for (isize i = elem_count; i < type->Array.count; i++) { values[i] = LLVMConstNull(lb_type(m, elem_type)); } - res.value = lb_build_constant_array_values(m, type, elem_type, cast(isize)type->Array.count, values, allow_local); + res.value = lb_build_constant_array_values(m, type, elem_type, cast(isize)type->Array.count, values, allow_local, is_rodata); return res; } } else if (is_type_enumerated_array(type)) { @@ -921,7 +929,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo } if (lo == i) { TypeAndValue tav = fv->value->tav; - LLVMValueRef val = lb_const_value(m, elem_type, tav.value, allow_local).value; + LLVMValueRef val = lb_const_value(m, elem_type, tav.value, allow_local, is_rodata).value; for (i64 k = lo; k < hi; k++) { values[value_index++] = val; } @@ -936,7 +944,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo i64 index = exact_value_to_i64(index_tav.value); if (index == i) { TypeAndValue tav = fv->value->tav; - LLVMValueRef val = lb_const_value(m, elem_type, tav.value, allow_local).value; + LLVMValueRef val = lb_const_value(m, elem_type, tav.value, allow_local, is_rodata).value; values[value_index++] = val; found = true; break; @@ -949,7 +957,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo } } - res.value = lb_build_constant_array_values(m, type, elem_type, cast(isize)type->EnumeratedArray.count, values, allow_local); + res.value = lb_build_constant_array_values(m, type, elem_type, cast(isize)type->EnumeratedArray.count, values, allow_local, is_rodata); return res; } else { GB_ASSERT_MSG(elem_count == type->EnumeratedArray.count, "%td != %td", elem_count, type->EnumeratedArray.count); @@ -959,13 +967,13 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo for (isize i = 0; i < elem_count; i++) { TypeAndValue tav = cl->elems[i]->tav; GB_ASSERT(tav.mode != Addressing_Invalid); - values[i] = lb_const_value(m, elem_type, tav.value, allow_local).value; + values[i] = lb_const_value(m, elem_type, tav.value, allow_local, is_rodata).value; } for (isize i = elem_count; i < type->EnumeratedArray.count; i++) { values[i] = LLVMConstNull(lb_type(m, elem_type)); } - res.value = lb_build_constant_array_values(m, type, elem_type, cast(isize)type->EnumeratedArray.count, values, allow_local); + res.value = lb_build_constant_array_values(m, type, elem_type, cast(isize)type->EnumeratedArray.count, values, allow_local, is_rodata); return res; } } else if (is_type_simd_vector(type)) { @@ -1004,7 +1012,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo } if (lo == i) { TypeAndValue tav = fv->value->tav; - LLVMValueRef val = lb_const_value(m, elem_type, tav.value, allow_local).value; + LLVMValueRef val = lb_const_value(m, elem_type, tav.value, allow_local, is_rodata).value; for (i64 k = lo; k < hi; k++) { values[value_index++] = val; } @@ -1019,7 +1027,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo i64 index = exact_value_to_i64(index_tav.value); if (index == i) { TypeAndValue tav = fv->value->tav; - LLVMValueRef val = lb_const_value(m, elem_type, tav.value, allow_local).value; + LLVMValueRef val = lb_const_value(m, elem_type, tav.value, allow_local, is_rodata).value; values[value_index++] = val; found = true; break; @@ -1038,7 +1046,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo for (isize i = 0; i < elem_count; i++) { TypeAndValue tav = cl->elems[i]->tav; GB_ASSERT(tav.mode != Addressing_Invalid); - values[i] = lb_const_value(m, elem_type, tav.value, allow_local).value; + values[i] = lb_const_value(m, elem_type, tav.value, allow_local, is_rodata).value; } LLVMTypeRef et = lb_type(m, elem_type); @@ -1087,7 +1095,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo i32 index = field_remapping[f->Variable.field_index]; if (elem_type_can_be_constant(f->type)) { if (sel.index.count == 1) { - values[index] = lb_const_value(m, f->type, tav.value, allow_local).value; + values[index] = lb_const_value(m, f->type, tav.value, allow_local, is_rodata).value; visited[index] = true; } else { if (!visited[index]) { @@ -1129,7 +1137,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo } } if (is_constant) { - LLVMValueRef elem_value = lb_const_value(m, tav.type, tav.value, allow_local).value; + LLVMValueRef elem_value = lb_const_value(m, tav.type, tav.value, allow_local, is_rodata).value; if (LLVMIsConstant(elem_value)) { values[index] = llvm_const_insert_value(m, values[index], elem_value, idx_list, idx_list_len); } else { @@ -1151,7 +1159,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo i32 index = field_remapping[f->Variable.field_index]; if (elem_type_can_be_constant(f->type)) { - values[index] = lb_const_value(m, f->type, val, allow_local).value; + values[index] = lb_const_value(m, f->type, val, allow_local, is_rodata).value; visited[index] = true; } } @@ -1277,7 +1285,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo TypeAndValue tav = fv->value->tav; - LLVMValueRef val = lb_const_value(m, elem_type, tav.value, allow_local).value; + LLVMValueRef val = lb_const_value(m, elem_type, tav.value, allow_local, is_rodata).value; for (i64 k = lo; k < hi; k++) { i64 offset = matrix_row_major_index_to_offset(type, k); GB_ASSERT(values[offset] == nullptr); @@ -1289,7 +1297,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo i64 index = exact_value_to_i64(index_tav.value); GB_ASSERT(index < max_count); TypeAndValue tav = fv->value->tav; - LLVMValueRef val = lb_const_value(m, elem_type, tav.value, allow_local).value; + LLVMValueRef val = lb_const_value(m, elem_type, tav.value, allow_local, is_rodata).value; i64 offset = matrix_row_major_index_to_offset(type, index); GB_ASSERT(values[offset] == nullptr); values[offset] = val; @@ -1302,7 +1310,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo } } - res.value = lb_build_constant_array_values(m, type, elem_type, cast(isize)total_count, values, allow_local); + res.value = lb_build_constant_array_values(m, type, elem_type, cast(isize)total_count, values, allow_local, is_rodata); return res; } else { GB_ASSERT_MSG(elem_count == max_count, "%td != %td", elem_count, max_count); @@ -1313,7 +1321,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo GB_ASSERT(tav.mode != Addressing_Invalid); i64 offset = 0; offset = matrix_row_major_index_to_offset(type, i); - values[offset] = lb_const_value(m, elem_type, tav.value, allow_local).value; + values[offset] = lb_const_value(m, elem_type, tav.value, allow_local, is_rodata).value; } for (isize i = 0; i < total_count; i++) { if (values[i] == nullptr) { @@ -1321,7 +1329,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo } } - res.value = lb_build_constant_array_values(m, type, elem_type, cast(isize)total_count, values, allow_local); + res.value = lb_build_constant_array_values(m, type, elem_type, cast(isize)total_count, values, allow_local, is_rodata); return res; } } else { -- cgit v1.2.3 From 3b22c0854c0a64ae27ca43f59b5f6cdffcae56ab Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Wed, 11 Sep 2024 22:45:16 +0200 Subject: fix some LLVM assertions --- src/llvm_backend_const.cpp | 4 ++-- src/llvm_backend_type.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/llvm_backend_const.cpp') diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp index 6a6b119aa..754bbfca2 100644 --- a/src/llvm_backend_const.cpp +++ b/src/llvm_backend_const.cpp @@ -154,7 +154,7 @@ gb_internal LLVMValueRef llvm_const_named_struct(lbModule *m, Type *t, LLVMValue GB_ASSERT(value_count_ == bt->Struct.fields.count); auto field_remapping = lb_get_struct_remapping(m, t); - unsigned values_with_padding_count = LLVMCountStructElementTypes(struct_type); + unsigned values_with_padding_count = elem_count; LLVMValueRef *values_with_padding = gb_alloc_array(permanent_allocator(), LLVMValueRef, values_with_padding_count); for (unsigned i = 0; i < value_count; i++) { @@ -722,7 +722,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo } case ExactValue_Integer: - if (is_type_pointer(type) || is_type_multi_pointer(type)) { + if (is_type_pointer(type) || is_type_multi_pointer(type) || is_type_proc(type)) { LLVMTypeRef t = lb_type(m, original_type); LLVMValueRef i = lb_big_int_to_llvm(m, t_uintptr, &value.value_integer); res.value = LLVMConstIntToPtr(i, t); diff --git a/src/llvm_backend_type.cpp b/src/llvm_backend_type.cpp index 638170bfc..9d4505bb0 100644 --- a/src/llvm_backend_type.cpp +++ b/src/llvm_backend_type.cpp @@ -826,7 +826,7 @@ gb_internal void lb_setup_type_info_data_giant_array(lbModule *m, i64 global_typ if (t->Struct.soa_kind != StructSoa_None) { - Type *kind_type = get_struct_field_type(tag_type, 10); + Type *kind_type = get_struct_field_type(tag_type, 7); lbValue soa_kind = lb_const_value(m, kind_type, exact_value_i64(t->Struct.soa_kind)); LLVMValueRef soa_type = get_type_info_ptr(m, t->Struct.soa_elem); -- cgit v1.2.3