diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2018-09-20 11:04:31 -0400 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2018-09-20 11:04:31 -0400 |
| commit | f8fe517d126d582e37ab4537fe9fd42f0531f44b (patch) | |
| tree | 040baa17d21eb30b1dc7d2a4ef470fe7aea08e85 /src | |
| parent | 492821781dc34659f694577aacbc853c8839406f (diff) | |
| download | zig-f8fe517d126d582e37ab4537fe9fd42f0531f44b.tar.gz zig-f8fe517d126d582e37ab4537fe9fd42f0531f44b.zip | |
better string literal caching implementation
We were caching the ConstExprValue of string literals,
which works if you can never modify ConstExprValues.
This premise is broken with `comptime var ...`.
So I implemented an optimization in ConstExprValue
arrays, where it stores a `Buf *` directly rather
than an array of ConstExprValues for the elements,
and then similar to array of undefined, it is
expanded into the canonical form when necessary.
However many operations can happen directly on the
`Buf *`, which is faster.
Furthermore, before a ConstExprValue array is expanded
into canonical form, it removes itself from the string
literal cache. This fixes the issue, because before an
array element is modified it would have to be expanded.
closes #1076
Diffstat (limited to 'src')
| -rw-r--r-- | src/all_types.hpp | 17 | ||||
| -rw-r--r-- | src/analyze.cpp | 239 | ||||
| -rw-r--r-- | src/analyze.hpp | 30 | ||||
| -rw-r--r-- | src/codegen.cpp | 48 | ||||
| -rw-r--r-- | src/ir.cpp | 135 |
5 files changed, 260 insertions, 209 deletions
diff --git a/src/all_types.hpp b/src/all_types.hpp index ed1dcb1f9b..290e4bb0dd 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -130,14 +130,18 @@ struct ConstUnionValue { enum ConstArraySpecial { ConstArraySpecialNone, ConstArraySpecialUndef, + ConstArraySpecialBuf, }; struct ConstArrayValue { ConstArraySpecial special; - struct { - ConstExprValue *elements; - ConstParent parent; - } s_none; + union { + struct { + ConstExprValue *elements; + ConstParent parent; + } s_none; + Buf *s_buf; + } data; }; enum ConstPtrSpecial { @@ -983,6 +987,7 @@ struct FnTypeParamInfo { }; struct GenericFnTypeId { + CodeGen *codegen; ZigFn *fn_entry; ConstExprValue *params; size_t param_count; @@ -1291,6 +1296,7 @@ struct FnExport { }; struct ZigFn { + CodeGen *codegen; LLVMValueRef llvm_value; const char *llvm_name; AstNode *proto_node; @@ -1848,13 +1854,14 @@ enum ScopeId { }; struct Scope { - ScopeId id; + CodeGen *codegen; AstNode *source_node; // if the scope has a parent, this is it Scope *parent; ZigLLVMDIScope *di_scope; + ScopeId id; }; // This scope comes from global declarations or from diff --git a/src/analyze.cpp b/src/analyze.cpp index f37418e4f4..b47f9e9b9c 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -92,62 +92,63 @@ ScopeDecls *get_container_scope(ZigType *type_entry) { return *get_container_scope_ptr(type_entry); } -void init_scope(Scope *dest, ScopeId id, AstNode *source_node, Scope *parent) { +void init_scope(CodeGen *g, Scope *dest, ScopeId id, AstNode *source_node, Scope *parent) { + dest->codegen = g; dest->id = id; dest->source_node = source_node; dest->parent = parent; } -ScopeDecls *create_decls_scope(AstNode *node, Scope *parent, ZigType *container_type, ImportTableEntry *import) { +ScopeDecls *create_decls_scope(CodeGen *g, AstNode *node, Scope *parent, ZigType *container_type, ImportTableEntry *import) { assert(node == nullptr || node->type == NodeTypeRoot || node->type == NodeTypeContainerDecl || node->type == NodeTypeFnCallExpr); ScopeDecls *scope = allocate<ScopeDecls>(1); - init_scope(&scope->base, ScopeIdDecls, node, parent); + init_scope(g, &scope->base, ScopeIdDecls, node, parent); scope->decl_table.init(4); scope->container_type = container_type; scope->import = import; return scope; } -ScopeBlock *create_block_scope(AstNode *node, Scope *parent) { +ScopeBlock *create_block_scope(CodeGen *g, AstNode *node, Scope *parent) { assert(node->type == NodeTypeBlock); ScopeBlock *scope = allocate<ScopeBlock>(1); - init_scope(&scope->base, ScopeIdBlock, node, parent); + init_scope(g, &scope->base, ScopeIdBlock, node, parent); scope->name = node->data.block.name; return scope; } -ScopeDefer *create_defer_scope(AstNode *node, Scope *parent) { +ScopeDefer *create_defer_scope(CodeGen *g, AstNode *node, Scope *parent) { assert(node->type == NodeTypeDefer); ScopeDefer *scope = allocate<ScopeDefer>(1); - init_scope(&scope->base, ScopeIdDefer, node, parent); + init_scope(g, &scope->base, ScopeIdDefer, node, parent); return scope; } -ScopeDeferExpr *create_defer_expr_scope(AstNode *node, Scope *parent) { +ScopeDeferExpr *create_defer_expr_scope(CodeGen *g, AstNode *node, Scope *parent) { assert(node->type == NodeTypeDefer); ScopeDeferExpr *scope = allocate<ScopeDeferExpr>(1); - init_scope(&scope->base, ScopeIdDeferExpr, node, parent); + init_scope(g, &scope->base, ScopeIdDeferExpr, node, parent); return scope; } -Scope *create_var_scope(AstNode *node, Scope *parent, ZigVar *var) { +Scope *create_var_scope(CodeGen *g, AstNode *node, Scope *parent, ZigVar *var) { ScopeVarDecl *scope = allocate<ScopeVarDecl>(1); - init_scope(&scope->base, ScopeIdVarDecl, node, parent); + init_scope(g, &scope->base, ScopeIdVarDecl, node, parent); scope->var = var; return &scope->base; } -ScopeCImport *create_cimport_scope(AstNode *node, Scope *parent) { +ScopeCImport *create_cimport_scope(CodeGen *g, AstNode *node, Scope *parent) { assert(node->type == NodeTypeFnCallExpr); ScopeCImport *scope = allocate<ScopeCImport>(1); - init_scope(&scope->base, ScopeIdCImport, node, parent); + init_scope(g, &scope->base, ScopeIdCImport, node, parent); buf_resize(&scope->buf, 0); return scope; } -ScopeLoop *create_loop_scope(AstNode *node, Scope *parent) { +ScopeLoop *create_loop_scope(CodeGen *g, AstNode *node, Scope *parent) { ScopeLoop *scope = allocate<ScopeLoop>(1); - init_scope(&scope->base, ScopeIdLoop, node, parent); + init_scope(g, &scope->base, ScopeIdLoop, node, parent); if (node->type == NodeTypeWhileExpr) { scope->name = node->data.while_expr.name; } else if (node->type == NodeTypeForExpr) { @@ -158,37 +159,37 @@ ScopeLoop *create_loop_scope(AstNode *node, Scope *parent) { return scope; } -Scope *create_runtime_scope(AstNode *node, Scope *parent, IrInstruction *is_comptime) { +Scope *create_runtime_scope(CodeGen *g, AstNode *node, Scope *parent, IrInstruction *is_comptime) { ScopeRuntime *scope = allocate<ScopeRuntime>(1); scope->is_comptime = is_comptime; - init_scope(&scope->base, ScopeIdRuntime, node, parent); + init_scope(g, &scope->base, ScopeIdRuntime, node, parent); return &scope->base; } -ScopeSuspend *create_suspend_scope(AstNode *node, Scope *parent) { +ScopeSuspend *create_suspend_scope(CodeGen *g, AstNode *node, Scope *parent) { assert(node->type == NodeTypeSuspend); ScopeSuspend *scope = allocate<ScopeSuspend>(1); - init_scope(&scope->base, ScopeIdSuspend, node, parent); + init_scope(g, &scope->base, ScopeIdSuspend, node, parent); return scope; } -ScopeFnDef *create_fndef_scope(AstNode *node, Scope *parent, ZigFn *fn_entry) { +ScopeFnDef *create_fndef_scope(CodeGen *g, AstNode *node, Scope *parent, ZigFn *fn_entry) { ScopeFnDef *scope = allocate<ScopeFnDef>(1); - init_scope(&scope->base, ScopeIdFnDef, node, parent); + init_scope(g, &scope->base, ScopeIdFnDef, node, parent); scope->fn_entry = fn_entry; return scope; } -Scope *create_comptime_scope(AstNode *node, Scope *parent) { +Scope *create_comptime_scope(CodeGen *g, AstNode *node, Scope *parent) { assert(node->type == NodeTypeCompTime || node->type == NodeTypeSwitchExpr); ScopeCompTime *scope = allocate<ScopeCompTime>(1); - init_scope(&scope->base, ScopeIdCompTime, node, parent); + init_scope(g, &scope->base, ScopeIdCompTime, node, parent); return &scope->base; } -Scope *create_coro_prelude_scope(AstNode *node, Scope *parent) { +Scope *create_coro_prelude_scope(CodeGen *g, AstNode *node, Scope *parent) { ScopeCoroPrelude *scope = allocate<ScopeCoroPrelude>(1); - init_scope(&scope->base, ScopeIdCoroPrelude, node, parent); + init_scope(g, &scope->base, ScopeIdCoroPrelude, node, parent); return &scope->base; } @@ -204,9 +205,9 @@ ImportTableEntry *get_scope_import(Scope *scope) { zig_unreachable(); } -static ZigType *new_container_type_entry(ZigTypeId id, AstNode *source_node, Scope *parent_scope) { +static ZigType *new_container_type_entry(CodeGen *g, ZigTypeId id, AstNode *source_node, Scope *parent_scope) { ZigType *entry = new_type_table_entry(id); - *get_container_scope_ptr(entry) = create_decls_scope(source_node, parent_scope, entry, get_scope_import(parent_scope)); + *get_container_scope_ptr(entry) = create_decls_scope(g, source_node, parent_scope, entry, get_scope_import(parent_scope)); return entry; } @@ -1245,7 +1246,7 @@ ZigType *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind AstNode *decl_node, const char *name, ContainerLayout layout) { ZigTypeId type_id = container_to_type(kind); - ZigType *entry = new_container_type_entry(type_id, decl_node, scope); + ZigType *entry = new_container_type_entry(g, type_id, decl_node, scope); switch (kind) { case ContainerKindStruct: @@ -1372,13 +1373,17 @@ static bool analyze_const_string(CodeGen *g, Scope *scope, AstNode *node, Buf ** assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray); ConstExprValue *array_val = ptr_field->data.x_ptr.data.base_array.array_val; + if (array_val->data.x_array.special == ConstArraySpecialBuf) { + *out_buffer = array_val->data.x_array.data.s_buf; + return true; + } expand_undef_array(g, array_val); size_t len = bigint_as_unsigned(&len_field->data.x_bigint); Buf *result = buf_alloc(); buf_resize(result, len); for (size_t i = 0; i < len; i += 1) { size_t new_index = ptr_field->data.x_ptr.data.base_array.elem_index + i; - ConstExprValue *char_val = &array_val->data.x_array.s_none.elements[new_index]; + ConstExprValue *char_val = &array_val->data.x_array.data.s_none.elements[new_index]; if (char_val->special == ConstValSpecialUndef) { add_node_error(g, node, buf_sprintf("use of undefined value")); return false; @@ -3093,9 +3098,10 @@ static void get_fully_qualified_decl_name(Buf *buf, Tld *tld, uint8_t sep) { buf_append_buf(buf, tld->name); } -ZigFn *create_fn_raw(FnInline inline_value) { +ZigFn *create_fn_raw(CodeGen *g, FnInline inline_value) { ZigFn *fn_entry = allocate<ZigFn>(1); + fn_entry->codegen = g; fn_entry->analyzed_executable.backward_branch_count = &fn_entry->prealloc_bbc; fn_entry->analyzed_executable.backward_branch_quota = default_backward_branch_quota; fn_entry->analyzed_executable.fn_entry = fn_entry; @@ -3105,12 +3111,12 @@ ZigFn *create_fn_raw(FnInline inline_value) { return fn_entry; } -ZigFn *create_fn(AstNode *proto_node) { +ZigFn *create_fn(CodeGen *g, AstNode *proto_node) { assert(proto_node->type == NodeTypeFnProto); AstNodeFnProto *fn_proto = &proto_node->data.fn_proto; FnInline inline_value = fn_proto->is_inline ? FnInlineAlways : FnInlineAuto; - ZigFn *fn_entry = create_fn_raw(inline_value); + ZigFn *fn_entry = create_fn_raw(g, inline_value); fn_entry->proto_node = proto_node; fn_entry->body_node = (proto_node->data.fn_proto.fn_def_node == nullptr) ? nullptr : @@ -3209,7 +3215,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { AstNode *fn_def_node = fn_proto->fn_def_node; - ZigFn *fn_table_entry = create_fn(source_node); + ZigFn *fn_table_entry = create_fn(g, source_node); get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, '_'); if (fn_proto->is_export) { @@ -3220,7 +3226,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { tld_fn->fn_entry = fn_table_entry; if (fn_table_entry->body_node) { - fn_table_entry->fndef_scope = create_fndef_scope( + fn_table_entry->fndef_scope = create_fndef_scope(g, fn_table_entry->body_node, tld_fn->base.parent_scope, fn_table_entry); for (size_t i = 0; i < fn_proto->params.length; i += 1) { @@ -3270,14 +3276,14 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { } } } else if (source_node->type == NodeTypeTestDecl) { - ZigFn *fn_table_entry = create_fn_raw(FnInlineAuto); + ZigFn *fn_table_entry = create_fn_raw(g, FnInlineAuto); get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, '_'); tld_fn->fn_entry = fn_table_entry; fn_table_entry->proto_node = source_node; - fn_table_entry->fndef_scope = create_fndef_scope(source_node, tld_fn->base.parent_scope, fn_table_entry); + fn_table_entry->fndef_scope = create_fndef_scope(g, source_node, tld_fn->base.parent_scope, fn_table_entry); fn_table_entry->type_entry = get_test_fn_type(g); fn_table_entry->body_node = source_node->data.test_decl.body; fn_table_entry->is_test = true; @@ -3606,7 +3612,7 @@ ZigVar *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf Scope *child_scope; if (source_node && source_node->type == NodeTypeParamDecl) { - child_scope = create_var_scope(source_node, parent_scope, variable_entry); + child_scope = create_var_scope(g, source_node, parent_scope, variable_entry); } else { // it's already in the decls table child_scope = parent_scope; @@ -4329,7 +4335,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *r g->import_table.put(resolved_path, import_entry); g->import_queue.append(import_entry); - import_entry->decls_scope = create_decls_scope(import_entry->root, nullptr, nullptr, import_entry); + import_entry->decls_scope = create_decls_scope(g, import_entry->root, nullptr, nullptr, import_entry); assert(import_entry->root->type == NodeTypeRoot); @@ -4880,7 +4886,7 @@ bool generic_fn_type_id_eql(GenericFnTypeId *a, GenericFnTypeId *b) { if (a_val->special != ConstValSpecialRuntime && b_val->special != ConstValSpecialRuntime) { assert(a_val->special == ConstValSpecialStatic); assert(b_val->special == ConstValSpecialStatic); - if (!const_values_equal(a_val, b_val)) { + if (!const_values_equal(a->fn_entry->codegen, a_val, b_val)) { return false; } } else { @@ -4920,14 +4926,18 @@ static bool can_mutate_comptime_var_state(ConstExprValue *value) { case ZigTypeIdArray: if (value->type->data.array.len == 0) return false; - if (value->data.x_array.special == ConstArraySpecialUndef) - return false; - for (uint32_t i = 0; i < value->type->data.array.len; i += 1) { - if (can_mutate_comptime_var_state(&value->data.x_array.s_none.elements[i])) - return true; + switch (value->data.x_array.special) { + case ConstArraySpecialUndef: + case ConstArraySpecialBuf: + return false; + case ConstArraySpecialNone: + for (uint32_t i = 0; i < value->type->data.array.len; i += 1) { + if (can_mutate_comptime_var_state(&value->data.x_array.data.s_none.elements[i])) + return true; + } + return false; } - return false; - + zig_unreachable(); case ZigTypeIdStruct: for (uint32_t i = 0; i < value->type->data.structure.src_field_count; i += 1) { if (can_mutate_comptime_var_state(&value->data.x_struct.fields[i])) @@ -5039,6 +5049,8 @@ uint32_t fn_eval_hash(Scope* scope) { } bool fn_eval_eql(Scope *a, Scope *b) { + assert(a->codegen != nullptr); + assert(b->codegen != nullptr); while (a && b) { if (a->id != b->id) return false; @@ -5048,7 +5060,7 @@ bool fn_eval_eql(Scope *a, Scope *b) { ScopeVarDecl *b_var_scope = (ScopeVarDecl *)b; if (a_var_scope->var->value->type != b_var_scope->var->value->type) return false; - if (!const_values_equal(a_var_scope->var->value, b_var_scope->var->value)) + if (!const_values_equal(a->codegen, a_var_scope->var->value, b_var_scope->var->value)) return false; } else if (a->id == ScopeIdFnDef) { ScopeFnDef *a_fn_scope = (ScopeFnDef *)a; @@ -5130,14 +5142,8 @@ void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) { const_val->special = ConstValSpecialStatic; const_val->type = get_array_type(g, g->builtin_types.entry_u8, buf_len(str)); - const_val->data.x_array.s_none.elements = create_const_vals(buf_len(str)); - - for (size_t i = 0; i < buf_len(str); i += 1) { - ConstExprValue *this_char = &const_val->data.x_array.s_none.elements[i]; - this_char->special = ConstValSpecialStatic; - this_char->type = g->builtin_types.entry_u8; - bigint_init_unsigned(&this_char->data.x_bigint, (uint8_t)buf_ptr(str)[i]); - } + const_val->data.x_array.special = ConstArraySpecialBuf; + const_val->data.x_array.data.s_buf = str; g->string_literals_table.put(str, const_val); } @@ -5154,14 +5160,15 @@ void init_const_c_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) { ConstExprValue *array_val = create_const_vals(1); array_val->special = ConstValSpecialStatic; array_val->type = get_array_type(g, g->builtin_types.entry_u8, len_with_null); - array_val->data.x_array.s_none.elements = create_const_vals(len_with_null); + // TODO buf optimization + array_val->data.x_array.data.s_none.elements = create_const_vals(len_with_null); for (size_t i = 0; i < buf_len(str); i += 1) { - ConstExprValue *this_char = &array_val->data.x_array.s_none.elements[i]; + ConstExprValue *this_char = &array_val->data.x_array.data.s_none.elements[i]; this_char->special = ConstValSpecialStatic; this_char->type = g->builtin_types.entry_u8; bigint_init_unsigned(&this_char->data.x_bigint, (uint8_t)buf_ptr(str)[i]); } - ConstExprValue *null_char = &array_val->data.x_array.s_none.elements[len_with_null - 1]; + ConstExprValue *null_char = &array_val->data.x_array.data.s_none.elements[len_with_null - 1]; null_char->special = ConstValSpecialStatic; null_char->type = g->builtin_types.entry_u8; bigint_init_unsigned(&null_char->data.x_bigint, 0); @@ -5535,7 +5542,7 @@ bool const_values_equal_ptr(ConstExprValue *a, ConstExprValue *b) { zig_unreachable(); } -bool const_values_equal(ConstExprValue *a, ConstExprValue *b) { +bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b) { assert(a->type->id == b->type->id); assert(a->special == ConstValSpecialStatic); assert(b->special == ConstValSpecialStatic); @@ -5593,13 +5600,20 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) { assert(a->type->data.array.len == b->type->data.array.len); assert(a->data.x_array.special != ConstArraySpecialUndef); assert(b->data.x_array.special != ConstArraySpecialUndef); + if (a->data.x_array.special == ConstArraySpecialBuf && + b->data.x_array.special == ConstArraySpecialBuf) + { + return buf_eql_buf(a->data.x_array.data.s_buf, b->data.x_array.data.s_buf); + } + expand_undef_array(g, a); + expand_undef_array(g, b); size_t len = a->type->data.array.len; - ConstExprValue *a_elems = a->data.x_array.s_none.elements; - ConstExprValue *b_elems = b->data.x_array.s_none.elements; + ConstExprValue *a_elems = a->data.x_array.data.s_none.elements; + ConstExprValue *b_elems = b->data.x_array.data.s_none.elements; for (size_t i = 0; i < len; ++i) { - if (!const_values_equal(&a_elems[i], &b_elems[i])) + if (!const_values_equal(g, &a_elems[i], &b_elems[i])) return false; } @@ -5609,7 +5623,7 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) { for (size_t i = 0; i < a->type->data.structure.src_field_count; i += 1) { ConstExprValue *field_a = &a->data.x_struct.fields[i]; ConstExprValue *field_b = &b->data.x_struct.fields[i]; - if (!const_values_equal(field_a, field_b)) + if (!const_values_equal(g, field_a, field_b)) return false; } return true; @@ -5623,7 +5637,7 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) { if (a->data.x_optional == nullptr || b->data.x_optional == nullptr) { return (a->data.x_optional == nullptr && b->data.x_optional == nullptr); } else { - return const_values_equal(a->data.x_optional, b->data.x_optional); + return const_values_equal(g, a->data.x_optional, b->data.x_optional); } case ZigTypeIdErrorUnion: zig_panic("TODO"); @@ -5808,26 +5822,15 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) { case ZigTypeIdPointer: return render_const_val_ptr(g, buf, const_val, type_entry); case ZigTypeIdArray: - { - ZigType *child_type = type_entry->data.array.child_type; - uint64_t len = type_entry->data.array.len; - - if (const_val->data.x_array.special == ConstArraySpecialUndef) { + switch (const_val->data.x_array.special) { + case ConstArraySpecialUndef: buf_append_str(buf, "undefined"); return; - } - - // if it's []u8, assume UTF-8 and output a string - if (child_type->id == ZigTypeIdInt && - child_type->data.integral.bit_count == 8 && - !child_type->data.integral.is_signed) - { + case ConstArraySpecialBuf: { + Buf *array_buf = const_val->data.x_array.data.s_buf; buf_append_char(buf, '"'); - for (uint64_t i = 0; i < len; i += 1) { - ConstExprValue *child_value = &const_val->data.x_array.s_none.elements[i]; - uint64_t big_c = bigint_as_unsigned(&child_value->data.x_bigint); - assert(big_c <= UINT8_MAX); - uint8_t c = (uint8_t)big_c; + for (size_t i = 0; i < buf_len(array_buf); i += 1) { + uint8_t c = buf_ptr(array_buf)[i]; if (c == '"') { buf_append_str(buf, "\\\""); } else { @@ -5837,17 +5840,20 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) { buf_append_char(buf, '"'); return; } - - buf_appendf(buf, "%s{", buf_ptr(&type_entry->name)); - for (uint64_t i = 0; i < len; i += 1) { - if (i != 0) - buf_appendf(buf, ","); - ConstExprValue *child_value = &const_val->data.x_array.s_none.elements[i]; - render_const_value(g, buf, child_value); + case ConstArraySpecialNone: { + buf_appendf(buf, "%s{", buf_ptr(&type_entry->name)); + uint64_t len = type_entry->data.array.len; + for (uint64_t i = 0; i < len; i += 1) { + if (i != 0) + buf_appendf(buf, ","); + ConstExprValue *child_value = &const_val->data.x_array.data.s_none.elements[i]; + render_const_value(g, buf, child_value); + } + buf_appendf(buf, "}"); + return; } - buf_appendf(buf, "}"); - return; } + zig_unreachable(); case ZigTypeIdNull: { buf_appendf(buf, "null"); @@ -6102,24 +6108,49 @@ bool zig_llvm_fn_key_eql(ZigLLVMFnKey a, ZigLLVMFnKey b) { zig_unreachable(); } +// Canonicalize the array value as ConstArraySpecialNone void expand_undef_array(CodeGen *g, ConstExprValue *const_val) { assert(const_val->type->id == ZigTypeIdArray); - if (const_val->data.x_array.special == ConstArraySpecialUndef) { - const_val->data.x_array.special = ConstArraySpecialNone; - size_t elem_count = const_val->type->data.array.len; - const_val->data.x_array.s_none.elements = create_const_vals(elem_count); - for (size_t i = 0; i < elem_count; i += 1) { - ConstExprValue *element_val = &const_val->data.x_array.s_none.elements[i]; - element_val->type = const_val->type->data.array.child_type; - init_const_undefined(g, element_val); - ConstParent *parent = get_const_val_parent(g, element_val); - if (parent != nullptr) { - parent->id = ConstParentIdArray; - parent->data.p_array.array_val = const_val; - parent->data.p_array.elem_index = i; + switch (const_val->data.x_array.special) { + case ConstArraySpecialNone: + return; + case ConstArraySpecialUndef: { + const_val->data.x_array.special = ConstArraySpecialNone; + size_t elem_count = const_val->type->data.array.len; + const_val->data.x_array.data.s_none.elements = create_const_vals(elem_count); + for (size_t i = 0; i < elem_count; i += 1) { + ConstExprValue *element_val = &const_val->data.x_array.data.s_none.elements[i]; + element_val->type = const_val->type->data.array.child_type; + init_const_undefined(g, element_val); + ConstParent *parent = get_const_val_parent(g, element_val); + if (parent != nullptr) { + parent->id = ConstParentIdArray; + parent->data.p_array.array_val = const_val; + parent->data.p_array.elem_index = i; + } } + return; + } + case ConstArraySpecialBuf: { + Buf *buf = const_val->data.x_array.data.s_buf; + // If we're doing this it means that we are potentially modifying the data, + // so we can't have it be in the string literals table + g->string_literals_table.maybe_remove(buf); + + const_val->data.x_array.special = ConstArraySpecialNone; + size_t elem_count = const_val->type->data.array.len; + assert(elem_count == buf_len(buf)); + const_val->data.x_array.data.s_none.elements = create_const_vals(elem_count); + for (size_t i = 0; i < elem_count; i += 1) { + ConstExprValue *this_char = &const_val->data.x_array.data.s_none.elements[i]; + this_char->special = ConstValSpecialStatic; + this_char->type = g->builtin_types.entry_u8; + bigint_init_unsigned(&this_char->data.x_bigint, (uint8_t)buf_ptr(buf)[i]); + } + return; } } + zig_unreachable(); } ConstParent *get_const_val_parent(CodeGen *g, ConstExprValue *value) { @@ -6127,7 +6158,7 @@ ConstParent *get_const_val_parent(CodeGen *g, ConstExprValue *value) { ZigType *type_entry = value->type; if (type_entry->id == ZigTypeIdArray) { expand_undef_array(g, value); - return &value->data.x_array.s_none.parent; + return &value->data.x_array.data.s_none.parent; } else if (type_entry->id == ZigTypeIdStruct) { return &value->data.x_struct.parent; } else if (type_entry->id == ZigTypeIdUnion) { diff --git a/src/analyze.hpp b/src/analyze.hpp index bcc02d1a42..b04cf6fdfd 100644 --- a/src/analyze.hpp +++ b/src/analyze.hpp @@ -84,8 +84,8 @@ void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source ZigVar *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf *name, bool is_const, ConstExprValue *init_value, Tld *src_tld); ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node); -ZigFn *create_fn(AstNode *proto_node); -ZigFn *create_fn_raw(FnInline inline_value, GlobalLinkageId linkage); +ZigFn *create_fn(CodeGen *g, AstNode *proto_node); +ZigFn *create_fn_raw(CodeGen *g, FnInline inline_value); void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, size_t param_count_alloc); AstNode *get_param_decl_node(ZigFn *fn_entry, size_t index); bool type_requires_comptime(ZigType *type_entry); @@ -93,25 +93,25 @@ Error ATTRIBUTE_MUST_USE ensure_complete_type(CodeGen *g, ZigType *type_entry); Error ATTRIBUTE_MUST_USE type_resolve(CodeGen *g, ZigType *type_entry, ResolveStatus status); void complete_enum(CodeGen *g, ZigType *enum_type); bool ir_get_var_is_comptime(ZigVar *var); -bool const_values_equal(ConstExprValue *a, ConstExprValue *b); +bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b); void eval_min_max_value(CodeGen *g, ZigType *type_entry, ConstExprValue *const_val, bool is_max); void eval_min_max_value_int(CodeGen *g, ZigType *int_type, BigInt *bigint, bool is_max); void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val); void analyze_fn_ir(CodeGen *g, ZigFn *fn_table_entry, AstNode *return_type_node); -ScopeBlock *create_block_scope(AstNode *node, Scope *parent); -ScopeDefer *create_defer_scope(AstNode *node, Scope *parent); -ScopeDeferExpr *create_defer_expr_scope(AstNode *node, Scope *parent); -Scope *create_var_scope(AstNode *node, Scope *parent, ZigVar *var); -ScopeCImport *create_cimport_scope(AstNode *node, Scope *parent); -ScopeLoop *create_loop_scope(AstNode *node, Scope *parent); -ScopeSuspend *create_suspend_scope(AstNode *node, Scope *parent); -ScopeFnDef *create_fndef_scope(AstNode *node, Scope *parent, ZigFn *fn_entry); -ScopeDecls *create_decls_scope(AstNode *node, Scope *parent, ZigType *container_type, ImportTableEntry *import); -Scope *create_comptime_scope(AstNode *node, Scope *parent); -Scope *create_coro_prelude_scope(AstNode *node, Scope *parent); -Scope *create_runtime_scope(AstNode *node, Scope *parent, IrInstruction *is_comptime); +ScopeBlock *create_block_scope(CodeGen *g, AstNode *node, Scope *parent); +ScopeDefer *create_defer_scope(CodeGen *g, AstNode *node, Scope *parent); +ScopeDeferExpr *create_defer_expr_scope(CodeGen *g, AstNode *node, Scope *parent); +Scope *create_var_scope(CodeGen *g, AstNode *node, Scope *parent, ZigVar *var); +ScopeCImport *create_cimport_scope(CodeGen *g, AstNode *node, Scope *parent); +ScopeLoop *create_loop_scope(CodeGen *g, AstNode *node, Scope *parent); +ScopeSuspend *create_suspend_scope(CodeGen *g, AstNode *node, Scope *parent); +ScopeFnDef *create_fndef_scope(CodeGen *g, AstNode *node, Scope *parent, ZigFn *fn_entry); +ScopeDecls *create_decls_scope(CodeGen *g, AstNode *node, Scope *parent, ZigType *container_type, ImportTableEntry *import); +Scope *create_comptime_scope(CodeGen *g, AstNode *node, Scope *parent); +Scope *create_coro_prelude_scope(CodeGen *g, AstNode *node, Scope *parent); +Scope *create_runtime_scope(CodeGen *g, AstNode *node, Scope *parent, IrInstruction *is_comptime); void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str); ConstExprValue *create_const_str_lit(CodeGen *g, Buf *str); diff --git a/src/codegen.cpp b/src/codegen.cpp index 91e7c8dde9..6c4b54261c 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -5336,7 +5336,7 @@ static LLVMValueRef gen_parent_ptr(CodeGen *g, ConstExprValue *val, ConstParent static LLVMValueRef gen_const_ptr_array_recursive(CodeGen *g, ConstExprValue *array_const_val, size_t index) { expand_undef_array(g, array_const_val); - ConstParent *parent = &array_const_val->data.x_array.s_none.parent; + ConstParent *parent = &array_const_val->data.x_array.data.s_none.parent; LLVMValueRef base_ptr = gen_parent_ptr(g, array_const_val, parent); LLVMTypeKind el_type = LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(base_ptr))); @@ -5716,23 +5716,29 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c case ZigTypeIdArray: { uint64_t len = type_entry->data.array.len; - if (const_val->data.x_array.special == ConstArraySpecialUndef) { - return LLVMGetUndef(type_entry->type_ref); - } - - LLVMValueRef *values = allocate<LLVMValueRef>(len); - LLVMTypeRef element_type_ref = type_entry->data.array.child_type->type_ref; - bool make_unnamed_struct = false; - for (uint64_t i = 0; i < len; i += 1) { - ConstExprValue *elem_value = &const_val->data.x_array.s_none.elements[i]; - LLVMValueRef val = gen_const_val(g, elem_value, ""); - values[i] = val; - make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(elem_value->type, val); - } - if (make_unnamed_struct) { - return LLVMConstStruct(values, len, true); - } else { - return LLVMConstArray(element_type_ref, values, (unsigned)len); + switch (const_val->data.x_array.special) { + case ConstArraySpecialUndef: + return LLVMGetUndef(type_entry->type_ref); + case ConstArraySpecialNone: { + LLVMValueRef *values = allocate<LLVMValueRef>(len); + LLVMTypeRef element_type_ref = type_entry->data.array.child_type->type_ref; + bool make_unnamed_struct = false; + for (uint64_t i = 0; i < len; i += 1) { + ConstExprValue *elem_value = &const_val->data.x_array.data.s_none.elements[i]; + LLVMValueRef val = gen_const_val(g, elem_value, ""); + values[i] = val; + make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(elem_value->type, val); + } + if (make_unnamed_struct) { + return LLVMConstStruct(values, len, true); + } else { + return LLVMConstArray(element_type_ref, values, (unsigned)len); + } + } + case ConstArraySpecialBuf: { + Buf *buf = const_val->data.x_array.data.s_buf; + return LLVMConstString(buf_ptr(buf), (unsigned)buf_len(buf), true); + } } } case ZigTypeIdUnion: @@ -7278,7 +7284,7 @@ void codegen_translate_c(CodeGen *g, Buf *full_path) { import->source_code = nullptr; import->path = full_path; g->root_import = import; - import->decls_scope = create_decls_scope(nullptr, nullptr, nullptr, import); + import->decls_scope = create_decls_scope(g, nullptr, nullptr, nullptr, import); init(g); @@ -7352,12 +7358,12 @@ static void create_test_compile_var_and_add_test_runner(CodeGen *g) { ConstExprValue *test_fn_array = create_const_vals(1); test_fn_array->type = get_array_type(g, struct_type, g->test_fns.length); test_fn_array->special = ConstValSpecialStatic; - test_fn_array->data.x_array.s_none.elements = create_const_vals(g->test_fns.length); + test_fn_array->data.x_array.data.s_none.elements = create_const_vals(g->test_fns.length); for (size_t i = 0; i < g->test_fns.length; i += 1) { ZigFn *test_fn_entry = g->test_fns.at(i); - ConstExprValue *this_val = &test_fn_array->data.x_array.s_none.elements[i]; + ConstExprValue *this_val = &test_fn_array->data.x_array.data.s_none.elements[i]; this_val->special = ConstValSpecialStatic; this_val->type = struct_type; this_val->data.x_struct.parent.id = ConstParentIdArray; diff --git a/src/ir.cpp b/src/ir.cpp index 7b2ae30a79..79596d1d91 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -166,7 +166,7 @@ static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *c break; case ConstPtrSpecialBaseArray: expand_undef_array(g, const_val->data.x_ptr.data.base_array.array_val); - result = &const_val->data.x_ptr.data.base_array.array_val->data.x_array.s_none.elements[ + result = &const_val->data.x_ptr.data.base_array.array_val->data.x_array.data.s_none.elements[ const_val->data.x_ptr.data.base_array.elem_index]; break; case ConstPtrSpecialBaseStruct: @@ -3360,7 +3360,7 @@ static ZigVar *create_local_var(CodeGen *codegen, AstNode *node, Scope *parent_s variable_entry->src_is_const = src_is_const; variable_entry->gen_is_const = gen_is_const; variable_entry->decl_node = node; - variable_entry->child_scope = create_var_scope(node, parent_scope, variable_entry); + variable_entry->child_scope = create_var_scope(codegen, node, parent_scope, variable_entry); return variable_entry; } @@ -3388,7 +3388,7 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode ZigList<IrInstruction *> incoming_values = {0}; ZigList<IrBasicBlock *> incoming_blocks = {0}; - ScopeBlock *scope_block = create_block_scope(block_node, parent_scope); + ScopeBlock *scope_block = create_block_scope(irb->codegen, block_node, parent_scope); Scope *outer_block_scope = &scope_block->base; Scope *child_scope = outer_block_scope; @@ -5026,7 +5026,7 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode ir_set_cursor_at_end_and_append_block(irb, then_block); - Scope *subexpr_scope = create_runtime_scope(node, scope, is_comptime); + Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); IrInstruction *then_expr_result = ir_gen_node(irb, then_node, subexpr_scope); if (then_expr_result == irb->codegen->invalid_instruction) return then_expr_result; @@ -5318,7 +5318,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n ir_should_inline(irb->exec, scope) || node->data.while_expr.is_inline); ir_build_br(irb, scope, node, cond_block, is_comptime); - Scope *subexpr_scope = create_runtime_scope(node, scope, is_comptime); + Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); Buf *var_symbol = node->data.while_expr.var_symbol; Buf *err_symbol = node->data.while_expr.err_symbol; if (err_symbol != nullptr) { @@ -5359,7 +5359,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n ZigList<IrInstruction *> incoming_values = {0}; ZigList<IrBasicBlock *> incoming_blocks = {0}; - ScopeLoop *loop_scope = create_loop_scope(node, payload_scope); + ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, payload_scope); loop_scope->break_block = end_block; loop_scope->continue_block = continue_block; loop_scope->is_comptime = is_comptime; @@ -5415,7 +5415,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); } else if (var_symbol != nullptr) { ir_set_cursor_at_end_and_append_block(irb, cond_block); - Scope *subexpr_scope = create_runtime_scope(node, scope, is_comptime); + Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); // TODO make it an error to write to payload variable AstNode *symbol_node = node; // TODO make more accurate @@ -5443,7 +5443,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n ZigList<IrInstruction *> incoming_values = {0}; ZigList<IrBasicBlock *> incoming_blocks = {0}; - ScopeLoop *loop_scope = create_loop_scope(node, child_scope); + ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, child_scope); loop_scope->break_block = end_block; loop_scope->continue_block = continue_block; loop_scope->is_comptime = is_comptime; @@ -5506,9 +5506,9 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n ZigList<IrInstruction *> incoming_values = {0}; ZigList<IrBasicBlock *> incoming_blocks = {0}; - Scope *subexpr_scope = create_runtime_scope(node, scope, is_comptime); + Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); - ScopeLoop *loop_scope = create_loop_scope(node, subexpr_scope); + ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, subexpr_scope); loop_scope->break_block = end_block; loop_scope->continue_block = continue_block; loop_scope->is_comptime = is_comptime; @@ -5645,7 +5645,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo ZigList<IrInstruction *> incoming_values = {0}; ZigList<IrBasicBlock *> incoming_blocks = {0}; - ScopeLoop *loop_scope = create_loop_scope(node, child_scope); + ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, child_scope); loop_scope->break_block = end_block; loop_scope->continue_block = continue_block; loop_scope->is_comptime = is_comptime; @@ -5855,7 +5855,7 @@ static IrInstruction *ir_gen_test_expr(IrBuilder *irb, Scope *scope, AstNode *no ir_set_cursor_at_end_and_append_block(irb, then_block); - Scope *subexpr_scope = create_runtime_scope(node, scope, is_comptime); + Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); Scope *var_scope; if (var_symbol) { IrInstruction *var_type = nullptr; @@ -5930,7 +5930,7 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * ir_set_cursor_at_end_and_append_block(irb, ok_block); - Scope *subexpr_scope = create_runtime_scope(node, scope, is_comptime); + Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); Scope *var_scope; if (var_symbol) { IrInstruction *var_type = nullptr; @@ -6066,8 +6066,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * ZigList<IrInstructionCheckSwitchProngsRange> check_ranges = {0}; // First do the else and the ranges - Scope *subexpr_scope = create_runtime_scope(node, scope, is_comptime); - Scope *comptime_scope = create_comptime_scope(node, scope); + Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); + Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope); AstNode *else_prong = nullptr; for (size_t prong_i = 0; prong_i < prong_count; prong_i += 1) { AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i); @@ -6231,7 +6231,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * static IrInstruction *ir_gen_comptime(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval) { assert(node->type == NodeTypeCompTime); - Scope *child_scope = create_comptime_scope(node, parent_scope); + Scope *child_scope = create_comptime_scope(irb->codegen, node, parent_scope); return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval); } @@ -6394,10 +6394,10 @@ static IrInstruction *ir_gen_error_type(IrBuilder *irb, Scope *scope, AstNode *n static IrInstruction *ir_gen_defer(IrBuilder *irb, Scope *parent_scope, AstNode *node) { assert(node->type == NodeTypeDefer); - ScopeDefer *defer_child_scope = create_defer_scope(node, parent_scope); + ScopeDefer *defer_child_scope = create_defer_scope(irb->codegen, node, parent_scope); node->data.defer.child_scope = &defer_child_scope->base; - ScopeDeferExpr *defer_expr_scope = create_defer_expr_scope(node, parent_scope); + ScopeDeferExpr *defer_expr_scope = create_defer_expr_scope(irb->codegen, node, parent_scope); node->data.defer.expr_scope = &defer_expr_scope->base; return ir_build_const_void(irb, parent_scope, node); @@ -7154,7 +7154,7 @@ static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNod suspend_code = ir_build_coro_suspend(irb, parent_scope, node, nullptr, const_bool_false); } else { Scope *child_scope; - ScopeSuspend *suspend_scope = create_suspend_scope(node, parent_scope); + ScopeSuspend *suspend_scope = create_suspend_scope(irb->codegen, node, parent_scope); suspend_scope->resume_block = resume_block; child_scope = &suspend_scope->base; IrInstruction *save_token = ir_build_coro_save(irb, child_scope, node, irb->exec->coro_handle); @@ -7370,7 +7370,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec ZigVar *coro_size_var; if (is_async) { // create the coro promise - Scope *coro_scope = create_coro_prelude_scope(node, scope); + Scope *coro_scope = create_coro_prelude_scope(irb->codegen, node, scope); const_bool_false = ir_build_const_bool(irb, coro_scope, node, false); ZigVar *promise_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false); @@ -10569,9 +10569,9 @@ static IrInstruction *ir_analyze_ptr_to_array(IrAnalyze *ira, IrInstruction *sou array_val->special = ConstValSpecialStatic; array_val->type = array_type; array_val->data.x_array.special = ConstArraySpecialNone; - array_val->data.x_array.s_none.elements = pointee; - array_val->data.x_array.s_none.parent.id = ConstParentIdScalar; - array_val->data.x_array.s_none.parent.data.p_scalar.scalar_val = pointee; + array_val->data.x_array.data.s_none.elements = pointee; + array_val->data.x_array.data.s_none.parent.id = ConstParentIdScalar; + array_val->data.x_array.data.s_none.parent.data.p_scalar.scalar_val = pointee; IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, source_instr->scope, source_instr->source_node); @@ -11391,13 +11391,16 @@ static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) { assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray); ConstExprValue *array_val = ptr_field->data.x_ptr.data.base_array.array_val; + if (array_val->data.x_array.special == ConstArraySpecialBuf) { + return array_val->data.x_array.data.s_buf; + } expand_undef_array(ira->codegen, array_val); size_t len = bigint_as_unsigned(&len_field->data.x_bigint); Buf *result = buf_alloc(); buf_resize(result, len); for (size_t i = 0; i < len; i += 1) { size_t new_index = ptr_field->data.x_ptr.data.base_array.elem_index + i; - ConstExprValue *char_val = &array_val->data.x_array.s_none.elements[new_index]; + ConstExprValue *char_val = &array_val->data.x_array.data.s_none.elements[new_index]; if (char_val->special == ConstValSpecialUndef) { ir_add_error(ira, casted_value, buf_sprintf("use of undefined value")); return nullptr; @@ -11750,7 +11753,7 @@ static ZigType *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *bin_op Cmp cmp_result = bigint_cmp(&op1_val->data.x_bigint, &op2_val->data.x_bigint); answer = resolve_cmp_op_id(op_id, cmp_result); } else { - bool are_equal = one_possible_value || const_values_equal(op1_val, op2_val); + bool are_equal = one_possible_value || const_values_equal(ira->codegen, op1_val, op2_val); if (op_id == IrBinOpCmpEq) { answer = are_equal; } else if (op_id == IrBinOpCmpNotEq) { @@ -12463,19 +12466,20 @@ static ZigType *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *instruc return result_type; } - out_array_val->data.x_array.s_none.elements = create_const_vals(new_len); + out_array_val->data.x_array.data.s_none.elements = create_const_vals(new_len); + // TODO handle the buf case here for an optimization expand_undef_array(ira->codegen, op1_array_val); expand_undef_array(ira->codegen, op2_array_val); size_t next_index = 0; for (size_t i = op1_array_index; i < op1_array_end; i += 1, next_index += 1) { - out_array_val->data.x_array.s_none.elements[next_index] = op1_array_val->data.x_array.s_none.elements[i]; + out_array_val->data.x_array.data.s_none.elements[next_index] = op1_array_val->data.x_array.data.s_none.elements[i]; } for (size_t i = op2_array_index; i < op2_array_end; i += 1, next_index += 1) { - out_array_val->data.x_array.s_none.elements[next_index] = op2_array_val->data.x_array.s_none.elements[i]; + out_array_val->data.x_array.data.s_none.elements[next_index] = op2_array_val->data.x_array.data.s_none.elements[i]; } if (next_index < new_len) { - ConstExprValue *null_byte = &out_array_val->data.x_array.s_none.elements[next_index]; + ConstExprValue *null_byte = &out_array_val->data.x_array.data.s_none.elements[next_index]; init_const_unsigned_negative(null_byte, child_type, 0, false); next_index += 1; } @@ -12524,12 +12528,14 @@ static ZigType *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp *instru return get_array_type(ira->codegen, child_type, new_array_len); } - out_val->data.x_array.s_none.elements = create_const_vals(new_array_len); + // TODO optimize the buf case + expand_undef_array(ira->codegen, array_val); + out_val->data.x_array.data.s_none.elements = create_const_vals(new_array_len); uint64_t i = 0; for (uint64_t x = 0; x < mult_amt; x += 1) { for (uint64_t y = 0; y < old_array_len; y += 1) { - out_val->data.x_array.s_none.elements[i] = array_val->data.x_array.s_none.elements[y]; + out_val->data.x_array.data.s_none.elements[i] = array_val->data.x_array.data.s_none.elements[y]; i += 1; } } @@ -13502,10 +13508,10 @@ static ZigType *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call_instr // Fork a scope of the function with known values for the parameters. Scope *parent_scope = fn_entry->fndef_scope->base.parent; - ZigFn *impl_fn = create_fn(fn_proto_node); + ZigFn *impl_fn = create_fn(ira->codegen, fn_proto_node); impl_fn->param_source_nodes = allocate<AstNode *>(new_fn_arg_count); buf_init_from_buf(&impl_fn->symbol_name, &fn_entry->symbol_name); - impl_fn->fndef_scope = create_fndef_scope(impl_fn->body_node, parent_scope, impl_fn); + impl_fn->fndef_scope = create_fndef_scope(ira->codegen, impl_fn->body_node, parent_scope, impl_fn); impl_fn->child_scope = &impl_fn->fndef_scope->base; FnTypeId inst_fn_type_id = {0}; init_fn_type_id(&inst_fn_type_id, fn_proto_node, new_fn_arg_count); @@ -16073,7 +16079,7 @@ static ZigType *ir_analyze_instruction_switch_br(IrAnalyze *ira, if (!case_val) return ir_unreach_error(ira); - if (const_values_equal(target_val, case_val)) { + if (const_values_equal(ira->codegen, target_val, case_val)) { old_dest_block = old_case->block; break; } @@ -16652,7 +16658,7 @@ static ZigType *ir_analyze_instruction_container_init_list(IrAnalyze *ira, ConstExprValue const_val = {}; const_val.special = ConstValSpecialStatic; const_val.type = fixed_size_array_type; - const_val.data.x_array.s_none.elements = create_const_vals(elem_count); + const_val.data.x_array.data.s_none.elements = create_const_vals(elem_count); bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->base.scope); @@ -16677,7 +16683,7 @@ static ZigType *ir_analyze_instruction_container_init_list(IrAnalyze *ira, if (!elem_val) return ira->codegen->builtin_types.entry_invalid; - copy_const_val(&const_val.data.x_array.s_none.elements[i], elem_val, true); + copy_const_val(&const_val.data.x_array.data.s_none.elements[i], elem_val, true); } else { first_non_const_instruction = casted_arg; const_val.special = ConstValSpecialRuntime; @@ -16689,7 +16695,7 @@ static ZigType *ir_analyze_instruction_container_init_list(IrAnalyze *ira, ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); *out_val = const_val; for (size_t i = 0; i < elem_count; i += 1) { - ConstExprValue *elem_val = &out_val->data.x_array.s_none.elements[i]; + ConstExprValue *elem_val = &out_val->data.x_array.data.s_none.elements[i]; ConstParent *parent = get_const_val_parent(ira->codegen, elem_val); if (parent != nullptr) { parent->id = ConstParentIdArray; @@ -17146,8 +17152,8 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Sco definition_array->special = ConstValSpecialStatic; definition_array->type = get_array_type(ira->codegen, type_info_definition_type, definition_count); definition_array->data.x_array.special = ConstArraySpecialNone; - definition_array->data.x_array.s_none.parent.id = ConstParentIdNone; - definition_array->data.x_array.s_none.elements = create_const_vals(definition_count); + definition_array->data.x_array.data.s_none.parent.id = ConstParentIdNone; + definition_array->data.x_array.data.s_none.elements = create_const_vals(definition_count); init_const_slice(ira->codegen, out_val, definition_array, 0, definition_count, false); // Loop through the definitions and generate info. @@ -17164,7 +17170,7 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Sco continue; } - ConstExprValue *definition_val = &definition_array->data.x_array.s_none.elements[definition_index]; + ConstExprValue *definition_val = &definition_array->data.x_array.data.s_none.elements[definition_index]; definition_val->special = ConstValSpecialStatic; definition_val->type = type_info_definition_type; @@ -17293,15 +17299,15 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Sco fn_arg_name_array->type = get_array_type(ira->codegen, get_slice_type(ira->codegen, u8_ptr), fn_arg_count); fn_arg_name_array->data.x_array.special = ConstArraySpecialNone; - fn_arg_name_array->data.x_array.s_none.parent.id = ConstParentIdNone; - fn_arg_name_array->data.x_array.s_none.elements = create_const_vals(fn_arg_count); + fn_arg_name_array->data.x_array.data.s_none.parent.id = ConstParentIdNone; + fn_arg_name_array->data.x_array.data.s_none.elements = create_const_vals(fn_arg_count); init_const_slice(ira->codegen, &fn_def_fields[8], fn_arg_name_array, 0, fn_arg_count, false); for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) { ZigVar *arg_var = fn_entry->variable_list.at(fn_arg_index); - ConstExprValue *fn_arg_name_val = &fn_arg_name_array->data.x_array.s_none.elements[fn_arg_index]; + ConstExprValue *fn_arg_name_val = &fn_arg_name_array->data.x_array.data.s_none.elements[fn_arg_index]; ConstExprValue *arg_name = create_const_str_lit(ira->codegen, &arg_var->name); init_const_slice(ira->codegen, fn_arg_name_val, arg_name, 0, buf_len(&arg_var->name), true); fn_arg_name_val->data.x_struct.parent.id = ConstParentIdArray; @@ -17593,15 +17599,15 @@ static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstE enum_field_array->special = ConstValSpecialStatic; enum_field_array->type = get_array_type(ira->codegen, type_info_enum_field_type, enum_field_count); enum_field_array->data.x_array.special = ConstArraySpecialNone; - enum_field_array->data.x_array.s_none.parent.id = ConstParentIdNone; - enum_field_array->data.x_array.s_none.elements = create_const_vals(enum_field_count); + enum_field_array->data.x_array.data.s_none.parent.id = ConstParentIdNone; + enum_field_array->data.x_array.data.s_none.elements = create_const_vals(enum_field_count); init_const_slice(ira->codegen, &fields[2], enum_field_array, 0, enum_field_count, false); for (uint32_t enum_field_index = 0; enum_field_index < enum_field_count; enum_field_index++) { TypeEnumField *enum_field = &type_entry->data.enumeration.fields[enum_field_index]; - ConstExprValue *enum_field_val = &enum_field_array->data.x_array.s_none.elements[enum_field_index]; + ConstExprValue *enum_field_val = &enum_field_array->data.x_array.data.s_none.elements[enum_field_index]; make_enum_field_val(ira, enum_field_val, enum_field, type_info_enum_field_type); enum_field_val->data.x_struct.parent.id = ConstParentIdArray; enum_field_val->data.x_struct.parent.data.p_array.array_val = enum_field_array; @@ -17632,13 +17638,13 @@ static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstE error_array->special = ConstValSpecialStatic; error_array->type = get_array_type(ira->codegen, type_info_error_type, error_count); error_array->data.x_array.special = ConstArraySpecialNone; - error_array->data.x_array.s_none.parent.id = ConstParentIdNone; - error_array->data.x_array.s_none.elements = create_const_vals(error_count); + error_array->data.x_array.data.s_none.parent.id = ConstParentIdNone; + error_array->data.x_array.data.s_none.elements = create_const_vals(error_count); init_const_slice(ira->codegen, &fields[0], error_array, 0, error_count, false); for (uint32_t error_index = 0; error_index < error_count; error_index++) { ErrorTableEntry *error = type_entry->data.error_set.errors[error_index]; - ConstExprValue *error_val = &error_array->data.x_array.s_none.elements[error_index]; + ConstExprValue *error_val = &error_array->data.x_array.data.s_none.elements[error_index]; error_val->special = ConstValSpecialStatic; error_val->type = type_info_error_type; @@ -17727,8 +17733,8 @@ static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstE union_field_array->special = ConstValSpecialStatic; union_field_array->type = get_array_type(ira->codegen, type_info_union_field_type, union_field_count); union_field_array->data.x_array.special = ConstArraySpecialNone; - union_field_array->data.x_array.s_none.parent.id = ConstParentIdNone; - union_field_array->data.x_array.s_none.elements = create_const_vals(union_field_count); + union_field_array->data.x_array.data.s_none.parent.id = ConstParentIdNone; + union_field_array->data.x_array.data.s_none.elements = create_const_vals(union_field_count); init_const_slice(ira->codegen, &fields[2], union_field_array, 0, union_field_count, false); @@ -17736,7 +17742,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstE for (uint32_t union_field_index = 0; union_field_index < union_field_count; union_field_index++) { TypeUnionField *union_field = &type_entry->data.unionation.fields[union_field_index]; - ConstExprValue *union_field_val = &union_field_array->data.x_array.s_none.elements[union_field_index]; + ConstExprValue *union_field_val = &union_field_array->data.x_array.data.s_none.elements[union_field_index]; union_field_val->special = ConstValSpecialStatic; union_field_val->type = type_info_union_field_type; @@ -17800,14 +17806,14 @@ static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstE struct_field_array->special = ConstValSpecialStatic; struct_field_array->type = get_array_type(ira->codegen, type_info_struct_field_type, struct_field_count); struct_field_array->data.x_array.special = ConstArraySpecialNone; - struct_field_array->data.x_array.s_none.parent.id = ConstParentIdNone; - struct_field_array->data.x_array.s_none.elements = create_const_vals(struct_field_count); + struct_field_array->data.x_array.data.s_none.parent.id = ConstParentIdNone; + struct_field_array->data.x_array.data.s_none.elements = create_const_vals(struct_field_count); init_const_slice(ira->codegen, &fields[1], struct_field_array, 0, struct_field_count, false); for (uint32_t struct_field_index = 0; struct_field_index < struct_field_count; struct_field_index++) { TypeStructField *struct_field = &type_entry->data.structure.fields[struct_field_index]; - ConstExprValue *struct_field_val = &struct_field_array->data.x_array.s_none.elements[struct_field_index]; + ConstExprValue *struct_field_val = &struct_field_array->data.x_array.data.s_none.elements[struct_field_index]; struct_field_val->special = ConstValSpecialStatic; struct_field_val->type = type_info_struct_field_type; @@ -17906,15 +17912,15 @@ static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstE fn_arg_array->special = ConstValSpecialStatic; fn_arg_array->type = get_array_type(ira->codegen, type_info_fn_arg_type, fn_arg_count); fn_arg_array->data.x_array.special = ConstArraySpecialNone; - fn_arg_array->data.x_array.s_none.parent.id = ConstParentIdNone; - fn_arg_array->data.x_array.s_none.elements = create_const_vals(fn_arg_count); + fn_arg_array->data.x_array.data.s_none.parent.id = ConstParentIdNone; + fn_arg_array->data.x_array.data.s_none.elements = create_const_vals(fn_arg_count); init_const_slice(ira->codegen, &fields[5], fn_arg_array, 0, fn_arg_count, false); for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) { FnTypeParamInfo *fn_param_info = &type_entry->data.fn.fn_type_id.param_info[fn_arg_index]; - ConstExprValue *fn_arg_val = &fn_arg_array->data.x_array.s_none.elements[fn_arg_index]; + ConstExprValue *fn_arg_val = &fn_arg_array->data.x_array.data.s_none.elements[fn_arg_index]; fn_arg_val->special = ConstValSpecialStatic; fn_arg_val->type = type_info_fn_arg_type; @@ -18059,7 +18065,7 @@ static ZigType *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstructionCIm assert(node->type == NodeTypeFnCallExpr); AstNode *block_node = node->data.fn_call_expr.params.at(0); - ScopeCImport *cimport_scope = create_cimport_scope(node, instruction->base.scope); + ScopeCImport *cimport_scope = create_cimport_scope(ira->codegen, node, instruction->base.scope); // Execute the C import block like an inline function ZigType *void_type = ira->codegen->builtin_types.entry_void; @@ -18072,7 +18078,7 @@ static ZigType *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstructionCIm find_libc_include_path(ira->codegen); ImportTableEntry *child_import = allocate<ImportTableEntry>(1); - child_import->decls_scope = create_decls_scope(node, nullptr, nullptr, child_import); + child_import->decls_scope = create_decls_scope(ira->codegen, node, nullptr, nullptr, child_import); child_import->c_import_node = node; child_import->package = new_anonymous_package(); child_import->package->package_table.put(buf_create_from_str("builtin"), ira->codegen->compile_var_package); @@ -18826,7 +18832,7 @@ static ZigType *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructionMemse { ConstExprValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val; expand_undef_array(ira->codegen, array_val); - dest_elements = array_val->data.x_array.s_none.elements; + dest_elements = array_val->data.x_array.data.s_none.elements; start = dest_ptr_val->data.x_ptr.data.base_array.elem_index; bound_end = array_val->type->data.array.len; break; @@ -18940,7 +18946,7 @@ static ZigType *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructionMemcp { ConstExprValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val; expand_undef_array(ira->codegen, array_val); - dest_elements = array_val->data.x_array.s_none.elements; + dest_elements = array_val->data.x_array.data.s_none.elements; dest_start = dest_ptr_val->data.x_ptr.data.base_array.elem_index; dest_end = array_val->type->data.array.len; break; @@ -18976,7 +18982,7 @@ static ZigType *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructionMemcp { ConstExprValue *array_val = src_ptr_val->data.x_ptr.data.base_array.array_val; expand_undef_array(ira->codegen, array_val); - src_elements = array_val->data.x_array.s_none.elements; + src_elements = array_val->data.x_array.data.s_none.elements; src_start = src_ptr_val->data.x_ptr.data.base_array.elem_index; src_end = array_val->type->data.array.len; break; @@ -20282,9 +20288,10 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue case ZigTypeIdArray: { size_t buf_i = 0; + // TODO optimize the buf case expand_undef_array(codegen, val); for (size_t elem_i = 0; elem_i < val->type->data.array.len; elem_i += 1) { - ConstExprValue *elem = &val->data.x_array.s_none.elements[elem_i]; + ConstExprValue *elem = &val->data.x_array.data.s_none.elements[elem_i]; buf_write_value_bytes(codegen, &buf[buf_i], elem); buf_i += type_size(codegen, elem->type); } |
