decouple llvm types from zig types

Not tested yet, but it builds.

This closes #761, and lays the groundwork for fixing the remaining
false positive "foo depends on itself" bugs, such as #624.

It also lays the groundwork for implementing ability to specify
alignment of fields (#1512).
This commit is contained in:
Andrew Kelley 2019-03-29 18:32:16 -04:00
parent 2f96c55095
commit ee5064c053
No known key found for this signature in database
GPG Key ID: 7C5F548F728501A9
5 changed files with 1668 additions and 1608 deletions

View File

@ -1067,8 +1067,10 @@ struct TypeStructField {
ZigType *type_entry;
size_t src_index;
size_t gen_index;
uint32_t bit_offset_in_host; // offset from the memory at gen_index
size_t offset; // byte offset from beginning of struct
AstNode *decl_node;
uint32_t bit_offset_in_host; // offset from the memory at gen_index
uint32_t host_int_bytes; // size of host integer
};
enum ResolveStatus {
@ -1101,14 +1103,13 @@ struct ZigTypeStruct {
AstNode *decl_node;
TypeStructField *fields;
ScopeDecls *decls_scope;
uint64_t size_bytes;
HashMap<Buf *, TypeStructField *, buf_hash, buf_eql_buf> fields_by_name;
RootStruct *root_struct;
uint32_t *host_int_bytes; // available for packed structs, indexed by gen_index
uint32_t src_field_count;
uint32_t gen_field_count;
uint32_t abi_alignment; // known after ResolveStatusAlignmentKnown
ContainerLayout layout;
ResolveStatus resolve_status;
@ -1164,39 +1165,28 @@ bool type_ptr_eql(const ZigType *a, const ZigType *b);
struct ZigTypeUnion {
AstNode *decl_node;
ContainerLayout layout;
TypeUnionField *fields;
ScopeDecls *decls_scope;
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;
size_t gen_union_index;
size_t gen_tag_index;
size_t union_abi_size;
uint32_t src_field_count;
uint32_t gen_field_count;
TypeUnionField *fields;
bool is_invalid; // true if any fields are invalid
ZigType *tag_type; // always an enum or null
LLVMTypeRef union_type_ref;
ScopeDecls *decls_scope;
ContainerLayout layout;
ResolveStatus resolve_status;
// set this flag temporarily to detect infinite loops
bool embedded_in_current;
bool have_explicit_tag_type;
bool resolve_loop_flag; // set this flag temporarily to detect infinite loops
bool reported_infinite_err;
// whether we've finished resolving it
bool complete;
// whether any of the fields require comptime
// the value is not valid until zero_bits_known == true
bool requires_comptime;
bool zero_bits_loop_flag;
bool zero_bits_known;
uint32_t abi_alignment; // also figured out with zero_bits pass
size_t gen_union_index;
size_t gen_tag_index;
bool have_explicit_tag_type;
uint32_t union_size_bytes;
ZigType *most_aligned_union_member;
HashMap<Buf *, TypeUnionField *, buf_hash, buf_eql_buf> fields_by_name;
};
struct FnGenParamInfo {
@ -1277,8 +1267,11 @@ struct ZigType {
ZigTypeId id;
Buf name;
LLVMTypeRef type_ref;
ZigLLVMDIType *di_type;
// These are not supposed to be accessed directly. They're
// null during semantic analysis, memoized with get_llvm_type
// and get_llvm_di_type
LLVMTypeRef llvm_type;
ZigLLVMDIType *llvm_di_type;
union {
ZigTypePointer pointer;
@ -1308,8 +1301,14 @@ struct ZigType {
ConstExprValue *cached_const_name_val;
OnePossibleValue one_possible_value;
// Known after ResolveStatusAlignmentKnown.
uint32_t abi_align;
// The offset in bytes between consecutive array elements of this type. Known
// after ResolveStatusSizeKnown.
size_t abi_size;
// Number of bits of information in this type. Known after ResolveStatusSizeKnown.
size_t size_in_bits;
bool zero_bits; // this is denormalized data
bool gen_h_loop_flag;
};
@ -1700,11 +1699,9 @@ struct CodeGen {
ZigList<AstNode *> use_queue;
size_t use_queue_index;
ZigList<TimeEvent> timing_events;
ZigList<ZigLLVMDIType **> error_di_types;
ZigList<AstNode *> tld_ref_source_node_stack;
ZigList<ZigFn *> inline_fns;
ZigList<ZigFn *> test_fns;
ZigList<ZigLLVMDIEnumerator *> err_enumerators;
ZigList<ErrorTableEntry *> errors_by_index;
ZigList<CacheHash *> caches_to_release;
size_t largest_err_name_len;

File diff suppressed because it is too large Load Diff

View File

@ -244,4 +244,6 @@ Buf *type_bare_name(ZigType *t);
Buf *type_h_name(ZigType *t);
Error create_c_object_cache(CodeGen *g, CacheHash **out_cache_hash, bool verbose);
LLVMTypeRef get_llvm_type(CodeGen *g, ZigType *type);
ZigLLVMDIType *get_llvm_di_type(CodeGen *g, ZigType *type);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -6842,6 +6842,9 @@ static ZigType *get_error_set_union(CodeGen *g, ErrorTableEntry **errors, ZigTyp
assert(set2->id == ZigTypeIdErrorSet);
ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet);
err_set_type->size_in_bits = g->builtin_types.entry_global_error_set->size_in_bits;
err_set_type->abi_align = g->builtin_types.entry_global_error_set->abi_align;
err_set_type->abi_size = g->builtin_types.entry_global_error_set->abi_size;
buf_resize(&err_set_type->name, 0);
buf_appendf(&err_set_type->name, "error{");
@ -6857,8 +6860,6 @@ static ZigType *get_error_set_union(CodeGen *g, ErrorTableEntry **errors, ZigTyp
}
}
err_set_type->type_ref = g->builtin_types.entry_global_error_set->type_ref;
err_set_type->di_type = g->builtin_types.entry_global_error_set->di_type;
err_set_type->data.error_set.err_count = count;
err_set_type->data.error_set.errors = allocate<ErrorTableEntry *>(count);
@ -6883,8 +6884,6 @@ static ZigType *get_error_set_union(CodeGen *g, ErrorTableEntry **errors, ZigTyp
buf_appendf(&err_set_type->name, "}");
g->error_di_types.append(&err_set_type->di_type);
return err_set_type;
}
@ -6895,13 +6894,12 @@ static ZigType *make_err_set_with_one_item(CodeGen *g, Scope *parent_scope, AstN
ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet);
buf_resize(&err_set_type->name, 0);
buf_appendf(&err_set_type->name, "error{%s}", buf_ptr(&err_entry->name));
err_set_type->type_ref = g->builtin_types.entry_global_error_set->type_ref;
err_set_type->di_type = g->builtin_types.entry_global_error_set->di_type;
err_set_type->size_in_bits = g->builtin_types.entry_global_error_set->size_in_bits;
err_set_type->abi_align = g->builtin_types.entry_global_error_set->abi_align;
err_set_type->abi_size = g->builtin_types.entry_global_error_set->abi_size;
err_set_type->data.error_set.err_count = 1;
err_set_type->data.error_set.errors = allocate<ErrorTableEntry *>(1);
g->error_di_types.append(&err_set_type->di_type);
err_set_type->data.error_set.errors[0] = err_entry;
return err_set_type;
@ -6917,9 +6915,9 @@ static IrInstruction *ir_gen_err_set_decl(IrBuilder *irb, Scope *parent_scope, A
ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet);
buf_init_from_buf(&err_set_type->name, type_name);
err_set_type->data.error_set.err_count = err_count;
err_set_type->type_ref = irb->codegen->builtin_types.entry_global_error_set->type_ref;
err_set_type->di_type = irb->codegen->builtin_types.entry_global_error_set->di_type;
irb->codegen->error_di_types.append(&err_set_type->di_type);
err_set_type->size_in_bits = irb->codegen->builtin_types.entry_global_error_set->size_in_bits;
err_set_type->abi_align = irb->codegen->builtin_types.entry_global_error_set->abi_align;
err_set_type->abi_size = irb->codegen->builtin_types.entry_global_error_set->abi_size;
err_set_type->data.error_set.errors = allocate<ErrorTableEntry *>(err_count);
ErrorTableEntry **errors = allocate<ErrorTableEntry *>(irb->codegen->errors_by_index.length + err_count);
@ -6940,8 +6938,6 @@ static IrInstruction *ir_gen_err_set_decl(IrBuilder *irb, Scope *parent_scope, A
assert((uint32_t)error_value_count < (((uint32_t)1) << (uint32_t)irb->codegen->err_tag_type->data.integral.bit_count));
err->value = error_value_count;
irb->codegen->errors_by_index.append(err);
irb->codegen->err_enumerators.append(ZigLLVMCreateDebugEnumerator(irb->codegen->dbuilder,
buf_ptr(err_name), error_value_count));
}
err_set_type->data.error_set.errors[i] = err;
@ -8947,16 +8943,16 @@ static ZigType *get_error_set_intersection(IrAnalyze *ira, ZigType *set1, ZigTyp
}
free(errors);
err_set_type->type_ref = ira->codegen->builtin_types.entry_global_error_set->type_ref;
err_set_type->di_type = ira->codegen->builtin_types.entry_global_error_set->di_type;
err_set_type->data.error_set.err_count = intersection_list.length;
err_set_type->data.error_set.errors = intersection_list.items;
err_set_type->zero_bits = intersection_list.length == 0;
if (intersection_list.length != 0) {
err_set_type->size_in_bits = ira->codegen->builtin_types.entry_global_error_set->size_in_bits;
err_set_type->abi_align = ira->codegen->builtin_types.entry_global_error_set->abi_align;
err_set_type->abi_size = ira->codegen->builtin_types.entry_global_error_set->abi_size;
}
buf_appendf(&err_set_type->name, "}");
ira->codegen->error_di_types.append(&err_set_type->di_type);
return err_set_type;
}
@ -14855,7 +14851,7 @@ static IrInstruction *ir_analyze_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op_
ZigType *type_entry = ir_resolve_type(ira, value);
if (type_is_invalid(type_entry))
return ira->codegen->invalid_instruction;
if ((err = ensure_complete_type(ira->codegen, type_entry)))
if ((err = type_resolve(ira->codegen, type_entry, ResolveStatusSizeKnown)))
return ira->codegen->invalid_instruction;
switch (type_entry->id) {
@ -16051,8 +16047,6 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc
assert((uint32_t)error_value_count < (((uint32_t)1) << (uint32_t)ira->codegen->err_tag_type->data.integral.bit_count));
err_entry->value = error_value_count;
ira->codegen->errors_by_index.append(err_entry);
ira->codegen->err_enumerators.append(ZigLLVMCreateDebugEnumerator(ira->codegen->dbuilder,
buf_ptr(field_name), error_value_count));
ira->codegen->error_table.put(field_name, err_entry);
}
if (err_entry->set_with_only_this_in_it == nullptr) {
@ -17873,7 +17867,7 @@ static TypeStructField *validate_byte_offset(IrAnalyze *ira,
return nullptr;
}
*byte_offset = LLVMOffsetOfElement(ira->codegen->target_data_ref, container_type->type_ref, field->gen_index);
*byte_offset = field->offset;
return field;
}
@ -18726,7 +18720,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
if (!type_has_bits(struct_field->type_entry)) {
inner_fields[1].data.x_optional = nullptr;
} else {
size_t byte_offset = LLVMOffsetOfElement(ira->codegen->target_data_ref, type_entry->type_ref, struct_field->gen_index);
size_t byte_offset = struct_field->offset;
inner_fields[1].data.x_optional = create_const_vals(1);
inner_fields[1].data.x_optional->special = ConstValSpecialStatic;
inner_fields[1].data.x_optional->type = ira->codegen->builtin_types.entry_num_lit_int;
@ -21425,12 +21419,11 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
case ContainerLayoutExtern: {
size_t src_field_count = val->type->data.structure.src_field_count;
for (size_t field_i = 0; field_i < src_field_count; field_i += 1) {
TypeStructField *type_field = &val->type->data.structure.fields[field_i];
if (type_field->gen_index == SIZE_MAX)
TypeStructField *struct_field = &val->type->data.structure.fields[field_i];
if (struct_field->gen_index == SIZE_MAX)
continue;
ConstExprValue *field_val = &val->data.x_struct.fields[field_i];
size_t offset = LLVMOffsetOfElement(codegen->target_data_ref, val->type->type_ref,
type_field->gen_index);
size_t offset = struct_field->offset;
buf_write_value_bytes(codegen, buf + offset, field_val);
}
return;
@ -21446,10 +21439,7 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
size_t child_buf_len = 16;
uint8_t *child_buf = child_buf_prealloc;
while (gen_i < gen_field_count) {
LLVMTypeRef gen_llvm_int_type = LLVMStructGetTypeAtIndex(val->type->type_ref,
(unsigned)gen_i);
size_t big_int_bit_count = LLVMGetIntTypeWidth(gen_llvm_int_type);
size_t big_int_byte_count = big_int_bit_count / 8;
size_t big_int_byte_count = val->type->data.structure.host_int_bytes[gen_i];
if (big_int_byte_count > child_buf_len) {
child_buf = allocate_nonzero<uint8_t>(big_int_byte_count);
child_buf_len = big_int_byte_count;
@ -21485,7 +21475,7 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
}
src_i += 1;
}
bigint_write_twos_complement(&big_int, buf + offset, big_int_bit_count, is_big_endian);
bigint_write_twos_complement(&big_int, buf + offset, big_int_byte_count * 8, is_big_endian);
offset += big_int_byte_count;
gen_i += 1;
}
@ -21606,12 +21596,11 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou
for (size_t field_i = 0; field_i < src_field_count; field_i += 1) {
ConstExprValue *field_val = &val->data.x_struct.fields[field_i];
field_val->special = ConstValSpecialStatic;
TypeStructField *type_field = &val->type->data.structure.fields[field_i];
field_val->type = type_field->type_entry;
if (type_field->gen_index == SIZE_MAX)
TypeStructField *struct_field = &val->type->data.structure.fields[field_i];
field_val->type = struct_field->type_entry;
if (struct_field->gen_index == SIZE_MAX)
continue;
size_t offset = LLVMOffsetOfElement(codegen->target_data_ref, val->type->type_ref,
type_field->gen_index);
size_t offset = struct_field->offset;
uint8_t *new_buf = buf + offset;
if ((err = buf_read_value_bytes(ira, codegen, source_node, new_buf, field_val)))
return err;
@ -21630,16 +21619,13 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou
size_t child_buf_len = 16;
uint8_t *child_buf = child_buf_prealloc;
while (gen_i < gen_field_count) {
LLVMTypeRef gen_llvm_int_type = LLVMStructGetTypeAtIndex(val->type->type_ref,
(unsigned)gen_i);
size_t big_int_bit_count = LLVMGetIntTypeWidth(gen_llvm_int_type);
size_t big_int_byte_count = big_int_bit_count / 8;
size_t big_int_byte_count = val->type->data.structure.host_int_bytes[gen_i];
if (big_int_byte_count > child_buf_len) {
child_buf = allocate_nonzero<uint8_t>(big_int_byte_count);
child_buf_len = big_int_byte_count;
}
BigInt big_int;
bigint_read_twos_complement(&big_int, buf + offset, big_int_bit_count, is_big_endian, false);
bigint_read_twos_complement(&big_int, buf + offset, big_int_byte_count * 8, is_big_endian, false);
while (src_i < src_field_count) {
TypeStructField *field = &val->type->data.structure.fields[src_i];
assert(field->gen_index != SIZE_MAX);
@ -21662,7 +21648,7 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou
big_int = tmp;
}
bigint_write_twos_complement(&child_val, child_buf, big_int_bit_count, is_big_endian);
bigint_write_twos_complement(&child_val, child_buf, big_int_byte_count * 8, is_big_endian);
if ((err = buf_read_value_bytes(ira, codegen, source_node, child_buf, field_val))) {
return err;
}