Skip to content

fix field alignment kludge by implementing lazy values #3115

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 33 commits into from
Aug 27, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
efdbede
breaking: remove field alignment kludge
andrewrk Aug 21, 2019
8460d56
introduce lazy values
andrewrk Aug 22, 2019
0d6a6c7
add missing "referenced here" notes for lazy values
andrewrk Aug 22, 2019
26b79ac
simple self-referential struct is working now
andrewrk Aug 22, 2019
79a4b7a
fix regressions
andrewrk Aug 22, 2019
3865b6a
Merge remote-tracking branch 'origin/master' into fix-field-alignment…
andrewrk Aug 23, 2019
20049ca
add lazy value for fn prototypes
andrewrk Aug 23, 2019
1dd658d
allow top level declarations to be lazy
andrewrk Aug 23, 2019
be0a9a7
pointer types lazily evaluate their element type
andrewrk Aug 23, 2019
ac4dd9d
better handling of lazy structs
andrewrk Aug 23, 2019
f003449
fix regression with simple pointer to self
andrewrk Aug 23, 2019
101440c
add lazy value support for optional types
andrewrk Aug 23, 2019
e8bad1e
fix regression on `@ptrCast`
andrewrk Aug 23, 2019
d277a11
tracking these issues on github now
andrewrk Aug 23, 2019
fa6c20a
hook up unions with lazy values
andrewrk Aug 25, 2019
8f41da2
fix behavior test regressions with unions
andrewrk Aug 25, 2019
64e9b0e
make the zero-bit-ness of pointers lazy
andrewrk Aug 26, 2019
a7f3158
behavior tests passing
andrewrk Aug 26, 2019
720302a
fix resolution detection of pointer types
andrewrk Aug 26, 2019
b13af07
fix assertion tripped instead of reporting compile error
andrewrk Aug 26, 2019
ede0c22
make `@alignOf` lazily evaluate the target type
andrewrk Aug 26, 2019
e1a4bcb
fix dependency loop errors with zig build
andrewrk Aug 26, 2019
6569bfc
fix some std lib dependency loops
andrewrk Aug 26, 2019
73a7747
fix some compile error regressions
andrewrk Aug 26, 2019
d316f70
fix regression on struct field with undefined type
andrewrk Aug 26, 2019
ae65c23
fix regression with global variable assignment...
andrewrk Aug 26, 2019
ca145a6
fix regression in ir_get_ref
andrewrk Aug 26, 2019
bad4b04
miscellaneous fixes regarding compile errors
andrewrk Aug 26, 2019
db50cf7
fix more compile error regressions
andrewrk Aug 27, 2019
a2e8ef7
fix regression in one of the doc examples
andrewrk Aug 27, 2019
ffac0b0
implement and test struct field explicit alignment
andrewrk Aug 27, 2019
7d34e55
add a TODO compile error for union field alignment syntax
andrewrk Aug 27, 2019
d9ed55f
fix not properly casting align values
andrewrk Aug 27, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 106 additions & 31 deletions src/all_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,19 @@ struct ResultLocPeer;
struct ResultLocPeerParent;
struct ResultLocBitCast;

enum PtrLen {
PtrLenUnknown,
PtrLenSingle,
PtrLenC,
};

enum UndefAllowed {
UndefOk,
UndefBad,
LazyOkNoUndef,
LazyOk,
};

