Merge branch 'master' into self-hosted

This commit is contained in:
Andrew Kelley
2017-10-27 01:28:08 -04:00
37 changed files with 499 additions and 205 deletions

View File

@@ -196,10 +196,6 @@ void codegen_set_is_static(CodeGen *g, bool is_static) {
g->is_static = is_static;
}
void codegen_set_verbose(CodeGen *g, bool verbose) {
g->verbose = verbose;
}
void codegen_set_each_lib_rpath(CodeGen *g, bool each_lib_rpath) {
g->each_lib_rpath = each_lib_rpath;
}
@@ -452,10 +448,10 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) {
LLVMSetLinkage(fn_table_entry->llvm_value, LLVMExternalLinkage);
break;
case GlobalLinkageIdWeak:
LLVMSetLinkage(fn_table_entry->llvm_value, LLVMWeakAnyLinkage);
LLVMSetLinkage(fn_table_entry->llvm_value, LLVMWeakODRLinkage);
break;
case GlobalLinkageIdLinkOnce:
LLVMSetLinkage(fn_table_entry->llvm_value, LLVMLinkOnceAnyLinkage);
LLVMSetLinkage(fn_table_entry->llvm_value, LLVMLinkOnceODRLinkage);
break;
}
@@ -3665,6 +3661,12 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con
zig_unreachable();
}
// We have this because union constants can't be represented by the official union type,
// and this property bubbles up in whatever aggregate type contains a union constant
static bool is_llvm_value_unnamed_type(TypeTableEntry *type_entry, LLVMValueRef val) {
return LLVMTypeOf(val) != type_entry->type_ref;
}
static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
TypeTableEntry *type_entry = const_val->type;
assert(!type_entry->zero_bits);
@@ -3726,24 +3728,34 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
} else {
LLVMValueRef child_val;
LLVMValueRef maybe_val;
bool make_unnamed_struct;
if (const_val->data.x_maybe) {
child_val = gen_const_val(g, const_val->data.x_maybe);
maybe_val = LLVMConstAllOnes(LLVMInt1Type());
make_unnamed_struct = is_llvm_value_unnamed_type(const_val->type, child_val);
} else {
child_val = LLVMConstNull(child_type->type_ref);
child_val = LLVMGetUndef(child_type->type_ref);
maybe_val = LLVMConstNull(LLVMInt1Type());
make_unnamed_struct = false;
}
LLVMValueRef fields[] = {
child_val,
maybe_val,
};
return LLVMConstStruct(fields, 2, false);
if (make_unnamed_struct) {
return LLVMConstStruct(fields, 2, false);
} else {
return LLVMConstNamedStruct(type_entry->type_ref, fields, 2);
}
}
}
case TypeTableEntryIdStruct:
{
LLVMValueRef *fields = allocate<LLVMValueRef>(type_entry->data.structure.gen_field_count);
size_t src_field_count = type_entry->data.structure.src_field_count;
bool make_unnamed_struct = false;
if (type_entry->data.structure.layout == ContainerLayoutPacked) {
size_t src_field_index = 0;
while (src_field_index < src_field_count) {
@@ -3761,8 +3773,10 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
}
if (src_field_index + 1 == src_field_index_end) {
fields[type_struct_field->gen_index] =
gen_const_val(g, &const_val->data.x_struct.fields[src_field_index]);
ConstExprValue *field_val = &const_val->data.x_struct.fields[src_field_index];
LLVMValueRef val = gen_const_val(g, field_val);
fields[type_struct_field->gen_index] = val;
make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(field_val->type, val);
} else {
LLVMTypeRef big_int_type_ref = LLVMStructGetTypeAtIndex(type_entry->type_ref,
(unsigned)type_struct_field->gen_index);
@@ -3790,11 +3804,18 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
if (type_struct_field->gen_index == SIZE_MAX) {
continue;
}
fields[type_struct_field->gen_index] = gen_const_val(g, &const_val->data.x_struct.fields[i]);
ConstExprValue *field_val = &const_val->data.x_struct.fields[i];
LLVMValueRef val = gen_const_val(g, field_val);
fields[type_struct_field->gen_index] = val;
make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(field_val->type, val);
}
}
return LLVMConstStruct(fields, type_entry->data.structure.gen_field_count,
type_entry->data.structure.layout == ContainerLayoutPacked);
if (make_unnamed_struct) {
return LLVMConstStruct(fields, type_entry->data.structure.gen_field_count,
type_entry->data.structure.layout == ContainerLayoutPacked);
} else {
return LLVMConstNamedStruct(type_entry->type_ref, fields, type_entry->data.structure.gen_field_count);
}
}
case TypeTableEntryIdUnion:
{
@@ -3808,11 +3829,19 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
}
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];
values[i] = gen_const_val(g, elem_value);
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);
}
return LLVMConstArray(LLVMTypeOf(values[0]), values, (unsigned)len);
}
case TypeTableEntryIdEnum:
{
@@ -3825,14 +3854,20 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
TypeEnumField *enum_field = &type_entry->data.enumeration.fields[const_val->data.x_enum.tag];
assert(enum_field->value == const_val->data.x_enum.tag);
LLVMValueRef union_value;
bool make_unnamed_struct;
if (type_has_bits(enum_field->type_entry)) {
uint64_t union_type_bytes = LLVMStoreSizeOfType(g->target_data_ref,
union_type_ref);
uint64_t field_type_bytes = LLVMStoreSizeOfType(g->target_data_ref,
enum_field->type_entry->type_ref);
uint64_t pad_bytes = union_type_bytes - field_type_bytes;
uint64_t pad_bytes = type_entry->data.enumeration.union_size_bytes - field_type_bytes;
ConstExprValue *payload_value = const_val->data.x_enum.payload;
LLVMValueRef correctly_typed_value = gen_const_val(g, payload_value);
make_unnamed_struct = is_llvm_value_unnamed_type(payload_value->type, correctly_typed_value) ||
payload_value->type != type_entry->data.enumeration.most_aligned_union_member;
LLVMValueRef correctly_typed_value = gen_const_val(g, const_val->data.x_enum.payload);
if (pad_bytes == 0) {
union_value = correctly_typed_value;
} else {
@@ -3843,12 +3878,18 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
union_value = LLVMConstStruct(fields, 2, false);
}
} else {
make_unnamed_struct = false;
union_value = LLVMGetUndef(union_type_ref);
}
LLVMValueRef fields[2];
fields[type_entry->data.enumeration.gen_tag_index] = tag_value;
fields[type_entry->data.enumeration.gen_union_index] = union_value;
return LLVMConstStruct(fields, 2, false);
if (make_unnamed_struct) {
return LLVMConstStruct(fields, 2, false);
} else {
return LLVMConstNamedStruct(type_entry->type_ref, fields, 2);
}
}
}
case TypeTableEntryIdFn:
@@ -3932,18 +3973,26 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
} else {
LLVMValueRef err_tag_value;
LLVMValueRef err_payload_value;
bool make_unnamed_struct;
if (const_val->data.x_err_union.err) {
err_tag_value = LLVMConstInt(g->err_tag_type->type_ref, const_val->data.x_err_union.err->value, false);
err_payload_value = LLVMConstNull(child_type->type_ref);
make_unnamed_struct = false;
} else {
err_tag_value = LLVMConstNull(g->err_tag_type->type_ref);
err_payload_value = gen_const_val(g, const_val->data.x_err_union.payload);
ConstExprValue *payload_val = const_val->data.x_err_union.payload;
err_payload_value = gen_const_val(g, payload_val);
make_unnamed_struct = is_llvm_value_unnamed_type(payload_val->type, err_payload_value);
}
LLVMValueRef fields[] = {
err_tag_value,
err_payload_value,
};
return LLVMConstStruct(fields, 2, false);
if (make_unnamed_struct) {
return LLVMConstStruct(fields, 2, false);
} else {
return LLVMConstNamedStruct(type_entry->type_ref, fields, 2);
}
}
}
case TypeTableEntryIdVoid:
@@ -4159,10 +4208,6 @@ static void validate_inline_fns(CodeGen *g) {
}
static void do_code_gen(CodeGen *g) {
if (g->verbose) {
fprintf(stderr, "\nCode Generation:\n");
fprintf(stderr, "------------------\n");
}
assert(!g->errors.length);
codegen_add_time_event(g, "Code Generation");
@@ -4439,7 +4484,8 @@ static void do_code_gen(CodeGen *g) {
ZigLLVMDIBuilderFinalize(g->dbuilder);
if (g->verbose || g->verbose_ir) {
if (g->verbose_llvm_ir) {
fflush(stderr);
LLVMDumpModule(g->module);
}
@@ -5269,10 +5315,6 @@ static void gen_root_source(CodeGen *g) {
resolve_top_level_decl(g, panic_tld, false, nullptr);
}
if (g->verbose) {
fprintf(stderr, "\nIR Generation and Semantic Analysis:\n");
fprintf(stderr, "--------------------------------------\n");
}
if (!g->error_during_imports) {
semantic_analyze(g);
}
@@ -5286,9 +5328,6 @@ static void gen_root_source(CodeGen *g) {
}
report_errors_and_maybe_exit(g);
if (g->verbose) {
fprintf(stderr, "OK\n");
}
}