diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2019-02-04 21:26:50 -0500 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2019-02-04 21:26:50 -0500 |
| commit | f32f7a937fa7150aaba450b1282bba9f01918807 (patch) | |
| tree | ecb462e15546a50b2e948b8f2907872dd39a2dc6 /src/codegen.cpp | |
| parent | 1411df4e2705e677003e6e5b5cbe1ca30bf637d7 (diff) | |
| parent | 8c6fa982cd0a02775264b616c37da9907cc603bb (diff) | |
| download | zig-f32f7a937fa7150aaba450b1282bba9f01918807.tar.gz zig-f32f7a937fa7150aaba450b1282bba9f01918807.zip | |
Merge remote-tracking branch 'origin/master' into llvm8
Diffstat (limited to 'src/codegen.cpp')
| -rw-r--r-- | src/codegen.cpp | 500 |
1 files changed, 396 insertions, 104 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp index e180b69215..1a70901cf0 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -118,6 +118,7 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out g->string_literals_table.init(16); g->type_info_cache.init(32); g->is_test_build = false; + g->is_single_threaded = false; buf_resize(&g->global_asm, 0); for (size_t i = 0; i < array_length(symbols_that_llvm_depends_on); i += 1) { @@ -313,6 +314,8 @@ static void render_const_val(CodeGen *g, ConstExprValue *const_val, const char * static void render_const_val_global(CodeGen *g, ConstExprValue *const_val, const char *name); static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const char *name); static void generate_error_name_table(CodeGen *g); +static bool value_is_all_undef(ConstExprValue *const_val); +static void gen_undef_init(CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_type, LLVMValueRef ptr); static void addLLVMAttr(LLVMValueRef val, LLVMAttributeIndex attr_index, const char *attr_name) { unsigned kind_id = LLVMGetEnumAttributeKindForName(attr_name, strlen(attr_name)); @@ -461,6 +464,21 @@ static void maybe_import_dll(CodeGen *g, LLVMValueRef global_value, GlobalLinkag } } +static bool cc_want_sret_attr(CallingConvention cc) { + switch (cc) { + case CallingConventionNaked: + zig_unreachable(); + case CallingConventionC: + case CallingConventionCold: + case CallingConventionStdcall: + return true; + case CallingConventionAsync: + case CallingConventionUnspecified: + return false; + } + zig_unreachable(); +} + static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) { if (fn_table_entry->llvm_value) return fn_table_entry->llvm_value; @@ -598,9 +616,9 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) { } else if (type_is_codegen_pointer(return_type)) { addLLVMAttr(fn_table_entry->llvm_value, 0, "nonnull"); } else if (want_first_arg_sret(g, &fn_type->data.fn.fn_type_id)) { - addLLVMArgAttr(fn_table_entry->llvm_value, 0, "sret"); addLLVMArgAttr(fn_table_entry->llvm_value, 0, "nonnull"); - if (cc == CallingConventionC) { + addLLVMArgAttr(fn_table_entry->llvm_value, 0, "sret"); + if (cc_want_sret_attr(cc)) { addLLVMArgAttr(fn_table_entry->llvm_value, 0, "noalias"); } init_gen_i = 1; @@ -1903,9 +1921,8 @@ static void give_up_with_c_abi_error(CodeGen *g, AstNode *source_node) { } static LLVMValueRef build_alloca(CodeGen *g, ZigType *type_entry, const char *name, uint32_t alignment) { - assert(alignment > 0); LLVMValueRef result = LLVMBuildAlloca(g->builder, type_entry->type_ref, name); - LLVMSetAlignment(result, alignment); + LLVMSetAlignment(result, (alignment == 0) ? get_abi_alignment(g, type_entry) : alignment); return result; } @@ -1963,7 +1980,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_ break; } - if (type_is_c_abi_int(g, ty) || ty->id == ZigTypeIdFloat || + if (type_is_c_abi_int(g, ty) || ty->id == ZigTypeIdFloat || ty->id == ZigTypeIdVector || ty->id == ZigTypeIdInt // TODO investigate if we need to change this ) { switch (fn_walk->id) { @@ -2200,10 +2217,10 @@ void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk) { assert(variable); assert(variable->value_ref); - if (!handle_is_ptr(variable->value->type)) { + if (!handle_is_ptr(variable->var_type)) { clear_debug_source_node(g); - gen_store_untyped(g, LLVMGetParam(llvm_fn, (unsigned)variable->gen_arg_index), variable->value_ref, - variable->align_bytes, false); + gen_store_untyped(g, LLVMGetParam(llvm_fn, (unsigned)variable->gen_arg_index), + variable->value_ref, variable->align_bytes, false); } if (variable->decl_node) { @@ -2643,6 +2660,27 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable, } else { return LLVMBuildNUWAdd(g->builder, op1_value, op2_value, ""); } + } else if (type_entry->id == ZigTypeIdVector) { + ZigType *elem_type = type_entry->data.vector.elem_type; + if (elem_type->id == ZigTypeIdFloat) { + ZigLLVMSetFastMath(g->builder, ir_want_fast_math(g, &bin_op_instruction->base)); + return LLVMBuildFAdd(g->builder, op1_value, op2_value, ""); + } else if (elem_type->id == ZigTypeIdPointer) { + zig_panic("TODO codegen for pointers in vectors"); + } else if (elem_type->id == ZigTypeIdInt) { + bool is_wrapping = (op_id == IrBinOpAddWrap); + if (is_wrapping) { + return LLVMBuildAdd(g->builder, op1_value, op2_value, ""); + } else if (want_runtime_safety) { + zig_panic("TODO runtime safety for vector integer addition"); + } else if (elem_type->data.integral.is_signed) { + return LLVMBuildNSWAdd(g->builder, op1_value, op2_value, ""); + } else { + return LLVMBuildNUWAdd(g->builder, op1_value, op2_value, ""); + } + } else { + zig_unreachable(); + } } else { zig_unreachable(); } @@ -2961,7 +2999,7 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable, } static LLVMValueRef ir_render_ptr_cast(CodeGen *g, IrExecutable *executable, - IrInstructionPtrCast *instruction) + IrInstructionPtrCastGen *instruction) { ZigType *wanted_type = instruction->base.value.type; if (!type_has_bits(wanted_type)) { @@ -3149,11 +3187,11 @@ static LLVMValueRef ir_render_bool_not(CodeGen *g, IrExecutable *executable, IrI } static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable, - IrInstructionDeclVar *decl_var_instruction) + IrInstructionDeclVarGen *decl_var_instruction) { ZigVar *var = decl_var_instruction->var; - if (!type_has_bits(var->value->type)) + if (!type_has_bits(var->var_type)) return nullptr; if (var->ref_count == 0 && g->build_mode != BuildModeDebug) @@ -3161,34 +3199,16 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable, IrInstruction *init_value = decl_var_instruction->init_value; - bool have_init_expr = false; - - ConstExprValue *const_val = &init_value->value; - if (const_val->special == ConstValSpecialRuntime || const_val->special == ConstValSpecialStatic) - have_init_expr = true; + bool have_init_expr = !value_is_all_undef(&init_value->value); if (have_init_expr) { - assert(var->value->type == init_value->value.type); - ZigType *var_ptr_type = get_pointer_to_type_extra(g, var->value->type, false, false, + ZigType *var_ptr_type = get_pointer_to_type_extra(g, var->var_type, false, false, PtrLenSingle, var->align_bytes, 0, 0); LLVMValueRef llvm_init_val = ir_llvm_value(g, init_value); gen_assign_raw(g, var->value_ref, var_ptr_type, llvm_init_val); - } else { - bool want_safe = ir_want_runtime_safety(g, &decl_var_instruction->base); - if (want_safe) { - ZigType *usize = g->builtin_types.entry_usize; - uint64_t size_bytes = LLVMStoreSizeOfType(g->target_data_ref, var->value->type->type_ref); - assert(size_bytes > 0); - - assert(var->align_bytes > 0); - - // memset uninitialized memory to 0xa - LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0); - LLVMValueRef fill_char = LLVMConstInt(LLVMInt8Type(), 0xaa, false); - LLVMValueRef dest_ptr = LLVMBuildBitCast(g->builder, var->value_ref, ptr_u8, ""); - LLVMValueRef byte_count = LLVMConstInt(usize->type_ref, size_bytes, false); - ZigLLVMBuildMemSet(g->builder, dest_ptr, fill_char, byte_count, var->align_bytes, false); - } + } else if (ir_want_runtime_safety(g, &decl_var_instruction->base)) { + uint32_t align_bytes = (var->align_bytes == 0) ? get_abi_alignment(g, var->var_type) : var->align_bytes; + gen_undef_init(g, align_bytes, var->var_type, var->value_ref); } gen_var_debug_decl(g, var); @@ -3225,21 +3245,81 @@ static LLVMValueRef ir_render_load_ptr(CodeGen *g, IrExecutable *executable, IrI return LLVMBuildTrunc(g->builder, shifted_value, child_type->type_ref, ""); } -static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, IrInstructionStorePtr *instruction) { - LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr); - LLVMValueRef value = ir_llvm_value(g, instruction->value); +static bool value_is_all_undef_array(ConstExprValue *const_val, size_t len) { + switch (const_val->data.x_array.special) { + case ConstArraySpecialUndef: + return true; + case ConstArraySpecialBuf: + return false; + case ConstArraySpecialNone: + for (size_t i = 0; i < len; i += 1) { + if (!value_is_all_undef(&const_val->data.x_array.data.s_none.elements[i])) + return false; + } + return true; + } + zig_unreachable(); +} - assert(instruction->ptr->value.type->id == ZigTypeIdPointer); - ZigType *ptr_type = instruction->ptr->value.type; +static bool value_is_all_undef(ConstExprValue *const_val) { + switch (const_val->special) { + case ConstValSpecialRuntime: + return false; + case ConstValSpecialUndef: + return true; + case ConstValSpecialStatic: + if (const_val->type->id == ZigTypeIdStruct) { + for (size_t i = 0; i < const_val->type->data.structure.src_field_count; i += 1) { + if (!value_is_all_undef(&const_val->data.x_struct.fields[i])) + return false; + } + return true; + } else if (const_val->type->id == ZigTypeIdArray) { + return value_is_all_undef_array(const_val, const_val->type->data.array.len); + } else if (const_val->type->id == ZigTypeIdVector) { + return value_is_all_undef_array(const_val, const_val->type->data.vector.len); + } else { + return false; + } + } + zig_unreachable(); +} + +static void gen_undef_init(CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_type, LLVMValueRef ptr) { + assert(type_has_bits(value_type)); + uint64_t size_bytes = LLVMStoreSizeOfType(g->target_data_ref, value_type->type_ref); + assert(size_bytes > 0); + assert(ptr_align_bytes > 0); + // memset uninitialized memory to 0xaa + LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0); + LLVMValueRef fill_char = LLVMConstInt(LLVMInt8Type(), 0xaa, false); + LLVMValueRef dest_ptr = LLVMBuildBitCast(g->builder, ptr, ptr_u8, ""); + ZigType *usize = g->builtin_types.entry_usize; + LLVMValueRef byte_count = LLVMConstInt(usize->type_ref, size_bytes, false); + ZigLLVMBuildMemSet(g->builder, dest_ptr, fill_char, byte_count, ptr_align_bytes, false); +} - gen_assign_raw(g, ptr, ptr_type, value); +static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, IrInstructionStorePtr *instruction) { + ZigType *ptr_type = instruction->ptr->value.type; + assert(ptr_type->id == ZigTypeIdPointer); + if (!type_has_bits(ptr_type)) + return nullptr; + bool have_init_expr = !value_is_all_undef(&instruction->value->value); + if (have_init_expr) { + LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr); + LLVMValueRef value = ir_llvm_value(g, instruction->value); + gen_assign_raw(g, ptr, ptr_type, value); + } else if (ir_want_runtime_safety(g, &instruction->base)) { + gen_undef_init(g, get_ptr_align(g, ptr_type), instruction->value->value.type, + ir_llvm_value(g, instruction->ptr)); + } return nullptr; } static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutable *executable, IrInstructionVarPtr *instruction) { ZigVar *var = instruction->var; - if (type_has_bits(var->value->type)) { + if (type_has_bits(var->var_type)) { assert(var->value_ref); return var->value_ref; } else { @@ -3553,7 +3633,8 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executab LLVMPositionBuilderAtEnd(g->builder, ok_block); } - LLVMValueRef union_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr, union_type->data.unionation.gen_union_index, ""); + LLVMValueRef union_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr, + union_type->data.unionation.gen_union_index, ""); LLVMValueRef bitcasted_union_field_ptr = LLVMBuildBitCast(g->builder, union_field_ptr, field_type_ref, ""); return bitcasted_union_field_ptr; } @@ -3715,8 +3796,8 @@ static LLVMValueRef gen_non_null_bit(CodeGen *g, ZigType *maybe_type, LLVMValueR if (child_type->zero_bits) { return maybe_handle; } else { - bool maybe_is_ptr = type_is_codegen_pointer(child_type); - if (maybe_is_ptr) { + bool is_scalar = type_is_codegen_pointer(child_type) || child_type->id == ZigTypeIdErrorSet; + if (is_scalar) { return LLVMBuildICmp(g->builder, LLVMIntNE, maybe_handle, LLVMConstNull(maybe_type->type_ref), ""); } else { LLVMValueRef maybe_field_ptr = LLVMBuildStructGEP(g->builder, maybe_handle, maybe_null_index, ""); @@ -3731,17 +3812,17 @@ static LLVMValueRef ir_render_test_non_null(CodeGen *g, IrExecutable *executable return gen_non_null_bit(g, instruction->value->value.type, ir_llvm_value(g, instruction->value)); } -static LLVMValueRef ir_render_unwrap_maybe(CodeGen *g, IrExecutable *executable, - IrInstructionUnwrapOptional *instruction) +static LLVMValueRef ir_render_optional_unwrap_ptr(CodeGen *g, IrExecutable *executable, + IrInstructionOptionalUnwrapPtr *instruction) { - ZigType *ptr_type = instruction->value->value.type; + ZigType *ptr_type = instruction->base_ptr->value.type; assert(ptr_type->id == ZigTypeIdPointer); ZigType *maybe_type = ptr_type->data.pointer.child_type; assert(maybe_type->id == ZigTypeIdOptional); ZigType *child_type = maybe_type->data.maybe.child_type; - LLVMValueRef maybe_ptr = ir_llvm_value(g, instruction->value); - LLVMValueRef maybe_handle = get_handle_value(g, maybe_ptr, maybe_type, ptr_type); + LLVMValueRef maybe_ptr = ir_llvm_value(g, instruction->base_ptr); if (ir_want_runtime_safety(g, &instruction->base) && instruction->safety_check_on) { + LLVMValueRef maybe_handle = get_handle_value(g, maybe_ptr, maybe_type, ptr_type); LLVMValueRef non_null_bit = gen_non_null_bit(g, maybe_type, maybe_handle); LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapOptionalOk"); LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapOptionalFail"); @@ -3755,8 +3836,8 @@ static LLVMValueRef ir_render_unwrap_maybe(CodeGen *g, IrExecutable *executable, if (child_type->zero_bits) { return nullptr; } else { - bool maybe_is_ptr = type_is_codegen_pointer(child_type); - if (maybe_is_ptr) { + bool is_scalar = type_is_codegen_pointer(child_type) || child_type->id == ZigTypeIdErrorSet; + if (is_scalar) { return maybe_ptr; } else { LLVMValueRef maybe_struct_ref = get_handle_value(g, maybe_ptr, maybe_type, ptr_type); @@ -4174,7 +4255,7 @@ static LLVMAtomicRMWBinOp to_LLVMAtomicRMWBinOp(AtomicRmwOp op, bool is_signed) zig_unreachable(); } -static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutable *executable, IrInstructionCmpxchg *instruction) { +static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutable *executable, IrInstructionCmpxchgGen *instruction) { LLVMValueRef ptr_val = ir_llvm_value(g, instruction->ptr); LLVMValueRef cmp_val = ir_llvm_value(g, instruction->cmp_value); LLVMValueRef new_val = ir_llvm_value(g, instruction->new_value); @@ -4189,18 +4270,18 @@ static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutable *executable, IrIn assert(maybe_type->id == ZigTypeIdOptional); ZigType *child_type = maybe_type->data.maybe.child_type; - if (type_is_codegen_pointer(child_type)) { + if (!handle_is_ptr(maybe_type)) { LLVMValueRef payload_val = LLVMBuildExtractValue(g->builder, result_val, 0, ""); LLVMValueRef success_bit = LLVMBuildExtractValue(g->builder, result_val, 1, ""); return LLVMBuildSelect(g->builder, success_bit, LLVMConstNull(child_type->type_ref), payload_val, ""); } assert(instruction->tmp_ptr != nullptr); - assert(type_has_bits(instruction->type)); + assert(type_has_bits(child_type)); LLVMValueRef payload_val = LLVMBuildExtractValue(g->builder, result_val, 0, ""); LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, maybe_child_index, ""); - gen_assign_raw(g, val_ptr, get_pointer_to_type(g, instruction->type, false), payload_val); + gen_assign_raw(g, val_ptr, get_pointer_to_type(g, child_type, false), payload_val); LLVMValueRef success_bit = LLVMBuildExtractValue(g->builder, result_val, 1, ""); LLVMValueRef nonnull_bit = LLVMBuildNot(g->builder, success_bit, ""); @@ -4351,6 +4432,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst assert(array_type->data.structure.is_slice); assert(LLVMGetTypeKind(LLVMTypeOf(array_ptr)) == LLVMPointerTypeKind); assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(array_ptr))) == LLVMStructTypeKind); + assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(tmp_struct_ptr))) == LLVMStructTypeKind); size_t ptr_index = array_type->data.structure.fields[slice_ptr_index].gen_index; assert(ptr_index != SIZE_MAX); @@ -4540,12 +4622,14 @@ static LLVMValueRef ir_render_test_err(CodeGen *g, IrExecutable *executable, IrI return LLVMBuildICmp(g->builder, LLVMIntNE, err_val, zero, ""); } -static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, IrExecutable *executable, IrInstructionUnwrapErrCode *instruction) { - ZigType *ptr_type = instruction->value->value.type; +static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, IrExecutable *executable, + IrInstructionUnwrapErrCode *instruction) +{ + ZigType *ptr_type = instruction->err_union->value.type; assert(ptr_type->id == ZigTypeIdPointer); ZigType *err_union_type = ptr_type->data.pointer.child_type; ZigType *payload_type = err_union_type->data.error_union.payload_type; - LLVMValueRef err_union_ptr = ir_llvm_value(g, instruction->value); + LLVMValueRef err_union_ptr = ir_llvm_value(g, instruction->err_union); LLVMValueRef err_union_handle = get_handle_value(g, err_union_ptr, err_union_type, ptr_type); if (type_has_bits(payload_type)) { @@ -4556,7 +4640,13 @@ static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, IrExecutable *executab } } -static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *executable, IrInstructionUnwrapErrPayload *instruction) { +static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *executable, + IrInstructionUnwrapErrPayload *instruction) +{ + bool want_safety = ir_want_runtime_safety(g, &instruction->base) && instruction->safety_check_on && + g->errors_by_index.length > 1; + if (!want_safety && !type_has_bits(instruction->base.value.type)) + return nullptr; ZigType *ptr_type = instruction->value->value.type; assert(ptr_type->id == ZigTypeIdPointer); ZigType *err_union_type = ptr_type->data.pointer.child_type; @@ -4568,7 +4658,7 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *execu return err_union_handle; } - if (ir_want_runtime_safety(g, &instruction->base) && instruction->safety_check_on && g->errors_by_index.length > 1) { + if (want_safety) { LLVMValueRef err_val; if (type_has_bits(payload_type)) { LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, ""); @@ -4607,7 +4697,7 @@ static LLVMValueRef ir_render_maybe_wrap(CodeGen *g, IrExecutable *executable, I } LLVMValueRef payload_val = ir_llvm_value(g, instruction->value); - if (type_is_codegen_pointer(child_type)) { + if (type_is_codegen_pointer(child_type) || child_type->id == ZigTypeIdErrorSet) { return payload_val; } @@ -5109,6 +5199,32 @@ static LLVMValueRef ir_render_bit_reverse(CodeGen *g, IrExecutable *executable, return LLVMBuildCall(g->builder, fn_val, &op, 1, ""); } +static LLVMValueRef ir_render_vector_to_array(CodeGen *g, IrExecutable *executable, + IrInstructionVectorToArray *instruction) +{ + ZigType *array_type = instruction->base.value.type; + assert(array_type->id == ZigTypeIdArray); + assert(handle_is_ptr(array_type)); + assert(instruction->tmp_ptr); + LLVMValueRef vector = ir_llvm_value(g, instruction->vector); + LLVMValueRef casted_ptr = LLVMBuildBitCast(g->builder, instruction->tmp_ptr, + LLVMPointerType(instruction->vector->value.type->type_ref, 0), ""); + gen_store_untyped(g, vector, casted_ptr, 0, false); + return instruction->tmp_ptr; +} + +static LLVMValueRef ir_render_array_to_vector(CodeGen *g, IrExecutable *executable, + IrInstructionArrayToVector *instruction) +{ + ZigType *vector_type = instruction->base.value.type; + assert(vector_type->id == ZigTypeIdVector); + assert(!handle_is_ptr(vector_type)); + LLVMValueRef array_ptr = ir_llvm_value(g, instruction->array); + LLVMValueRef casted_ptr = LLVMBuildBitCast(g->builder, array_ptr, + LLVMPointerType(vector_type->type_ref, 0), ""); + return gen_load_untyped(g, casted_ptr, 0, false, ""); +} + static void set_debug_location(CodeGen *g, IrInstruction *instruction) { AstNode *source_node = instruction->source_node; Scope *scope = instruction->scope; @@ -5148,6 +5264,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, case IrInstructionIdCUndef: case IrInstructionIdEmbedFile: case IrInstructionIdIntType: + case IrInstructionIdVectorType: case IrInstructionIdMemberCount: case IrInstructionIdMemberType: case IrInstructionIdMemberName: @@ -5184,12 +5301,15 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, case IrInstructionIdToBytes: case IrInstructionIdEnumToInt: case IrInstructionIdCheckRuntimeScope: + case IrInstructionIdDeclVarSrc: + case IrInstructionIdPtrCastSrc: + case IrInstructionIdCmpxchgSrc: zig_unreachable(); + case IrInstructionIdDeclVarGen: + return ir_render_decl_var(g, executable, (IrInstructionDeclVarGen *)instruction); case IrInstructionIdReturn: return ir_render_return(g, executable, (IrInstructionReturn *)instruction); - case IrInstructionIdDeclVar: - return ir_render_decl_var(g, executable, (IrInstructionDeclVar *)instruction); case IrInstructionIdBinOp: return ir_render_bin_op(g, executable, (IrInstructionBinOp *)instruction); case IrInstructionIdCast: @@ -5220,8 +5340,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, return ir_render_asm(g, executable, (IrInstructionAsm *)instruction); case IrInstructionIdTestNonNull: return ir_render_test_non_null(g, executable, (IrInstructionTestNonNull *)instruction); - case IrInstructionIdUnwrapOptional: - return ir_render_unwrap_maybe(g, executable, (IrInstructionUnwrapOptional *)instruction); + case IrInstructionIdOptionalUnwrapPtr: + return ir_render_optional_unwrap_ptr(g, executable, (IrInstructionOptionalUnwrapPtr *)instruction); case IrInstructionIdClz: return ir_render_clz(g, executable, (IrInstructionClz *)instruction); case IrInstructionIdCtz: @@ -5236,8 +5356,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, return ir_render_ref(g, executable, (IrInstructionRef *)instruction); case IrInstructionIdErrName: return ir_render_err_name(g, executable, (IrInstructionErrName *)instruction); - case IrInstructionIdCmpxchg: - return ir_render_cmpxchg(g, executable, (IrInstructionCmpxchg *)instruction); + case IrInstructionIdCmpxchgGen: + return ir_render_cmpxchg(g, executable, (IrInstructionCmpxchgGen *)instruction); case IrInstructionIdFence: return ir_render_fence(g, executable, (IrInstructionFence *)instruction); case IrInstructionIdTruncate: @@ -5278,8 +5398,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, return ir_render_struct_init(g, executable, (IrInstructionStructInit *)instruction); case IrInstructionIdUnionInit: return ir_render_union_init(g, executable, (IrInstructionUnionInit *)instruction); - case IrInstructionIdPtrCast: - return ir_render_ptr_cast(g, executable, (IrInstructionPtrCast *)instruction); + case IrInstructionIdPtrCastGen: + return ir_render_ptr_cast(g, executable, (IrInstructionPtrCastGen *)instruction); case IrInstructionIdBitCast: return ir_render_bit_cast(g, executable, (IrInstructionBitCast *)instruction); case IrInstructionIdWidenOrShorten: @@ -5350,6 +5470,10 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, return ir_render_bswap(g, executable, (IrInstructionBswap *)instruction); case IrInstructionIdBitReverse: return ir_render_bit_reverse(g, executable, (IrInstructionBitReverse *)instruction); + case IrInstructionIdArrayToVector: + return ir_render_array_to_vector(g, executable, (IrInstructionArrayToVector *)instruction); + case IrInstructionIdVectorToArray: + return ir_render_vector_to_array(g, executable, (IrInstructionVectorToArray *)instruction); } zig_unreachable(); } @@ -5377,6 +5501,9 @@ static void ir_render(CodeGen *g, ZigFn *fn_entry) { static LLVMValueRef gen_const_ptr_struct_recursive(CodeGen *g, ConstExprValue *struct_const_val, size_t field_index); static LLVMValueRef gen_const_ptr_array_recursive(CodeGen *g, ConstExprValue *array_const_val, size_t index); static LLVMValueRef gen_const_ptr_union_recursive(CodeGen *g, ConstExprValue *union_const_val); +static LLVMValueRef gen_const_ptr_err_union_code_recursive(CodeGen *g, ConstExprValue *err_union_const_val); +static LLVMValueRef gen_const_ptr_err_union_payload_recursive(CodeGen *g, ConstExprValue *err_union_const_val); +static LLVMValueRef gen_const_ptr_optional_payload_recursive(CodeGen *g, ConstExprValue *optional_const_val); static LLVMValueRef gen_parent_ptr(CodeGen *g, ConstExprValue *val, ConstParent *parent) { switch (parent->id) { @@ -5387,6 +5514,12 @@ static LLVMValueRef gen_parent_ptr(CodeGen *g, ConstExprValue *val, ConstParent case ConstParentIdStruct: return gen_const_ptr_struct_recursive(g, parent->data.p_struct.struct_val, parent->data.p_struct.field_index); + case ConstParentIdErrUnionCode: + return gen_const_ptr_err_union_code_recursive(g, parent->data.p_err_union_code.err_union_val); + case ConstParentIdErrUnionPayload: + return gen_const_ptr_err_union_payload_recursive(g, parent->data.p_err_union_payload.err_union_val); + case ConstParentIdOptionalPayload: + return gen_const_ptr_optional_payload_recursive(g, parent->data.p_optional_payload.optional_val); case ConstParentIdArray: return gen_const_ptr_array_recursive(g, parent->data.p_array.array_val, parent->data.p_array.elem_index); @@ -5402,7 +5535,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.data.s_none.parent; + ConstParent *parent = &array_const_val->parent; LLVMValueRef base_ptr = gen_parent_ptr(g, array_const_val, parent); LLVMTypeKind el_type = LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(base_ptr))); @@ -5427,7 +5560,7 @@ static LLVMValueRef gen_const_ptr_array_recursive(CodeGen *g, ConstExprValue *ar } static LLVMValueRef gen_const_ptr_struct_recursive(CodeGen *g, ConstExprValue *struct_const_val, size_t field_index) { - ConstParent *parent = &struct_const_val->data.x_struct.parent; + ConstParent *parent = &struct_const_val->parent; LLVMValueRef base_ptr = gen_parent_ptr(g, struct_const_val, parent); ZigType *u32 = g->builtin_types.entry_u32; @@ -5438,8 +5571,44 @@ static LLVMValueRef gen_const_ptr_struct_recursive(CodeGen *g, ConstExprValue *s return LLVMConstInBoundsGEP(base_ptr, indices, 2); } +static LLVMValueRef gen_const_ptr_err_union_code_recursive(CodeGen *g, ConstExprValue *err_union_const_val) { + ConstParent *parent = &err_union_const_val->parent; + LLVMValueRef base_ptr = gen_parent_ptr(g, err_union_const_val, parent); + + ZigType *u32 = g->builtin_types.entry_u32; + LLVMValueRef indices[] = { + LLVMConstNull(u32->type_ref), + LLVMConstInt(u32->type_ref, err_union_err_index, false), + }; + return LLVMConstInBoundsGEP(base_ptr, indices, 2); +} + +static LLVMValueRef gen_const_ptr_err_union_payload_recursive(CodeGen *g, ConstExprValue *err_union_const_val) { + ConstParent *parent = &err_union_const_val->parent; + LLVMValueRef base_ptr = gen_parent_ptr(g, err_union_const_val, parent); + + ZigType *u32 = g->builtin_types.entry_u32; + LLVMValueRef indices[] = { + LLVMConstNull(u32->type_ref), + LLVMConstInt(u32->type_ref, err_union_payload_index, false), + }; + return LLVMConstInBoundsGEP(base_ptr, indices, 2); +} + +static LLVMValueRef gen_const_ptr_optional_payload_recursive(CodeGen *g, ConstExprValue *optional_const_val) { + ConstParent *parent = &optional_const_val->parent; + LLVMValueRef base_ptr = gen_parent_ptr(g, optional_const_val, parent); + + ZigType *u32 = g->builtin_types.entry_u32; + LLVMValueRef indices[] = { + LLVMConstNull(u32->type_ref), + LLVMConstInt(u32->type_ref, maybe_child_index, false), + }; + return LLVMConstInBoundsGEP(base_ptr, indices, 2); +} + static LLVMValueRef gen_const_ptr_union_recursive(CodeGen *g, ConstExprValue *union_const_val) { - ConstParent *parent = &union_const_val->data.x_union.parent; + ConstParent *parent = &union_const_val->parent; LLVMValueRef base_ptr = gen_parent_ptr(g, union_const_val, parent); ZigType *u32 = g->builtin_types.entry_u32; @@ -5509,6 +5678,8 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con } case ZigTypeIdArray: zig_panic("TODO bit pack an array"); + case ZigTypeIdVector: + zig_panic("TODO bit pack a vector"); case ZigTypeIdUnion: zig_panic("TODO bit pack a union"); case ZigTypeIdStruct: @@ -5609,6 +5780,63 @@ static LLVMValueRef gen_const_val_ptr(CodeGen *g, ConstExprValue *const_val, con render_const_val_global(g, const_val, ""); return ptr_val; } + case ConstPtrSpecialBaseErrorUnionCode: + { + render_const_val_global(g, const_val, name); + ConstExprValue *err_union_const_val = const_val->data.x_ptr.data.base_err_union_code.err_union_val; + assert(err_union_const_val->type->id == ZigTypeIdErrorUnion); + if (err_union_const_val->type->zero_bits) { + // make this a null pointer + ZigType *usize = g->builtin_types.entry_usize; + const_val->global_refs->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->type_ref), + const_val->type->type_ref); + render_const_val_global(g, const_val, ""); + return const_val->global_refs->llvm_value; + } + LLVMValueRef uncasted_ptr_val = gen_const_ptr_err_union_code_recursive(g, err_union_const_val); + LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, const_val->type->type_ref); + const_val->global_refs->llvm_value = ptr_val; + render_const_val_global(g, const_val, ""); + return ptr_val; + } + case ConstPtrSpecialBaseErrorUnionPayload: + { + render_const_val_global(g, const_val, name); + ConstExprValue *err_union_const_val = const_val->data.x_ptr.data.base_err_union_payload.err_union_val; + assert(err_union_const_val->type->id == ZigTypeIdErrorUnion); + if (err_union_const_val->type->zero_bits) { + // make this a null pointer + ZigType *usize = g->builtin_types.entry_usize; + const_val->global_refs->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->type_ref), + const_val->type->type_ref); + render_const_val_global(g, const_val, ""); + return const_val->global_refs->llvm_value; + } + LLVMValueRef uncasted_ptr_val = gen_const_ptr_err_union_payload_recursive(g, err_union_const_val); + LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, const_val->type->type_ref); + const_val->global_refs->llvm_value = ptr_val; + render_const_val_global(g, const_val, ""); + return ptr_val; + } + case ConstPtrSpecialBaseOptionalPayload: + { + render_const_val_global(g, const_val, name); + ConstExprValue *optional_const_val = const_val->data.x_ptr.data.base_optional_payload.optional_val; + assert(optional_const_val->type->id == ZigTypeIdOptional); + if (optional_const_val->type->zero_bits) { + // make this a null pointer + ZigType *usize = g->builtin_types.entry_usize; + const_val->global_refs->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->type_ref), + const_val->type->type_ref); + render_const_val_global(g, const_val, ""); + return const_val->global_refs->llvm_value; + } + LLVMValueRef uncasted_ptr_val = gen_const_ptr_optional_payload_recursive(g, optional_const_val); + LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, const_val->type->type_ref); + const_val->global_refs->llvm_value = ptr_val; + render_const_val_global(g, const_val, ""); + return ptr_val; + } case ConstPtrSpecialHardCodedAddr: { render_const_val_global(g, const_val, name); @@ -5621,10 +5849,17 @@ static LLVMValueRef gen_const_val_ptr(CodeGen *g, ConstExprValue *const_val, con } case ConstPtrSpecialFunction: return LLVMConstBitCast(fn_llvm_value(g, const_val->data.x_ptr.data.fn.fn_entry), const_val->type->type_ref); + case ConstPtrSpecialNull: + return LLVMConstNull(const_val->type->type_ref); } zig_unreachable(); } +static LLVMValueRef gen_const_val_err_set(CodeGen *g, ConstExprValue *const_val, const char *name) { + uint64_t value = (const_val->data.x_err_set == nullptr) ? 0 : const_val->data.x_err_set->value; + return LLVMConstInt(g->builtin_types.entry_global_error_set->type_ref, value, false); +} + static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const char *name) { Error err; @@ -5644,9 +5879,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c case ZigTypeIdInt: return bigint_to_llvm_const(type_entry->type_ref, &const_val->data.x_bigint); case ZigTypeIdErrorSet: - assert(const_val->data.x_err_set != nullptr); - return LLVMConstInt(g->builtin_types.entry_global_error_set->type_ref, - const_val->data.x_err_set->value, false); + return gen_const_val_err_set(g, const_val, name); case ZigTypeIdFloat: switch (type_entry->data.floating.bit_count) { case 16: @@ -5680,6 +5913,8 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c return LLVMConstInt(LLVMInt1Type(), const_val->data.x_optional ? 1 : 0, false); } else if (type_is_codegen_pointer(child_type)) { return gen_const_val_ptr(g, const_val, name); + } else if (child_type->id == ZigTypeIdErrorSet) { + return gen_const_val_err_set(g, const_val, name); } else { LLVMValueRef child_val; LLVMValueRef maybe_val; @@ -5816,7 +6051,33 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c return LLVMConstString(buf_ptr(buf), (unsigned)buf_len(buf), true); } } + zig_unreachable(); } + case ZigTypeIdVector: { + uint32_t len = type_entry->data.vector.len; + switch (const_val->data.x_array.special) { + case ConstArraySpecialUndef: + return LLVMGetUndef(type_entry->type_ref); + case ConstArraySpecialNone: { + LLVMValueRef *values = allocate<LLVMValueRef>(len); + for (uint64_t i = 0; i < len; i += 1) { + ConstExprValue *elem_value = &const_val->data.x_array.data.s_none.elements[i]; + values[i] = gen_const_val(g, elem_value, ""); + } + return LLVMConstVector(values, len); + } + case ConstArraySpecialBuf: { + Buf *buf = const_val->data.x_array.data.s_buf; + assert(buf_len(buf) == len); + LLVMValueRef *values = allocate<LLVMValueRef>(len); + for (uint64_t i = 0; i < len; i += 1) { + values[i] = LLVMConstInt(g->builtin_types.entry_u8->type_ref, buf_ptr(buf)[i], false); + } + return LLVMConstVector(values, len); + } + } + zig_unreachable(); + } case ZigTypeIdUnion: { LLVMTypeRef union_type_ref = type_entry->data.unionation.union_type_ref; @@ -5914,7 +6175,8 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c ZigType *err_set_type = type_entry->data.error_union.err_set_type; if (!type_has_bits(payload_type)) { assert(type_has_bits(err_set_type)); - uint64_t value = const_val->data.x_err_union.err ? const_val->data.x_err_union.err->value : 0; + ErrorTableEntry *err_set = const_val->data.x_err_union.error_set->data.x_err_set; + uint64_t value = (err_set == nullptr) ? 0 : err_set->value; return LLVMConstInt(g->err_tag_type->type_ref, value, false); } else if (!type_has_bits(err_set_type)) { assert(type_has_bits(payload_type)); @@ -5923,8 +6185,9 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c 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); + ErrorTableEntry *err_set = const_val->data.x_err_union.error_set->data.x_err_set; + if (err_set != nullptr) { + err_tag_value = LLVMConstInt(g->err_tag_type->type_ref, err_set->value, false); err_payload_value = LLVMConstNull(payload_type->type_ref); make_unnamed_struct = false; } else { @@ -6130,10 +6393,13 @@ static void do_code_gen(CodeGen *g) { TldVar *tld_var = g->global_vars.at(i); ZigVar *var = tld_var->var; - if (var->value->type->id == ZigTypeIdComptimeFloat) { + if (var->var_type->id == ZigTypeIdComptimeFloat) { // Generate debug info for it but that's it. - ConstExprValue *const_val = var->value; + ConstExprValue *const_val = var->const_value; assert(const_val->special != ConstValSpecialRuntime); + if (const_val->type != var->var_type) { + zig_panic("TODO debug info for var with ptr casted value"); + } ZigType *var_type = g->builtin_types.entry_f128; ConstExprValue coerced_value; coerced_value.special = ConstValSpecialStatic; @@ -6144,10 +6410,13 @@ static void do_code_gen(CodeGen *g) { continue; } - if (var->value->type->id == ZigTypeIdComptimeInt) { + if (var->var_type->id == ZigTypeIdComptimeInt) { // Generate debug info for it but that's it. - ConstExprValue *const_val = var->value; + ConstExprValue *const_val = var->const_value; assert(const_val->special != ConstValSpecialRuntime); + if (const_val->type != var->var_type) { + zig_panic("TODO debug info for var with ptr casted value"); + } size_t bits_needed = bigint_bits_needed(&const_val->data.x_bigint); if (bits_needed < 8) { bits_needed = 8; @@ -6158,7 +6427,7 @@ static void do_code_gen(CodeGen *g) { continue; } - if (!type_has_bits(var->value->type)) + if (!type_has_bits(var->var_type)) continue; assert(var->decl_node); @@ -6167,9 +6436,9 @@ static void do_code_gen(CodeGen *g) { if (var->linkage == VarLinkageExternal) { LLVMValueRef existing_llvm_var = LLVMGetNamedGlobal(g->module, buf_ptr(&var->name)); if (existing_llvm_var) { - global_value = LLVMConstBitCast(existing_llvm_var, LLVMPointerType(var->value->type->type_ref, 0)); + global_value = LLVMConstBitCast(existing_llvm_var, LLVMPointerType(var->var_type->type_ref, 0)); } else { - global_value = LLVMAddGlobal(g->module, var->value->type->type_ref, buf_ptr(&var->name)); + global_value = LLVMAddGlobal(g->module, var->var_type->type_ref, buf_ptr(&var->name)); // TODO debug info for the extern variable LLVMSetLinkage(global_value, LLVMExternalLinkage); @@ -6180,9 +6449,9 @@ static void do_code_gen(CodeGen *g) { } else { bool exported = (var->linkage == VarLinkageExport); const char *mangled_name = buf_ptr(get_mangled_name(g, &var->name, exported)); - render_const_val(g, var->value, mangled_name); - render_const_val_global(g, var->value, mangled_name); - global_value = var->value->global_refs->llvm_global; + render_const_val(g, var->const_value, mangled_name); + render_const_val_global(g, var->const_value, mangled_name); + global_value = var->const_value->global_refs->llvm_global; if (exported) { LLVMSetLinkage(global_value, LLVMExternalLinkage); @@ -6194,8 +6463,10 @@ static void do_code_gen(CodeGen *g) { LLVMSetAlignment(global_value, var->align_bytes); // TODO debug info for function pointers - if (var->gen_is_const && var->value->type->id != ZigTypeIdFn) { - gen_global_var(g, var, var->value->global_refs->llvm_value, var->value->type); + // Here we use const_value->type because that's the type of the llvm global, + // which we const ptr cast upon use to whatever it needs to be. + if (var->gen_is_const && var->const_value->type->id != ZigTypeIdFn) { + gen_global_var(g, var, var->const_value->global_refs->llvm_value, var->const_value->type); } LLVMSetGlobalConstant(global_value, var->gen_is_const); @@ -6249,6 +6520,7 @@ static void do_code_gen(CodeGen *g) { IrInstruction *instruction = fn_table_entry->alloca_list.at(alloca_i); LLVMValueRef *slot; ZigType *slot_type = instruction->value.type; + uint32_t alignment_bytes = 0; if (instruction->id == IrInstructionIdCast) { IrInstructionCast *cast_instruction = (IrInstructionCast *)instruction; slot = &cast_instruction->tmp_ptr; @@ -6281,13 +6553,17 @@ static void do_code_gen(CodeGen *g) { } else if (instruction->id == IrInstructionIdErrWrapCode) { IrInstructionErrWrapCode *err_wrap_code_instruction = (IrInstructionErrWrapCode *)instruction; slot = &err_wrap_code_instruction->tmp_ptr; - } else if (instruction->id == IrInstructionIdCmpxchg) { - IrInstructionCmpxchg *cmpxchg_instruction = (IrInstructionCmpxchg *)instruction; + } else if (instruction->id == IrInstructionIdCmpxchgGen) { + IrInstructionCmpxchgGen *cmpxchg_instruction = (IrInstructionCmpxchgGen *)instruction; slot = &cmpxchg_instruction->tmp_ptr; + } else if (instruction->id == IrInstructionIdVectorToArray) { + IrInstructionVectorToArray *vector_to_array_instruction = (IrInstructionVectorToArray *)instruction; + alignment_bytes = get_abi_alignment(g, vector_to_array_instruction->vector->value.type); + slot = &vector_to_array_instruction->tmp_ptr; } else { zig_unreachable(); } - *slot = build_alloca(g, slot_type, "", get_abi_alignment(g, slot_type)); + *slot = build_alloca(g, slot_type, "", alignment_bytes); } ImportTableEntry *import = get_scope_import(&fn_table_entry->fndef_scope->base); @@ -6304,12 +6580,12 @@ static void do_code_gen(CodeGen *g) { for (size_t var_i = 0; var_i < fn_table_entry->variable_list.length; var_i += 1) { ZigVar *var = fn_table_entry->variable_list.at(var_i); - if (!type_has_bits(var->value->type)) { + if (!type_has_bits(var->var_type)) { continue; } if (ir_get_var_is_comptime(var)) continue; - switch (type_requires_comptime(g, var->value->type)) { + switch (type_requires_comptime(g, var->var_type)) { case ReqCompTimeInvalid: zig_unreachable(); case ReqCompTimeYes: @@ -6319,11 +6595,11 @@ static void do_code_gen(CodeGen *g) { } if (var->src_arg_index == SIZE_MAX) { - var->value_ref = build_alloca(g, var->value->type, buf_ptr(&var->name), var->align_bytes); + var->value_ref = build_alloca(g, var->var_type, buf_ptr(&var->name), var->align_bytes); var->di_loc_var = ZigLLVMCreateAutoVariable(g->dbuilder, get_di_scope(g, var->parent_scope), buf_ptr(&var->name), import->di_file, (unsigned)(var->decl_node->line + 1), - var->value->type->di_type, !g->strip_debug_symbols, 0); + var->var_type->di_type, !g->strip_debug_symbols, 0); } else if (is_c_abi) { fn_walk_var.data.vars.var = var; @@ -6333,16 +6609,16 @@ static void do_code_gen(CodeGen *g) { ZigType *gen_type; FnGenParamInfo *gen_info = &fn_table_entry->type_entry->data.fn.gen_param_info[var->src_arg_index]; - if (handle_is_ptr(var->value->type)) { + if (handle_is_ptr(var->var_type)) { if (gen_info->is_byval) { - gen_type = var->value->type; + gen_type = var->var_type; } else { gen_type = gen_info->type; } var->value_ref = LLVMGetParam(fn, (unsigned)var->gen_arg_index); } else { - gen_type = var->value->type; - var->value_ref = build_alloca(g, var->value->type, buf_ptr(&var->name), var->align_bytes); + gen_type = var->var_type; + var->value_ref = build_alloca(g, var->var_type, buf_ptr(&var->name), var->align_bytes); } if (var->decl_node) { var->di_loc_var = ZigLLVMCreateParameterVariable(g->dbuilder, get_di_scope(g, var->parent_scope), @@ -6742,6 +7018,7 @@ static void define_builtin_fns(CodeGen *g) { create_builtin_fn(g, BuiltinFnIdCompileErr, "compileError", 1); create_builtin_fn(g, BuiltinFnIdCompileLog, "compileLog", SIZE_MAX); create_builtin_fn(g, BuiltinFnIdIntType, "IntType", 2); // TODO rename to Int + create_builtin_fn(g, BuiltinFnIdVectorType, "Vector", 2); create_builtin_fn(g, BuiltinFnIdSetCold, "setCold", 1); create_builtin_fn(g, BuiltinFnIdSetRuntimeSafety, "setRuntimeSafety", 1); create_builtin_fn(g, BuiltinFnIdSetFloatMode, "setFloatMode", 1); @@ -6967,6 +7244,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { " ArgTuple: void,\n" " Opaque: void,\n" " Promise: Promise,\n" + " Vector: Vector,\n" "\n\n" " pub const Int = struct {\n" " is_signed: bool,\n" @@ -7085,6 +7363,11 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { " child: ?type,\n" " };\n" "\n" + " pub const Vector = struct {\n" + " len: u32,\n" + " child: type,\n" + " };\n" + "\n" " pub const Definition = struct {\n" " name: []const u8,\n" " is_pub: bool,\n" @@ -7153,6 +7436,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { buf_appendf(contents, "pub const endian = %s;\n", endian_str); } buf_appendf(contents, "pub const is_test = %s;\n", bool_to_str(g->is_test_build)); + buf_appendf(contents, "pub const single_threaded = %s;\n", bool_to_str(g->is_single_threaded)); buf_appendf(contents, "pub const os = Os.%s;\n", cur_os); buf_appendf(contents, "pub const arch = Arch.%s;\n", cur_arch); buf_appendf(contents, "pub const environ = Environ.%s;\n", cur_environ); @@ -7187,6 +7471,7 @@ static Error define_builtin_compile_vars(CodeGen *g) { cache_buf(&cache_hash, compiler_id); cache_int(&cache_hash, g->build_mode); cache_bool(&cache_hash, g->is_test_build); + cache_bool(&cache_hash, g->is_single_threaded); cache_int(&cache_hash, g->zig_target.arch.arch); cache_int(&cache_hash, g->zig_target.arch.sub_arch); cache_int(&cache_hash, g->zig_target.vendor); @@ -7458,9 +7743,9 @@ static void create_test_compile_var_and_add_test_runner(CodeGen *g) { 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; - this_val->data.x_struct.parent.data.p_array.array_val = test_fn_array; - this_val->data.x_struct.parent.data.p_array.elem_index = i; + this_val->parent.id = ConstParentIdArray; + this_val->parent.data.p_array.array_val = test_fn_array; + this_val->parent.data.p_array.elem_index = i; this_val->data.x_struct.fields = create_const_vals(2); ConstExprValue *name_field = &this_val->data.x_struct.fields[0]; @@ -7656,6 +7941,9 @@ static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, ZigType *type_e case ZigTypeIdArray: prepend_c_type_to_decl_list(g, gen_h, type_entry->data.array.child_type); return; + case ZigTypeIdVector: + prepend_c_type_to_decl_list(g, gen_h, type_entry->data.vector.elem_type); + return; case ZigTypeIdOptional: prepend_c_type_to_decl_list(g, gen_h, type_entry->data.maybe.child_type); return; @@ -7787,6 +8075,8 @@ static void get_c_type(CodeGen *g, GenH *gen_h, ZigType *type_entry, Buf *out_bu buf_appendf(out_buf, "%s", buf_ptr(child_buf)); return; } + case ZigTypeIdVector: + zig_panic("TODO implement get_c_type for vector types"); case ZigTypeIdErrorUnion: case ZigTypeIdErrorSet: case ZigTypeIdFn: @@ -7952,6 +8242,7 @@ static void gen_h_file(CodeGen *g) { case ZigTypeIdOptional: case ZigTypeIdFn: case ZigTypeIdPromise: + case ZigTypeIdVector: zig_unreachable(); case ZigTypeIdEnum: if (type_entry->data.enumeration.layout == ContainerLayoutExtern) { @@ -8099,6 +8390,7 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { cache_bool(ch, g->is_static); cache_bool(ch, g->strip_debug_symbols); cache_bool(ch, g->is_test_build); + cache_bool(ch, g->is_single_threaded); cache_bool(ch, g->is_native_target); cache_bool(ch, g->linker_rdynamic); cache_bool(ch, g->no_rosegment_workaround); |
