Skip to content

Commit 8460d56

Browse files
committed
introduce lazy values
see #2174
1 parent efdbede commit 8460d56

File tree

7 files changed

+320
-136
lines changed

7 files changed

+320
-136
lines changed

BRANCH_TODO

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
* slice type and ptr type instructions need to implicit cast alignment
2+
* fix regressions of error notes with "called from here"
3+
* fix tests

src/all_types.hpp

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ struct ResultLocPeer;
4747
struct ResultLocPeerParent;
4848
struct ResultLocBitCast;
4949

50+
enum PtrLen {
51+
PtrLenUnknown,
52+
PtrLenSingle,
53+
PtrLenC,
54+
};
55+
5056
enum X64CABIClass {
5157
X64CABIClass_Unknown,
5258
X64CABIClass_MEMORY,
@@ -255,6 +261,7 @@ enum ConstValSpecial {
255261
ConstValSpecialRuntime,
256262
ConstValSpecialStatic,
257263
ConstValSpecialUndef,
264+
ConstValSpecialLazy,
258265
};
259266

260267
enum RuntimeHintErrorUnion {
@@ -291,6 +298,44 @@ struct ConstGlobalRefs {
291298
uint32_t align;
292299
};
293300

301+
enum LazyValueId {
302+
LazyValueIdInvalid,
303+
LazyValueIdAlignOf,
304+
LazyValueIdPtrType,
305+
LazyValueIdSliceType,
306+
};
307+
308+
struct LazyValue {
309+
LazyValueId id;
310+
IrExecutable *exec;
311+
};
312+
313+
struct LazyValueAlignOf {
314+
LazyValue base;
315+
ZigType *target_type;
316+
};
317+
318+
struct LazyValueSliceType {
319+
LazyValue base;
320+
ZigType *elem_type;
321+
ConstExprValue *align_val; // can be null
322+
bool is_const;
323+
bool is_volatile;
324+
bool is_allowzero;
325+
};
326+
327+
struct LazyValuePtrType {
328+
LazyValue base;
329+
ZigType *elem_type;
330+
ConstExprValue *align_val; // can be null
331+
PtrLen ptr_len;
332+
uint32_t bit_offset_in_host;
333+
uint32_t host_int_bytes;
334+
bool is_const;
335+
bool is_volatile;
336+
bool is_allowzero;
337+
};
338+
294339
struct ConstExprValue {
295340
ZigType *type;
296341
ConstValSpecial special;
@@ -318,6 +363,7 @@ struct ConstExprValue {
318363
ConstPtrValue x_ptr;
319364
ConstArgTuple x_arg_tuple;
320365
Buf *x_enum_literal;
366+
LazyValue *x_lazy;
321367

322368
// populated if special == ConstValSpecialRuntime
323369
RuntimeHintErrorUnion rh_error_union;
@@ -1039,12 +1085,6 @@ struct FnTypeId {
10391085
uint32_t fn_type_id_hash(FnTypeId*);
10401086
bool fn_type_id_eql(FnTypeId *a, FnTypeId *b);
10411087

1042-
enum PtrLen {
1043-
PtrLenUnknown,
1044-
PtrLenSingle,
1045-
PtrLenC,
1046-
};
1047-
10481088
struct ZigTypePointer {
10491089
ZigType *child_type;
10501090
ZigType *slice_parent;
@@ -1073,7 +1113,8 @@ struct ZigTypeArray {
10731113

10741114
struct TypeStructField {
10751115
Buf *name;
1076-
ZigType *type_entry;
1116+
ZigType *type_entry; // available after ResolveStatusSizeKnown
1117+
ConstExprValue *type_val; // available after ResolveStatusZeroBitsKnown
10771118
size_t src_index;
10781119
size_t gen_index;
10791120
size_t offset; // byte offset from beginning of struct
@@ -1931,7 +1972,7 @@ struct CodeGen {
19311972
Buf *zig_lib_dir;
19321973
Buf *zig_std_dir;
19331974
Buf *dynamic_linker_path;
1934-
Buf *version_script_path;
1975+
Buf *version_script_path;
19351976

19361977
const char **llvm_argv;
19371978
size_t llvm_argv_len;
@@ -3648,13 +3689,13 @@ enum ResultLocId {
36483689
ResultLocIdBitCast,
36493690
};
36503691

3651-
// Additions to this struct may need to be handled in
3692+
// Additions to this struct may need to be handled in
36523693
// ir_reset_result
36533694
struct ResultLoc {
36543695
ResultLocId id;
36553696
bool written;
36563697
bool allow_write_through_const;
3657-
IrInstruction *resolved_loc; // result ptr
3698+
IrInstruction *resolved_loc; // result ptr
36583699
IrInstruction *source_instruction;
36593700
IrInstruction *gen_instruction; // value to store to the result loc
36603701
ZigType *implicit_elem_type;

src/analyze.cpp

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -445,8 +445,6 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons
445445
}
446446
}
447447

448-
assert(type_is_resolved(child_type, ResolveStatusZeroBitsKnown));
449-
450448
ZigType *entry = new_type_table_entry(ZigTypeIdPointer);
451449

452450
const char *star_str = ptr_len_to_star_str(ptr_len);
@@ -476,8 +474,6 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons
476474
buf_ptr(&child_type->name));
477475
}
478476

479-
assert(child_type->id != ZigTypeIdInvalid);
480-
481477
if (type_has_bits(child_type)) {
482478
entry->abi_size = g->builtin_types.entry_usize->abi_size;
483479
entry->size_in_bits = g->builtin_types.entry_usize->size_in_bits;
@@ -689,7 +685,7 @@ ZigType *get_slice_type(CodeGen *g, ZigType *ptr_type) {
689685
entry->data.structure.fields_by_name.put(ptr_field_name, &entry->data.structure.fields[slice_ptr_index]);
690686
entry->data.structure.fields_by_name.put(len_field_name, &entry->data.structure.fields[slice_len_index]);
691687

692-
switch (type_requires_comptime(g, ptr_type)) {
688+
switch (type_requires_comptime(g, ptr_type, entry)) {
693689
case ReqCompTimeInvalid:
694690
zig_unreachable();
695691
case ReqCompTimeNo:
@@ -945,12 +941,18 @@ ZigType *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind
945941
return entry;
946942
}
947943

948-
ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry, Buf *type_name) {
944+
ConstExprValue *analyze_const_value_allow_lazy(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry,
945+
Buf *type_name, bool allow_lazy)
946+
{
949947
size_t backward_branch_count = 0;
950948
size_t backward_branch_quota = default_backward_branch_quota;
951949
return ir_eval_const_value(g, scope, node, type_entry,
952950
&backward_branch_count, &backward_branch_quota,
953-
nullptr, nullptr, node, type_name, nullptr, nullptr);
951+
nullptr, nullptr, node, type_name, nullptr, nullptr, allow_lazy);
952+
}
953+
954+
ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry, Buf *type_name) {
955+
return analyze_const_value_allow_lazy(g, scope, node, type_entry, type_name, false);
954956
}
955957

956958
ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) {
@@ -1355,7 +1357,7 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
13551357
case ZigTypeIdVector:
13561358
case ZigTypeIdFnFrame:
13571359
case ZigTypeIdAnyFrame:
1358-
switch (type_requires_comptime(g, type_entry)) {
1360+
switch (type_requires_comptime(g, type_entry, fn_entry->type_entry)) {
13591361
case ReqCompTimeNo:
13601362
break;
13611363
case ReqCompTimeYes:
@@ -1451,7 +1453,7 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
14511453
case ZigTypeIdVector:
14521454
case ZigTypeIdFnFrame:
14531455
case ZigTypeIdAnyFrame:
1454-
switch (type_requires_comptime(g, fn_type_id.return_type)) {
1456+
switch (type_requires_comptime(g, fn_type_id.return_type, fn_entry->type_entry)) {
14551457
case ReqCompTimeInvalid:
14561458
return g->builtin_types.entry_invalid;
14571459
case ReqCompTimeYes:
@@ -2164,7 +2166,7 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {
21642166
struct_type->data.structure.resolve_status = ResolveStatusInvalid;
21652167
return ErrorSemanticAnalyzeFail;
21662168
}
2167-
switch (type_requires_comptime(g, field_type)) {
2169+
switch (type_requires_comptime(g, field_type, struct_type)) {
21682170
case ReqCompTimeYes:
21692171
struct_type->data.structure.requires_comptime = true;
21702172
break;
@@ -2422,7 +2424,7 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {
24222424
return ErrorSemanticAnalyzeFail;
24232425
}
24242426

2425-
switch (type_requires_comptime(g, field_type)) {
2427+
switch (type_requires_comptime(g, field_type, union_type)) {
24262428
case ReqCompTimeInvalid:
24272429
union_type->data.unionation.resolve_status = ResolveStatusInvalid;
24282430
return ErrorSemanticAnalyzeFail;
@@ -4754,11 +4756,12 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {
47544756
zig_unreachable();
47554757
}
47564758

4757-
ReqCompTime type_requires_comptime(CodeGen *g, ZigType *type_entry) {
4759+
ReqCompTime type_requires_comptime(CodeGen *g, ZigType *ty, ZigType *parent_type) {
47584760
Error err;
4759-
if ((err = type_resolve(g, type_entry, ResolveStatusZeroBitsKnown)))
4760-
return ReqCompTimeInvalid;
4761-
switch (type_entry->id) {
4761+
if (ty == parent_type) {
4762+
return ReqCompTimeNo;
4763+
}
4764+
switch (ty->id) {
47624765
case ZigTypeIdInvalid:
47634766
case ZigTypeIdOpaque:
47644767
zig_unreachable();
@@ -4772,23 +4775,27 @@ ReqCompTime type_requires_comptime(CodeGen *g, ZigType *type_entry) {
47724775
case ZigTypeIdArgTuple:
47734776
return ReqCompTimeYes;
47744777
case ZigTypeIdArray:
4775-
return type_requires_comptime(g, type_entry->data.array.child_type);
4778+
return type_requires_comptime(g, ty->data.array.child_type, parent_type);
47764779
case ZigTypeIdStruct:
4777-
return type_entry->data.structure.requires_comptime ? ReqCompTimeYes : ReqCompTimeNo;
4780+
if ((err = type_resolve(g, ty, ResolveStatusZeroBitsKnown)))
4781+
return ReqCompTimeInvalid;
4782+
return ty->data.structure.requires_comptime ? ReqCompTimeYes : ReqCompTimeNo;
47784783
case ZigTypeIdUnion:
4779-
return type_entry->data.unionation.requires_comptime ? ReqCompTimeYes : ReqCompTimeNo;
4784+
if ((err = type_resolve(g, ty, ResolveStatusZeroBitsKnown)))
4785+
return ReqCompTimeInvalid;
4786+
return ty->data.unionation.requires_comptime ? ReqCompTimeYes : ReqCompTimeNo;
47804787
case ZigTypeIdOptional:
4781-
return type_requires_comptime(g, type_entry->data.maybe.child_type);
4788+
return type_requires_comptime(g, ty->data.maybe.child_type, parent_type);
47824789
case ZigTypeIdErrorUnion:
4783-
return type_requires_comptime(g, type_entry->data.error_union.payload_type);
4790+
return type_requires_comptime(g, ty->data.error_union.payload_type, parent_type);
47844791
case ZigTypeIdPointer:
4785-
if (type_entry->data.pointer.child_type->id == ZigTypeIdOpaque) {
4792+
if (ty->data.pointer.child_type->id == ZigTypeIdOpaque) {
47864793
return ReqCompTimeNo;
47874794
} else {
4788-
return type_requires_comptime(g, type_entry->data.pointer.child_type);
4795+
return type_requires_comptime(g, ty->data.pointer.child_type, parent_type);
47894796
}
47904797
case ZigTypeIdFn:
4791-
return type_entry->data.fn.is_generic ? ReqCompTimeYes : ReqCompTimeNo;
4798+
return ty->data.fn.is_generic ? ReqCompTimeYes : ReqCompTimeNo;
47924799
case ZigTypeIdEnum:
47934800
case ZigTypeIdErrorSet:
47944801
case ZigTypeIdBool:
@@ -5726,6 +5733,9 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
57265733
case ConstValSpecialRuntime:
57275734
buf_appendf(buf, "(runtime value)");
57285735
return;
5736+
case ConstValSpecialLazy:
5737+
buf_appendf(buf, "(lazy value)");
5738+
return;
57295739
case ConstValSpecialUndef:
57305740
buf_appendf(buf, "undefined");
57315741
return;

src/analyze.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ enum ReqCompTime {
221221
ReqCompTimeNo,
222222
ReqCompTimeYes,
223223
};
224-
ReqCompTime type_requires_comptime(CodeGen *g, ZigType *type_entry);
224+
ReqCompTime type_requires_comptime(CodeGen *g, ZigType *type_entry, ZigType *parent_type);
225225

226226
OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry);
227227

@@ -241,6 +241,8 @@ void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_pa
241241
void src_assert(bool ok, AstNode *source_node);
242242
bool is_container(ZigType *type_entry);
243243
ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry, Buf *type_name);
244+
ConstExprValue *analyze_const_value_allow_lazy(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry,
245+
Buf *type_name, bool allow_lazy);
244246

245247
void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn);
246248
bool fn_is_async(ZigFn *fn);

src/codegen.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3386,6 +3386,8 @@ static bool value_is_all_undef_array(ConstExprValue *const_val, size_t len) {
33863386

33873387
static bool value_is_all_undef(ConstExprValue *const_val) {
33883388
switch (const_val->special) {
3389+
case ConstValSpecialLazy:
3390+
zig_unreachable();
33893391
case ConstValSpecialRuntime:
33903392
return false;
33913393
case ConstValSpecialUndef:
@@ -3686,7 +3688,7 @@ static void render_async_spills(CodeGen *g) {
36863688
}
36873689
if (ir_get_var_is_comptime(var))
36883690
continue;
3689-
switch (type_requires_comptime(g, var->var_type)) {
3691+
switch (type_requires_comptime(g, var->var_type, nullptr)) {
36903692
case ReqCompTimeInvalid:
36913693
zig_unreachable();
36923694
case ReqCompTimeYes:
@@ -6041,6 +6043,7 @@ static LLVMValueRef gen_const_ptr_union_recursive(CodeGen *g, ConstExprValue *un
60416043

60426044
static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, ConstExprValue *const_val) {
60436045
switch (const_val->special) {
6046+
case ConstValSpecialLazy:
60446047
case ConstValSpecialRuntime:
60456048
zig_unreachable();
60466049
case ConstValSpecialUndef:
@@ -6300,6 +6303,8 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c
63006303
assert(type_has_bits(type_entry));
63016304

63026305
switch (const_val->special) {
6306+
case ConstValSpecialLazy:
6307+
zig_unreachable();
63036308
case ConstValSpecialRuntime:
63046309
zig_unreachable();
63056310
case ConstValSpecialUndef:
@@ -7044,7 +7049,7 @@ static void do_code_gen(CodeGen *g) {
70447049
}
70457050
if (ir_get_var_is_comptime(var))
70467051
continue;
7047-
switch (type_requires_comptime(g, var->var_type)) {
7052+
switch (type_requires_comptime(g, var->var_type, nullptr)) {
70487053
case ReqCompTimeInvalid:
70497054
zig_unreachable();
70507055
case ReqCompTimeYes:

0 commit comments

Comments
 (0)