enum X64CABIClass {
X64CABIClass_Unknown,
X64CABIClass_MEMORY,
Expand All @@ -69,9 +82,9 @@ struct IrExecutable {
IrExecutable *source_exec;
IrAnalyze *analysis;
Scope *begin_scope;
ErrorMsg *first_err_trace_msg;
ZigList<Tld *> tld_list;

bool invalid;
bool is_inline;
bool is_generic_instantiation;
bool need_err_code_spill;
Expand Down Expand Up @@ -255,6 +268,7 @@ enum ConstValSpecial {
ConstValSpecialRuntime,
ConstValSpecialStatic,
ConstValSpecialUndef,
ConstValSpecialLazy,
};

enum RuntimeHintErrorUnion {
Expand Down Expand Up @@ -291,6 +305,73 @@ struct ConstGlobalRefs {
uint32_t align;
};

enum LazyValueId {
LazyValueIdInvalid,
LazyValueIdAlignOf,
LazyValueIdPtrType,
LazyValueIdOptType,
LazyValueIdSliceType,
LazyValueIdFnType,
};

struct LazyValue {
LazyValueId id;
};

struct LazyValueAlignOf {
LazyValue base;

IrAnalyze *ira;
IrInstruction *target_type;
};

struct LazyValueSliceType {
LazyValue base;

IrAnalyze *ira;
ZigType *elem_type;
IrInstruction *align_inst; // can be null

bool is_const;
bool is_volatile;
bool is_allowzero;
};

struct LazyValuePtrType {
LazyValue base;

IrAnalyze *ira;
IrInstruction *elem_type;
IrInstruction *align_inst; // can be null

PtrLen ptr_len;
uint32_t bit_offset_in_host;

uint32_t host_int_bytes;
bool is_const;
bool is_volatile;
bool is_allowzero;
};

struct LazyValueOptType {
LazyValue base;

IrAnalyze *ira;
IrInstruction *payload_type;
};

struct LazyValueFnType {
LazyValue base;

IrAnalyze *ira;
AstNode *proto_node;
IrInstruction **param_types;
IrInstruction *align_inst; // can be null
IrInstruction *return_type;

bool is_generic;
};

struct ConstExprValue {
ZigType *type;
ConstValSpecial special;
Expand Down Expand Up @@ -318,6 +399,7 @@ struct ConstExprValue {
ConstPtrValue x_ptr;
ConstArgTuple x_arg_tuple;
Buf *x_enum_literal;
LazyValue *x_lazy;

// populated if special == ConstValSpecialRuntime
RuntimeHintErrorUnion rh_error_union;
Expand Down Expand Up @@ -364,6 +446,7 @@ enum TldResolution {
TldResolutionUnresolved,
TldResolutionResolving,
TldResolutionInvalid,
TldResolutionOkLazy,
TldResolutionOk,
};

Expand Down Expand Up @@ -420,10 +503,12 @@ struct TypeEnumField {

struct TypeUnionField {
Buf *name;
ZigType *type_entry; // available after ResolveStatusSizeKnown
ConstExprValue *type_val; // available after ResolveStatusZeroBitsKnown
TypeEnumField *enum_field;
ZigType *type_entry;
AstNode *decl_node;
uint32_t gen_index;
uint32_t align;
};

enum NodeType {
Expand Down Expand Up @@ -946,6 +1031,7 @@ struct AstNodeEnumLiteral {

struct AstNode {
enum NodeType type;
bool already_traced_this_node;
size_t line;
size_t column;
ZigType *owner;
Expand Down Expand Up @@ -1041,12 +1127,6 @@ struct FnTypeId {
uint32_t fn_type_id_hash(FnTypeId*);
bool fn_type_id_eql(FnTypeId *a, FnTypeId *b);

enum PtrLen {
PtrLenUnknown,
PtrLenSingle,
PtrLenC,
};

struct ZigTypePointer {
ZigType *child_type;
ZigType *slice_parent;
Expand All @@ -1057,6 +1137,7 @@ struct ZigTypePointer {
bool is_const;
bool is_volatile;
bool allow_zero;
bool resolve_loop_flag_zero_bits;
};

struct ZigTypeInt {
Expand All @@ -1075,7 +1156,8 @@ struct ZigTypeArray {

struct TypeStructField {
Buf *name;
ZigType *type_entry;
ZigType *type_entry; // available after ResolveStatusSizeKnown
ConstExprValue *type_val; // available after ResolveStatusZeroBitsKnown
size_t src_index;
size_t gen_index;
size_t offset; // byte offset from beginning of struct
Expand Down Expand Up @@ -1131,11 +1213,11 @@ struct ZigTypeStruct {
ResolveStatus resolve_status;

bool is_slice;
bool resolve_loop_flag; // set this flag temporarily to detect infinite loops
bool reported_infinite_err;
// whether any of the fields require comptime
// known after ResolveStatusZeroBitsKnown
bool requires_comptime;
bool resolve_loop_flag_zero_bits;
bool resolve_loop_flag_other;
};

struct ZigTypeOptional {
Expand All @@ -1157,26 +1239,20 @@ struct ZigTypeErrorSet {

struct ZigTypeEnum {
AstNode *decl_node;
ContainerLayout layout;
uint32_t src_field_count;
TypeEnumField *fields;
bool is_invalid; // true if any fields are invalid
ZigType *tag_int_type;

ScopeDecls *decls_scope;

// set this flag temporarily to detect infinite loops
bool embedded_in_current;
bool reported_infinite_err;
// whether we've finished resolving it
bool complete;

bool zero_bits_loop_flag;
bool zero_bits_known;

LLVMValueRef name_function;

HashMap<Buf *, TypeEnumField *, buf_hash, buf_eql_buf> fields_by_name;
uint32_t src_field_count;

ContainerLayout layout;
ResolveStatus resolve_status;

bool resolve_loop_flag;
};

uint32_t type_ptr_hash(const ZigType *ptr);
Expand All @@ -1189,7 +1265,7 @@ struct ZigTypeUnion {
HashMap<Buf *, TypeUnionField *, buf_hash, buf_eql_buf> fields_by_name;
ZigType *tag_type; // always an enum or null
LLVMTypeRef union_llvm_type;
ZigType *most_aligned_union_member;
TypeUnionField *most_aligned_union_member;
size_t gen_union_index;
size_t gen_tag_index;
size_t union_abi_size;
Expand All @@ -1201,11 +1277,11 @@ struct ZigTypeUnion {
ResolveStatus resolve_status;

bool have_explicit_tag_type;
bool resolve_loop_flag; // set this flag temporarily to detect infinite loops
bool reported_infinite_err;
// whether any of the fields require comptime
// the value is not valid until zero_bits_known == true
bool requires_comptime;
bool resolve_loop_flag_zero_bits;
bool resolve_loop_flag_other;
};

struct FnGenParamInfo {
Expand Down Expand Up @@ -1717,6 +1793,7 @@ struct CodeGen {
//////////////////////////// Runtime State
LLVMModuleRef module;
ZigList<ErrorMsg*> errors;
ErrorMsg *trace_err;
LLVMBuilderRef builder;
ZigLLVMDIBuilder *dbuilder;
ZigLLVMDICompileUnit *compile_unit;
Expand Down Expand Up @@ -1769,7 +1846,6 @@ struct CodeGen {
ZigList<Tld *> resolve_queue;
size_t resolve_queue_index;
ZigList<TimeEvent> timing_events;
ZigList<AstNode *> tld_ref_source_node_stack;
ZigList<ZigFn *> inline_fns;
ZigList<ZigFn *> test_fns;
ZigList<ErrorTableEntry *> errors_by_index;
Expand Down Expand Up @@ -1854,7 +1930,6 @@ struct CodeGen {
ZigFn *main_fn;
ZigFn *panic_fn;
TldFn *panic_tld_fn;
AstNode *root_export_decl;

WantPIC want_pic;
WantStackCheck want_stack_check;
Expand Down Expand Up @@ -1942,7 +2017,7 @@ struct CodeGen {
Buf *zig_lib_dir;
Buf *zig_std_dir;
Buf *dynamic_linker_path;
Buf *version_script_path;
Buf *version_script_path;

const char **llvm_argv;
size_t llvm_argv_len;
Expand Down Expand Up @@ -3659,13 +3734,13 @@ enum ResultLocId {
ResultLocIdBitCast,
};

// Additions to this struct may need to be handled in
// Additions to this struct may need to be handled in
// ir_reset_result
struct ResultLoc {
ResultLocId id;
bool written;
bool allow_write_through_const;
IrInstruction *resolved_loc; // result ptr
IrInstruction *resolved_loc; // result ptr
IrInstruction *source_instruction;
IrInstruction *gen_instruction; // value to store to the result loc
ZigType *implicit_elem_type;
Expand Down
Loading