aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2016-12-25 04:15:23 -0500
committerAndrew Kelley <superjoe30@gmail.com>2016-12-25 04:15:23 -0500
commitf47dea2a2ee5e2351736fa416d82c1ed38bfe0f1 (patch)
treedb58b40ab7bc848c6fdbf19007c8d303fb0d7185 /src/codegen.cpp
parent6f91fb4c37a676002ccb68b78bea8044ba44b7e2 (diff)
downloadzig-f47dea2a2ee5e2351736fa416d82c1ed38bfe0f1.tar.gz
zig-f47dea2a2ee5e2351736fa416d82c1ed38bfe0f1.zip
IR: support compile time global pointer reinterpret
this required moving the place we store types to ConstExprValue
Diffstat (limited to 'src/codegen.cpp')
-rw-r--r--src/codegen.cpp372
1 files changed, 179 insertions, 193 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp
index df5e6d1787..123caea75c 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -225,8 +225,8 @@ void codegen_set_rdynamic(CodeGen *g, bool rdynamic) {
g->linker_rdynamic = rdynamic;
}
-static void render_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *const_val);
-static void render_const_val_global(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *const_val);
+static void render_const_val(CodeGen *g, ConstExprValue *const_val);
+static void render_const_val_global(CodeGen *g, ConstExprValue *const_val);
static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) {
if (fn_table_entry->llvm_value)
@@ -645,18 +645,14 @@ static LLVMValueRef gen_struct_memcpy(CodeGen *g, LLVMValueRef src, LLVMValueRef
return LLVMBuildCall(g->builder, g->memcpy_fn_val, params, 5, "");
}
-static LLVMValueRef gen_assign_raw(CodeGen *g,
- LLVMValueRef target_ref, LLVMValueRef value,
- TypeTableEntry *op1_type, TypeTableEntry *op2_type)
+static LLVMValueRef gen_assign_raw(CodeGen *g, LLVMValueRef target_ref, LLVMValueRef value,
+ TypeTableEntry *child_type)
{
- if (!type_has_bits(op1_type)) {
+ if (!type_has_bits(child_type))
return nullptr;
- }
- if (handle_is_ptr(op1_type)) {
- assert(op1_type == op2_type);
- return gen_struct_memcpy(g, value, target_ref, op1_type);
- }
+ if (handle_is_ptr(child_type))
+ return gen_struct_memcpy(g, value, target_ref, child_type);
LLVMBuildStore(g->builder, value, target_ref);
return nullptr;
@@ -671,17 +667,17 @@ static void gen_var_debug_decl(CodeGen *g, VariableTableEntry *var) {
}
static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstruction *instruction) {
- if (!type_has_bits(instruction->type_entry))
+ if (!type_has_bits(instruction->value.type))
return nullptr;
if (!instruction->llvm_value) {
- assert(instruction->static_value.special != ConstValSpecialRuntime);
- assert(instruction->type_entry);
- render_const_val(g, instruction->type_entry, &instruction->static_value);
- if (handle_is_ptr(instruction->type_entry)) {
- render_const_val_global(g, instruction->type_entry, &instruction->static_value);
- instruction->llvm_value = instruction->static_value.llvm_global;
+ assert(instruction->value.special != ConstValSpecialRuntime);
+ assert(instruction->value.type);
+ render_const_val(g, &instruction->value);
+ if (handle_is_ptr(instruction->value.type)) {
+ render_const_val_global(g, &instruction->value);
+ instruction->llvm_value = instruction->value.llvm_global;
} else {
- instruction->llvm_value = instruction->static_value.llvm_value;
+ instruction->llvm_value = instruction->value.llvm_value;
}
assert(instruction->llvm_value);
}
@@ -690,7 +686,7 @@ static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstruction *instruction) {
static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrInstructionReturn *return_instruction) {
LLVMValueRef value = ir_llvm_value(g, return_instruction->value);
- TypeTableEntry *return_type = g->cur_fn->type_entry->data.fn.fn_type_id.return_type;
+ TypeTableEntry *return_type = return_instruction->value->value.type;
bool is_extern = g->cur_fn->type_entry->data.fn.fn_type_id.is_extern;
if (handle_is_ptr(return_type)) {
if (is_extern) {
@@ -698,7 +694,7 @@ static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrIns
LLVMBuildRet(g->builder, by_val_value);
} else {
assert(g->cur_ret_ptr);
- gen_assign_raw(g, g->cur_ret_ptr, value, return_type, return_instruction->value->type_entry);
+ gen_assign_raw(g, g->cur_ret_ptr, value, return_type);
LLVMBuildRetVoid(g->builder);
}
} else {
@@ -809,7 +805,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
IrInstruction *op1 = bin_op_instruction->op1;
IrInstruction *op2 = bin_op_instruction->op2;
- assert(op1->type_entry == op2->type_entry);
+ assert(op1->value.type == op2->value.type);
bool want_debug_safety = bin_op_instruction->safety_check_on &&
ir_want_debug_safety(g, &bin_op_instruction->base);
@@ -831,22 +827,22 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
case IrBinOpCmpGreaterThan:
case IrBinOpCmpLessOrEq:
case IrBinOpCmpGreaterOrEq:
- if (op1->type_entry->id == TypeTableEntryIdFloat) {
+ if (op1->value.type->id == TypeTableEntryIdFloat) {
LLVMRealPredicate pred = cmp_op_to_real_predicate(op_id);
return LLVMBuildFCmp(g->builder, pred, op1_value, op2_value, "");
- } else if (op1->type_entry->id == TypeTableEntryIdInt) {
- LLVMIntPredicate pred = cmp_op_to_int_predicate(op_id, op1->type_entry->data.integral.is_signed);
+ } else if (op1->value.type->id == TypeTableEntryIdInt) {
+ LLVMIntPredicate pred = cmp_op_to_int_predicate(op_id, op1->value.type->data.integral.is_signed);
return LLVMBuildICmp(g->builder, pred, op1_value, op2_value, "");
- } else if (op1->type_entry->id == TypeTableEntryIdEnum) {
- if (op1->type_entry->data.enumeration.gen_field_count == 0) {
+ } else if (op1->value.type->id == TypeTableEntryIdEnum) {
+ if (op1->value.type->data.enumeration.gen_field_count == 0) {
LLVMIntPredicate pred = cmp_op_to_int_predicate(op_id, false);
return LLVMBuildICmp(g->builder, pred, op1_value, op2_value, "");
} else {
zig_unreachable();
}
- } else if (op1->type_entry->id == TypeTableEntryIdPureError ||
- op1->type_entry->id == TypeTableEntryIdPointer ||
- op1->type_entry->id == TypeTableEntryIdBool)
+ } else if (op1->value.type->id == TypeTableEntryIdPureError ||
+ op1->value.type->id == TypeTableEntryIdPointer ||
+ op1->value.type->id == TypeTableEntryIdBool)
{
LLVMIntPredicate pred = cmp_op_to_int_predicate(op_id, false);
return LLVMBuildICmp(g->builder, pred, op1_value, op2_value, "");
@@ -855,15 +851,15 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
}
case IrBinOpAdd:
case IrBinOpAddWrap:
- if (op1->type_entry->id == TypeTableEntryIdFloat) {
+ if (op1->value.type->id == TypeTableEntryIdFloat) {
return LLVMBuildFAdd(g->builder, op1_value, op2_value, "");
- } else if (op1->type_entry->id == TypeTableEntryIdInt) {
+ } else if (op1->value.type->id == TypeTableEntryIdInt) {
bool is_wrapping = (op_id == IrBinOpAddWrap);
if (is_wrapping) {
return LLVMBuildAdd(g->builder, op1_value, op2_value, "");
} else if (want_debug_safety) {
- return gen_overflow_op(g, op1->type_entry, AddSubMulAdd, op1_value, op2_value);
- } else if (op1->type_entry->data.integral.is_signed) {
+ return gen_overflow_op(g, op1->value.type, AddSubMulAdd, op1_value, op2_value);
+ } else if (op1->value.type->data.integral.is_signed) {
return LLVMBuildNSWAdd(g->builder, op1_value, op2_value, "");
} else {
return LLVMBuildNUWAdd(g->builder, op1_value, op2_value, "");
@@ -880,36 +876,36 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
case IrBinOpBitShiftLeft:
case IrBinOpBitShiftLeftWrap:
{
- assert(op1->type_entry->id == TypeTableEntryIdInt);
+ assert(op1->value.type->id == TypeTableEntryIdInt);
bool is_wrapping = (op_id == IrBinOpBitShiftLeftWrap);
if (is_wrapping) {
return LLVMBuildShl(g->builder, op1_value, op2_value, "");
} else if (want_debug_safety) {
- return gen_overflow_shl_op(g, op1->type_entry, op1_value, op2_value);
- } else if (op1->type_entry->data.integral.is_signed) {
+ return gen_overflow_shl_op(g, op1->value.type, op1_value, op2_value);
+ } else if (op1->value.type->data.integral.is_signed) {
return ZigLLVMBuildNSWShl(g->builder, op1_value, op2_value, "");
} else {
return ZigLLVMBuildNUWShl(g->builder, op1_value, op2_value, "");
}
}
case IrBinOpBitShiftRight:
- assert(op1->type_entry->id == TypeTableEntryIdInt);
- if (op1->type_entry->data.integral.is_signed) {
+ assert(op1->value.type->id == TypeTableEntryIdInt);
+ if (op1->value.type->data.integral.is_signed) {
return LLVMBuildAShr(g->builder, op1_value, op2_value, "");
} else {
return LLVMBuildLShr(g->builder, op1_value, op2_value, "");
}
case IrBinOpSub:
case IrBinOpSubWrap:
- if (op1->type_entry->id == TypeTableEntryIdFloat) {
+ if (op1->value.type->id == TypeTableEntryIdFloat) {
return LLVMBuildFSub(g->builder, op1_value, op2_value, "");
- } else if (op1->type_entry->id == TypeTableEntryIdInt) {
+ } else if (op1->value.type->id == TypeTableEntryIdInt) {
bool is_wrapping = (op_id == IrBinOpSubWrap);
if (is_wrapping) {
return LLVMBuildSub(g->builder, op1_value, op2_value, "");
} else if (want_debug_safety) {
- return gen_overflow_op(g, op1->type_entry, AddSubMulSub, op1_value, op2_value);
- } else if (op1->type_entry->data.integral.is_signed) {
+ return gen_overflow_op(g, op1->value.type, AddSubMulSub, op1_value, op2_value);
+ } else if (op1->value.type->data.integral.is_signed) {
return LLVMBuildNSWSub(g->builder, op1_value, op2_value, "");
} else {
return LLVMBuildNUWSub(g->builder, op1_value, op2_value, "");
@@ -919,15 +915,15 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
}
case IrBinOpMult:
case IrBinOpMultWrap:
- if (op1->type_entry->id == TypeTableEntryIdFloat) {
+ if (op1->value.type->id == TypeTableEntryIdFloat) {
return LLVMBuildFMul(g->builder, op1_value, op2_value, "");
- } else if (op1->type_entry->id == TypeTableEntryIdInt) {
+ } else if (op1->value.type->id == TypeTableEntryIdInt) {
bool is_wrapping = (op_id == IrBinOpMultWrap);
if (is_wrapping) {
return LLVMBuildMul(g->builder, op1_value, op2_value, "");
} else if (want_debug_safety) {
- return gen_overflow_op(g, op1->type_entry, AddSubMulMul, op1_value, op2_value);
- } else if (op1->type_entry->data.integral.is_signed) {
+ return gen_overflow_op(g, op1->value.type, AddSubMulMul, op1_value, op2_value);
+ } else if (op1->value.type->data.integral.is_signed) {
return LLVMBuildNSWMul(g->builder, op1_value, op2_value, "");
} else {
return LLVMBuildNUWMul(g->builder, op1_value, op2_value, "");
@@ -936,13 +932,13 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
zig_unreachable();
}
case IrBinOpDiv:
- return gen_div(g, want_debug_safety, op1_value, op2_value, op1->type_entry, false);
+ return gen_div(g, want_debug_safety, op1_value, op2_value, op1->value.type, false);
case IrBinOpMod:
- if (op1->type_entry->id == TypeTableEntryIdFloat) {
+ if (op1->value.type->id == TypeTableEntryIdFloat) {
return LLVMBuildFRem(g->builder, op1_value, op2_value, "");
} else {
- assert(op1->type_entry->id == TypeTableEntryIdInt);
- if (op1->type_entry->data.integral.is_signed) {
+ assert(op1->value.type->id == TypeTableEntryIdInt);
+ if (op1->value.type->data.integral.is_signed) {
return LLVMBuildSRem(g->builder, op1_value, op2_value, "");
} else {
return LLVMBuildURem(g->builder, op1_value, op2_value, "");
@@ -955,8 +951,8 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
IrInstructionCast *cast_instruction)
{
- TypeTableEntry *actual_type = cast_instruction->value->type_entry;
- TypeTableEntry *wanted_type = cast_instruction->base.type_entry;
+ TypeTableEntry *actual_type = cast_instruction->value->value.type;
+ TypeTableEntry *wanted_type = cast_instruction->base.value.type;
LLVMValueRef expr_val = ir_llvm_value(g, cast_instruction->value);
assert(expr_val);
@@ -977,35 +973,9 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
return LLVMBuildPtrToInt(g->builder, expr_val, wanted_type->type_ref, "");
case CastOpIntToPtr:
return LLVMBuildIntToPtr(g->builder, expr_val, wanted_type->type_ref, "");
- case CastOpPointerReinterpret:
- return LLVMBuildBitCast(g->builder, expr_val, wanted_type->type_ref, "");
case CastOpWidenOrShorten:
return gen_widen_or_shorten(g, ir_want_debug_safety(g, &cast_instruction->base),
actual_type, wanted_type, expr_val);
- case CastOpToUnknownSizeArray:
- {
- assert(cast_instruction->tmp_ptr);
- assert(wanted_type->id == TypeTableEntryIdStruct);
- assert(wanted_type->data.structure.is_slice);
-
- TypeTableEntry *pointer_type = wanted_type->data.structure.fields[0].type_entry;
-
-
- size_t ptr_index = wanted_type->data.structure.fields[0].gen_index;
- if (ptr_index != SIZE_MAX) {
- LLVMValueRef ptr_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr, ptr_index, "");
- LLVMValueRef expr_bitcast = LLVMBuildBitCast(g->builder, expr_val, pointer_type->type_ref, "");
- LLVMBuildStore(g->builder, expr_bitcast, ptr_ptr);
- }
-
- size_t len_index = wanted_type->data.structure.fields[1].gen_index;
- LLVMValueRef len_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr, len_index, "");
- LLVMValueRef len_val = LLVMConstInt(g->builtin_types.entry_usize->type_ref,
- actual_type->data.array.len, false);
- LLVMBuildStore(g->builder, len_val, len_ptr);
-
- return cast_instruction->tmp_ptr;
- }
case CastOpResizeSlice:
{
assert(cast_instruction->tmp_ptr);
@@ -1123,6 +1093,15 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
zig_unreachable();
}
+static LLVMValueRef ir_render_pointer_reinterpret(CodeGen *g, IrExecutable *executable,
+ IrInstructionPointerReinterpret *instruction)
+{
+ TypeTableEntry *wanted_type = instruction->base.value.type;
+ LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);
+ return LLVMBuildBitCast(g->builder, ptr, wanted_type->type_ref, "");
+}
+
+
static LLVMValueRef ir_render_unreachable(CodeGen *g, IrExecutable *executable,
IrInstructionUnreachable *unreachable_instruction)
{
@@ -1152,7 +1131,7 @@ static LLVMValueRef ir_render_br(CodeGen *g, IrExecutable *executable, IrInstruc
static LLVMValueRef ir_render_un_op(CodeGen *g, IrExecutable *executable, IrInstructionUnOp *un_op_instruction) {
IrUnOp op_id = un_op_instruction->op_id;
LLVMValueRef expr = ir_llvm_value(g, un_op_instruction->value);
- TypeTableEntry *expr_type = un_op_instruction->value->type_entry;
+ TypeTableEntry *expr_type = un_op_instruction->value->value.type;
switch (op_id) {
case IrUnOpInvalid:
@@ -1213,7 +1192,7 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable,
{
VariableTableEntry *var = decl_var_instruction->var;
- if (!type_has_bits(var->type))
+ if (!type_has_bits(var->value.type))
return nullptr;
if (var->ref_count == 0)
@@ -1224,22 +1203,23 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable,
bool have_init_expr = false;
bool want_zeroes = false;
- ConstExprValue *const_val = &init_value->static_value;
+ ConstExprValue *const_val = &init_value->value;
if (const_val->special == ConstValSpecialRuntime || const_val->special == ConstValSpecialStatic)
have_init_expr = true;
if (const_val->special == ConstValSpecialZeroes)
want_zeroes = true;
if (have_init_expr) {
- gen_assign_raw(g, var->value_ref, ir_llvm_value(g, init_value), var->type, init_value->type_entry);
+ assert(var->value.type == init_value->value.type);
+ gen_assign_raw(g, var->value_ref, ir_llvm_value(g, init_value), var->value.type);
} else {
bool ignore_uninit = false;
// handle runtime stack allocation
bool want_safe = ir_want_debug_safety(g, &decl_var_instruction->base);
if (!ignore_uninit && (want_safe || want_zeroes)) {
TypeTableEntry *usize = g->builtin_types.entry_usize;
- uint64_t size_bytes = LLVMStoreSizeOfType(g->target_data_ref, var->type->type_ref);
- uint64_t align_bytes = get_memcpy_align(g, var->type);
+ uint64_t size_bytes = LLVMStoreSizeOfType(g->target_data_ref, var->value.type->type_ref);
+ uint64_t align_bytes = get_memcpy_align(g, var->value.type);
// memset uninitialized memory to 0xa
LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0);
@@ -1265,16 +1245,16 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable,
static LLVMValueRef ir_render_load_ptr(CodeGen *g, IrExecutable *executable, IrInstructionLoadPtr *instruction) {
LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);
- return get_handle_value(g, ptr, instruction->base.type_entry);
+ return get_handle_value(g, ptr, instruction->base.value.type);
}
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);
- assert(instruction->ptr->type_entry->id == TypeTableEntryIdPointer);
- TypeTableEntry *op1_type = instruction->ptr->type_entry->data.pointer.child_type;
- TypeTableEntry *op2_type = instruction->value->type_entry;
+ assert(instruction->ptr->value.type->id == TypeTableEntryIdPointer);
+ TypeTableEntry *op1_type = instruction->ptr->value.type->data.pointer.child_type;
+ TypeTableEntry *op2_type = instruction->value->value.type;
if (!type_has_bits(op1_type)) {
return nullptr;
@@ -1290,7 +1270,7 @@ static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, Ir
static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutable *executable, IrInstructionVarPtr *instruction) {
VariableTableEntry *var = instruction->var;
- if (type_has_bits(var->type)) {
+ if (type_has_bits(var->value.type)) {
assert(var->value_ref);
return var->value_ref;
} else {
@@ -1300,7 +1280,7 @@ static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutable *executable, IrIn
static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrInstructionElemPtr *instruction) {
LLVMValueRef array_ptr_ptr = ir_llvm_value(g, instruction->array_ptr);
- TypeTableEntry *array_ptr_type = instruction->array_ptr->type_entry;
+ TypeTableEntry *array_ptr_type = instruction->array_ptr->value.type;
assert(array_ptr_type->id == TypeTableEntryIdPointer);
TypeTableEntry *array_type = array_ptr_type->data.pointer.child_type;
LLVMValueRef array_ptr = get_handle_value(g, array_ptr_ptr, array_type);
@@ -1361,7 +1341,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
} else {
assert(instruction->fn_ref);
fn_val = ir_llvm_value(g, instruction->fn_ref);
- fn_type = instruction->fn_ref->type_entry;
+ fn_type = instruction->fn_ref->value.type;
}
TypeTableEntry *src_return_type = fn_type->data.fn.fn_type_id.return_type;
@@ -1377,7 +1357,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
}
for (size_t call_i = 0; call_i < instruction->arg_count; call_i += 1) {
IrInstruction *param_instruction = instruction->args[call_i];
- TypeTableEntry *param_type = param_instruction->type_entry;
+ TypeTableEntry *param_type = param_instruction->value.type;
if (is_var_args || type_has_bits(param_type)) {
LLVMValueRef param_value = ir_llvm_value(g, param_instruction);
assert(param_value);
@@ -1526,7 +1506,7 @@ static LLVMValueRef ir_render_asm(CodeGen *g, IrExecutable *executable, IrInstru
buf_append_char(&constraint_buf, ',');
}
- param_types[param_index] = ir_input->type_entry->type_ref;
+ param_types[param_index] = ir_input->value.type->type_ref;
param_values[param_index] = ir_llvm_value(g, ir_input);
}
for (size_t i = 0; i < asm_expr->clobber_list.length; i += 1, total_index += 1) {
@@ -1541,7 +1521,7 @@ static LLVMValueRef ir_render_asm(CodeGen *g, IrExecutable *executable, IrInstru
if (instruction->return_count == 0) {
ret_type = LLVMVoidType();
} else {
- ret_type = instruction->base.type_entry->type_ref;
+ ret_type = instruction->base.value.type->type_ref;
}
LLVMTypeRef function_type = LLVMFunctionType(ret_type, param_types, input_and_output_count, false);
@@ -1565,13 +1545,13 @@ static LLVMValueRef gen_non_null_bit(CodeGen *g, TypeTableEntry *maybe_type, LLV
static LLVMValueRef ir_render_test_non_null(CodeGen *g, IrExecutable *executable,
IrInstructionTestNonNull *instruction)
{
- return gen_non_null_bit(g, instruction->value->type_entry, ir_llvm_value(g, instruction->value));
+ 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,
IrInstructionUnwrapMaybe *instruction)
{
- TypeTableEntry *ptr_type = instruction->value->type_entry;
+ TypeTableEntry *ptr_type = instruction->value->value.type;
assert(ptr_type->id == TypeTableEntryIdPointer);
TypeTableEntry *maybe_type = ptr_type->data.pointer.child_type;
assert(maybe_type->id == TypeTableEntryIdMaybe);
@@ -1617,7 +1597,7 @@ static LLVMValueRef get_int_builtin_fn(CodeGen *g, TypeTableEntry *int_type, Bui
}
static LLVMValueRef ir_render_clz(CodeGen *g, IrExecutable *executable, IrInstructionClz *instruction) {
- TypeTableEntry *int_type = instruction->base.type_entry;
+ TypeTableEntry *int_type = instruction->base.value.type;
LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdClz);
LLVMValueRef operand = ir_llvm_value(g, instruction->value);
LLVMValueRef params[] {
@@ -1628,7 +1608,7 @@ static LLVMValueRef ir_render_clz(CodeGen *g, IrExecutable *executable, IrInstru
}
static LLVMValueRef ir_render_ctz(CodeGen *g, IrExecutable *executable, IrInstructionCtz *instruction) {
- TypeTableEntry *int_type = instruction->base.type_entry;
+ TypeTableEntry *int_type = instruction->base.value.type;
LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdCtz);
LLVMValueRef operand = ir_llvm_value(g, instruction->value);
LLVMValueRef params[] {
@@ -1650,14 +1630,14 @@ static LLVMValueRef ir_render_switch_br(CodeGen *g, IrExecutable *executable, Ir
}
static LLVMValueRef ir_render_phi(CodeGen *g, IrExecutable *executable, IrInstructionPhi *instruction) {
- if (!type_has_bits(instruction->base.type_entry))
+ if (!type_has_bits(instruction->base.value.type))
return nullptr;
LLVMTypeRef phi_type;
- if (handle_is_ptr(instruction->base.type_entry)) {
- phi_type = LLVMPointerType(instruction->base.type_entry->type_ref, 0);
+ if (handle_is_ptr(instruction->base.value.type)) {
+ phi_type = LLVMPointerType(instruction->base.value.type->type_ref, 0);
} else {
- phi_type = instruction->base.type_entry->type_ref;
+ phi_type = instruction->base.value.type->type_ref;
}
LLVMValueRef phi = LLVMBuildPhi(g->builder, phi_type, "");
@@ -1673,7 +1653,7 @@ static LLVMValueRef ir_render_phi(CodeGen *g, IrExecutable *executable, IrInstru
static LLVMValueRef ir_render_ref(CodeGen *g, IrExecutable *executable, IrInstructionRef *instruction) {
LLVMValueRef value = ir_llvm_value(g, instruction->value);
- if (handle_is_ptr(instruction->value->type_entry)) {
+ if (handle_is_ptr(instruction->value->value.type)) {
return value;
} else {
assert(instruction->tmp_ptr);
@@ -1741,17 +1721,17 @@ static LLVMValueRef ir_render_div_exact(CodeGen *g, IrExecutable *executable, Ir
LLVMValueRef op2_val = ir_llvm_value(g, instruction->op2);
bool want_debug_safety = ir_want_debug_safety(g, &instruction->base);
- return gen_div(g, want_debug_safety, op1_val, op2_val, instruction->base.type_entry, true);
+ return gen_div(g, want_debug_safety, op1_val, op2_val, instruction->base.value.type, true);
}
static LLVMValueRef ir_render_truncate(CodeGen *g, IrExecutable *executable, IrInstructionTruncate *instruction) {
- TypeTableEntry *dest_type = get_underlying_type(instruction->base.type_entry);
+ TypeTableEntry *dest_type = get_underlying_type(instruction->base.value.type);
LLVMValueRef target_val = ir_llvm_value(g, instruction->target);
return LLVMBuildTrunc(g->builder, target_val, dest_type->type_ref, "");
}
static LLVMValueRef ir_render_alloca(CodeGen *g, IrExecutable *executable, IrInstructionAlloca *instruction) {
- TypeTableEntry *slice_type = get_underlying_type(instruction->base.type_entry);
+ TypeTableEntry *slice_type = get_underlying_type(instruction->base.value.type);
TypeTableEntry *ptr_type = slice_type->data.structure.fields[slice_ptr_index].type_entry;
TypeTableEntry *child_type = ptr_type->data.pointer.child_type;
LLVMValueRef size_val = ir_llvm_value(g, instruction->count);
@@ -1814,12 +1794,14 @@ static LLVMValueRef ir_render_memcpy(CodeGen *g, IrExecutable *executable, IrIns
}
static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInstructionSlice *instruction) {
- TypeTableEntry *array_type = get_underlying_type(instruction->ptr->type_entry);
+ assert(instruction->tmp_ptr);
+
+ TypeTableEntry *array_type = get_underlying_type(instruction->ptr->value.type);
LLVMValueRef tmp_struct_ptr = instruction->tmp_ptr;
LLVMValueRef array_ptr = ir_llvm_value(g, instruction->ptr);
- bool want_debug_safety = ir_want_debug_safety(g, &instruction->base);
+ bool want_debug_safety = instruction->safety_check_on && ir_want_debug_safety(g, &instruction->base);
if (array_type->id == TypeTableEntryIdArray) {
LLVMValueRef start_val = ir_llvm_value(g, instruction->start);
@@ -1997,7 +1979,7 @@ static LLVMValueRef ir_render_overflow_op(CodeGen *g, IrExecutable *executable,
}
static LLVMValueRef ir_render_test_err(CodeGen *g, IrExecutable *executable, IrInstructionTestErr *instruction) {
- TypeTableEntry *err_union_type = get_underlying_type(instruction->value->type_entry);
+ TypeTableEntry *err_union_type = get_underlying_type(instruction->value->value.type);
TypeTableEntry *child_type = get_underlying_type(err_union_type->data.error.child_type);
LLVMValueRef err_union_handle = ir_llvm_value(g, instruction->value);
@@ -2014,7 +1996,7 @@ static LLVMValueRef ir_render_test_err(CodeGen *g, IrExecutable *executable, IrI
}
static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, IrExecutable *executable, IrInstructionUnwrapErrCode *instruction) {
- TypeTableEntry *ptr_type = get_underlying_type(instruction->value->type_entry);
+ TypeTableEntry *ptr_type = get_underlying_type(instruction->value->value.type);
TypeTableEntry *err_union_type = get_underlying_type(ptr_type->data.pointer.child_type);
TypeTableEntry *child_type = get_underlying_type(err_union_type->data.error.child_type);
LLVMValueRef err_union_ptr = ir_llvm_value(g, instruction->value);
@@ -2029,7 +2011,7 @@ static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, IrExecutable *executab
}
static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *executable, IrInstructionUnwrapErrPayload *instruction) {
- TypeTableEntry *ptr_type = get_underlying_type(instruction->value->type_entry);
+ TypeTableEntry *ptr_type = get_underlying_type(instruction->value->value.type);
TypeTableEntry *err_union_type = get_underlying_type(ptr_type->data.pointer.child_type);
TypeTableEntry *child_type = get_underlying_type(err_union_type->data.error.child_type);
LLVMValueRef err_union_ptr = ir_llvm_value(g, instruction->value);
@@ -2063,7 +2045,7 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *execu
}
static LLVMValueRef ir_render_maybe_wrap(CodeGen *g, IrExecutable *executable, IrInstructionMaybeWrap *instruction) {
- TypeTableEntry *wanted_type = instruction->base.type_entry;
+ TypeTableEntry *wanted_type = instruction->base.value.type;
assert(wanted_type->id == TypeTableEntryIdMaybe);
@@ -2079,7 +2061,8 @@ static LLVMValueRef ir_render_maybe_wrap(CodeGen *g, IrExecutable *executable, I
assert(instruction->tmp_ptr);
LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, maybe_child_index, "");
- gen_assign_raw(g, val_ptr, payload_val, child_type, instruction->value->type_entry);
+ assert(child_type == instruction->value->value.type);
+ gen_assign_raw(g, val_ptr, payload_val, child_type);
LLVMValueRef maybe_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, maybe_null_index, "");
LLVMBuildStore(g->builder, LLVMConstAllOnes(LLVMInt1Type()), maybe_ptr);
@@ -2087,7 +2070,7 @@ static LLVMValueRef ir_render_maybe_wrap(CodeGen *g, IrExecutable *executable, I
}
static LLVMValueRef ir_render_err_wrap_code(CodeGen *g, IrExecutable *executable, IrInstructionErrWrapCode *instruction) {
- TypeTableEntry *wanted_type = instruction->base.type_entry;
+ TypeTableEntry *wanted_type = instruction->base.value.type;
assert(wanted_type->id == TypeTableEntryIdErrorUnion);
@@ -2106,7 +2089,7 @@ static LLVMValueRef ir_render_err_wrap_code(CodeGen *g, IrExecutable *executable
}
static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutable *executable, IrInstructionErrWrapPayload *instruction) {
- TypeTableEntry *wanted_type = instruction->base.type_entry;
+ TypeTableEntry *wanted_type = instruction->base.value.type;
assert(wanted_type->id == TypeTableEntryIdErrorUnion);
@@ -2125,13 +2108,14 @@ static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutable *executa
LLVMBuildStore(g->builder, ok_err_val, err_tag_ptr);
LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, err_union_payload_index, "");
- gen_assign_raw(g, payload_ptr, payload_val, child_type, instruction->value->type_entry);
+ assert(child_type == instruction->value->value.type);
+ gen_assign_raw(g, payload_ptr, payload_val, child_type);
return instruction->tmp_ptr;
}
static LLVMValueRef ir_render_enum_tag(CodeGen *g, IrExecutable *executable, IrInstructionEnumTag *instruction) {
- TypeTableEntry *enum_type = instruction->value->type_entry;
+ TypeTableEntry *enum_type = instruction->value->value.type;
TypeTableEntry *tag_type = enum_type->data.enumeration.tag_type;
if (!type_has_bits(tag_type))
return nullptr;
@@ -2165,7 +2149,7 @@ static LLVMValueRef ir_render_init_enum(CodeGen *g, IrExecutable *executable, Ir
LLVMValueRef bitcasted_union_field_ptr = LLVMBuildBitCast(g->builder, union_field_ptr,
LLVMPointerType(union_val_type->type_ref, 0), "");
- gen_assign_raw(g, bitcasted_union_field_ptr, new_union_val, union_val_type, union_val_type);
+ gen_assign_raw(g, bitcasted_union_field_ptr, new_union_val, union_val_type);
}
return tmp_struct_ptr;
@@ -2180,7 +2164,7 @@ static LLVMValueRef ir_render_struct_init(CodeGen *g, IrExecutable *executable,
LLVMValueRef field_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, type_struct_field->gen_index, "");
LLVMValueRef value = ir_llvm_value(g, field->value);
- gen_assign_raw(g, field_ptr, value, type_struct_field->type_entry, type_struct_field->type_entry);
+ gen_assign_raw(g, field_ptr, value, type_struct_field->type_entry);
}
return instruction->tmp_ptr;
}
@@ -2323,6 +2307,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
return ir_render_init_enum(g, executable, (IrInstructionInitEnum *)instruction);
case IrInstructionIdStructInit:
return ir_render_struct_init(g, executable, (IrInstructionStructInit *)instruction);
+ case IrInstructionIdPointerReinterpret:
+ return ir_render_pointer_reinterpret(g, executable, (IrInstructionPointerReinterpret *)instruction);
case IrInstructionIdSwitchVar:
zig_panic("TODO render switch var instruction to LLVM");
case IrInstructionIdContainerInitList:
@@ -2350,37 +2336,40 @@ static void ir_render(CodeGen *g, FnTableEntry *fn_entry) {
}
}
-static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *const_val) {
+static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
+ TypeTableEntry *canon_type = get_underlying_type(const_val->type);
+
switch (const_val->special) {
case ConstValSpecialRuntime:
zig_unreachable();
case ConstValSpecialUndef:
- return LLVMGetUndef(type_entry->type_ref);
+ return LLVMGetUndef(canon_type->type_ref);
case ConstValSpecialZeroes:
- return LLVMConstNull(type_entry->type_ref);
+ return LLVMConstNull(canon_type->type_ref);
case ConstValSpecialStatic:
break;
}
- switch (type_entry->id) {
+ switch (canon_type->id) {
case TypeTableEntryIdTypeDecl:
- return gen_const_val(g, type_entry->data.type_decl.canonical_type, const_val);
+ zig_unreachable();
case TypeTableEntryIdInt:
- return LLVMConstInt(type_entry->type_ref, bignum_to_twos_complement(&const_val->data.x_bignum), false);
+ case TypeTableEntryIdEnumTag:
+ return LLVMConstInt(canon_type->type_ref, bignum_to_twos_complement(&const_val->data.x_bignum), false);
case TypeTableEntryIdPureError:
assert(const_val->data.x_pure_err);
return LLVMConstInt(g->builtin_types.entry_pure_error->type_ref,
const_val->data.x_pure_err->value, false);
case TypeTableEntryIdFloat:
if (const_val->data.x_bignum.kind == BigNumKindFloat) {
- return LLVMConstReal(type_entry->type_ref, const_val->data.x_bignum.data.x_float);
+ return LLVMConstReal(canon_type->type_ref, const_val->data.x_bignum.data.x_float);
} else {
int64_t x = const_val->data.x_bignum.data.x_uint;
if (const_val->data.x_bignum.is_negative) {
x = -x;
}
- return LLVMConstReal(type_entry->type_ref, x);
+ return LLVMConstReal(canon_type->type_ref, x);
}
case TypeTableEntryIdBool:
if (const_val->data.x_bool) {
@@ -2390,12 +2379,12 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE
}
case TypeTableEntryIdMaybe:
{
- TypeTableEntry *child_type = type_entry->data.maybe.child_type;
+ TypeTableEntry *child_type = canon_type->data.maybe.child_type;
if (child_type->id == TypeTableEntryIdPointer ||
child_type->id == TypeTableEntryIdFn)
{
if (const_val->data.x_maybe) {
- return gen_const_val(g, child_type, const_val->data.x_maybe);
+ return gen_const_val(g, const_val->data.x_maybe);
} else {
return LLVMConstNull(child_type->type_ref);
}
@@ -2403,7 +2392,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE
LLVMValueRef child_val;
LLVMValueRef maybe_val;
if (const_val->data.x_maybe) {
- child_val = gen_const_val(g, child_type, const_val->data.x_maybe);
+ child_val = gen_const_val(g, const_val->data.x_maybe);
maybe_val = LLVMConstAllOnes(LLVMInt1Type());
} else {
child_val = LLVMConstNull(child_type->type_ref);
@@ -2418,17 +2407,16 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE
}
case TypeTableEntryIdStruct:
{
- LLVMValueRef *fields = allocate<LLVMValueRef>(type_entry->data.structure.gen_field_count);
- for (uint32_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) {
- TypeStructField *type_struct_field = &type_entry->data.structure.fields[i];
+ LLVMValueRef *fields = allocate<LLVMValueRef>(canon_type->data.structure.gen_field_count);
+ for (uint32_t i = 0; i < canon_type->data.structure.src_field_count; i += 1) {
+ TypeStructField *type_struct_field = &canon_type->data.structure.fields[i];
if (type_struct_field->gen_index == SIZE_MAX) {
continue;
}
- fields[type_struct_field->gen_index] = gen_const_val(g, type_struct_field->type_entry,
- &const_val->data.x_struct.fields[i]);
+ fields[type_struct_field->gen_index] = gen_const_val(g, &const_val->data.x_struct.fields[i]);
}
- return LLVMConstNamedStruct(type_entry->type_ref, fields,
- type_entry->data.structure.gen_field_count);
+ return LLVMConstNamedStruct(canon_type->type_ref, fields,
+ canon_type->data.structure.gen_field_count);
}
case TypeTableEntryIdUnion:
{
@@ -2436,24 +2424,24 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE
}
case TypeTableEntryIdArray:
{
- TypeTableEntry *child_type = type_entry->data.array.child_type;
- uint64_t len = type_entry->data.array.len;
+ TypeTableEntry *child_type = canon_type->data.array.child_type;
+ uint64_t len = canon_type->data.array.len;
LLVMValueRef *values = allocate<LLVMValueRef>(len);
for (uint64_t i = 0; i < len; i += 1) {
ConstExprValue *elem_value = &const_val->data.x_array.elements[i];
- values[i] = gen_const_val(g, child_type, elem_value);
+ values[i] = gen_const_val(g, elem_value);
}
return LLVMConstArray(child_type->type_ref, values, len);
}
case TypeTableEntryIdEnum:
{
- LLVMTypeRef tag_type_ref = type_entry->data.enumeration.tag_type->type_ref;
+ LLVMTypeRef tag_type_ref = canon_type->data.enumeration.tag_type->type_ref;
LLVMValueRef tag_value = LLVMConstInt(tag_type_ref, const_val->data.x_enum.tag, false);
- if (type_entry->data.enumeration.gen_field_count == 0) {
+ if (canon_type->data.enumeration.gen_field_count == 0) {
return tag_value;
} else {
- TypeTableEntry *union_type = type_entry->data.enumeration.union_type;
- TypeEnumField *enum_field = &type_entry->data.enumeration.fields[const_val->data.x_enum.tag];
+ TypeTableEntry *union_type = canon_type->data.enumeration.union_type;
+ TypeEnumField *enum_field = &canon_type->data.enumeration.fields[const_val->data.x_enum.tag];
assert(enum_field->value == const_val->data.x_enum.tag);
LLVMValueRef union_value;
if (type_has_bits(enum_field->type_entry)) {
@@ -2463,8 +2451,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE
enum_field->type_entry->type_ref);
uint64_t pad_bytes = union_type_bytes - field_type_bytes;
- LLVMValueRef correctly_typed_value = gen_const_val(g, enum_field->type_entry,
- const_val->data.x_enum.payload);
+ LLVMValueRef correctly_typed_value = gen_const_val(g, const_val->data.x_enum.payload);
if (pad_bytes == 0) {
union_value = correctly_typed_value;
} else {
@@ -2481,29 +2468,31 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE
tag_value,
union_value,
};
- return LLVMConstNamedStruct(type_entry->type_ref, fields, 2);
+ return LLVMConstNamedStruct(canon_type->type_ref, fields, 2);
}
}
case TypeTableEntryIdFn:
return fn_llvm_value(g, const_val->data.x_fn);
case TypeTableEntryIdPointer:
{
- TypeTableEntry *child_type = type_entry->data.pointer.child_type;
-
- render_const_val_global(g, type_entry, const_val);
+ render_const_val_global(g, const_val);
size_t index = const_val->data.x_ptr.index;
if (index == SIZE_MAX) {
- render_const_val(g, child_type, const_val->data.x_ptr.base_ptr);
- render_const_val_global(g, child_type, const_val->data.x_ptr.base_ptr);
- const_val->llvm_value = const_val->data.x_ptr.base_ptr->llvm_global;
- render_const_val_global(g, type_entry, const_val);
+ render_const_val(g, const_val->data.x_ptr.base_ptr);
+ render_const_val_global(g, const_val->data.x_ptr.base_ptr);
+ ConstExprValue *other_val = const_val->data.x_ptr.base_ptr;
+ if (other_val->type == const_val->type->data.pointer.child_type) {
+ const_val->llvm_value = other_val->llvm_global;
+ } else {
+ const_val->llvm_value = LLVMConstBitCast(other_val->llvm_global, const_val->type->type_ref);
+ }
+ render_const_val_global(g, const_val);
return const_val->llvm_value;
} else {
ConstExprValue *array_const_val = const_val->data.x_ptr.base_ptr;
- TypeTableEntry *array_type = get_array_type(g, child_type,
- array_const_val->data.x_array.size);
- render_const_val(g, array_type, array_const_val);
- render_const_val_global(g, array_type, array_const_val);
+ assert(array_const_val->type->id == TypeTableEntryIdArray);
+ render_const_val(g, array_const_val);
+ render_const_val_global(g, array_const_val);
TypeTableEntry *usize = g->builtin_types.entry_usize;
LLVMValueRef indices[] = {
LLVMConstNull(usize->type_ref),
@@ -2511,13 +2500,13 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE
};
LLVMValueRef ptr_val = LLVMConstInBoundsGEP(array_const_val->llvm_global, indices, 2);
const_val->llvm_value = ptr_val;
- render_const_val_global(g, type_entry, const_val);
+ render_const_val_global(g, const_val);
return ptr_val;
}
}
case TypeTableEntryIdErrorUnion:
{
- TypeTableEntry *child_type = type_entry->data.error.child_type;
+ TypeTableEntry *child_type = canon_type->data.error.child_type;
if (!type_has_bits(child_type)) {
uint64_t value = const_val->data.x_err_union.err ? const_val->data.x_err_union.err->value : 0;
return LLVMConstInt(g->err_tag_type->type_ref, value, false);
@@ -2529,7 +2518,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE
err_payload_value = LLVMConstNull(child_type->type_ref);
} else {
err_tag_value = LLVMConstNull(g->err_tag_type->type_ref);
- err_payload_value = gen_const_val(g, child_type, const_val->data.x_err_union.payload);
+ err_payload_value = gen_const_val(g, const_val->data.x_err_union.payload);
}
LLVMValueRef fields[] = {
err_tag_value,
@@ -2540,8 +2529,6 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE
}
case TypeTableEntryIdVoid:
return nullptr;
- case TypeTableEntryIdEnumTag:
- return gen_const_val(g, type_entry->data.enum_tag.int_type, const_val);
case TypeTableEntryIdInvalid:
case TypeTableEntryIdMetaType:
case TypeTableEntryIdUnreachable:
@@ -2559,17 +2546,17 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE
zig_unreachable();
}
-static void render_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *const_val) {
+static void render_const_val(CodeGen *g, ConstExprValue *const_val) {
if (!const_val->llvm_value)
- const_val->llvm_value = gen_const_val(g, type_entry, const_val);
+ const_val->llvm_value = gen_const_val(g, const_val);
if (const_val->llvm_global)
LLVMSetInitializer(const_val->llvm_global, const_val->llvm_value);
}
-static void render_const_val_global(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *const_val) {
+static void render_const_val_global(CodeGen *g, ConstExprValue *const_val) {
if (!const_val->llvm_global) {
- LLVMValueRef global_value = LLVMAddGlobal(g->module, type_entry->type_ref, "");
+ LLVMValueRef global_value = LLVMAddGlobal(g->module, const_val->type->type_ref, "");
LLVMSetLinkage(global_value, LLVMInternalLinkage);
LLVMSetGlobalConstant(global_value, true);
LLVMSetUnnamedAddr(global_value, true);
@@ -2717,9 +2704,9 @@ static void do_code_gen(CodeGen *g) {
for (size_t i = 0; i < g->global_vars.length; i += 1) {
VariableTableEntry *var = g->global_vars.at(i);
- if (var->type->id == TypeTableEntryIdNumLitFloat) {
+ if (var->value.type->id == TypeTableEntryIdNumLitFloat) {
// Generate debug info for it but that's it.
- ConstExprValue *const_val = var->value;
+ ConstExprValue *const_val = &var->value;
assert(const_val->special != ConstValSpecialRuntime);
TypeTableEntry *var_type = g->builtin_types.entry_f64;
LLVMValueRef init_val = LLVMConstReal(var_type->type_ref, const_val->data.x_bignum.data.x_float);
@@ -2727,9 +2714,9 @@ static void do_code_gen(CodeGen *g) {
continue;
}
- if (var->type->id == TypeTableEntryIdNumLitInt) {
+ if (var->value.type->id == TypeTableEntryIdNumLitInt) {
// Generate debug info for it but that's it.
- ConstExprValue *const_val = var->value;
+ ConstExprValue *const_val = &var->value;
assert(const_val->special != ConstValSpecialRuntime);
TypeTableEntry *var_type = const_val->data.x_bignum.is_negative ?
g->builtin_types.entry_isize : g->builtin_types.entry_usize;
@@ -2739,27 +2726,26 @@ static void do_code_gen(CodeGen *g) {
continue;
}
- if (!type_has_bits(var->type)) {
+ if (!type_has_bits(var->value.type))
continue;
- }
assert(var->decl_node);
assert(var->decl_node->type == NodeTypeVariableDeclaration);
LLVMValueRef global_value;
if (var->is_extern) {
- global_value = LLVMAddGlobal(g->module, var->type->type_ref, buf_ptr(&var->name));
+ global_value = LLVMAddGlobal(g->module, var->value.type->type_ref, buf_ptr(&var->name));
// TODO debug info for the extern variable
LLVMSetLinkage(global_value, LLVMExternalLinkage);
} else {
- render_const_val(g, var->type, var->value);
- render_const_val_global(g, var->type, var->value);
- global_value = var->value->llvm_global;
+ render_const_val(g, &var->value);
+ render_const_val_global(g, &var->value);
+ global_value = var->value.llvm_global;
// TODO debug info for function pointers
- if (var->gen_is_const && var->type->id != TypeTableEntryIdFn) {
- gen_global_var(g, var, var->value->llvm_value, var->type);
+ if (var->gen_is_const && var->value.type->id != TypeTableEntryIdFn) {
+ gen_global_var(g, var, var->value.llvm_value, var->value.type);
}
}
@@ -2890,15 +2876,15 @@ static void do_code_gen(CodeGen *g) {
for (size_t alloca_i = 0; alloca_i < fn_table_entry->alloca_list.length; alloca_i += 1) {
IrInstruction *instruction = fn_table_entry->alloca_list.at(alloca_i);
LLVMValueRef *slot;
- TypeTableEntry *slot_type = instruction->type_entry;
+ TypeTableEntry *slot_type = instruction->value.type;
if (instruction->id == IrInstructionIdCast) {
IrInstructionCast *cast_instruction = (IrInstructionCast *)instruction;
slot = &cast_instruction->tmp_ptr;
} else if (instruction->id == IrInstructionIdRef) {
IrInstructionRef *ref_instruction = (IrInstructionRef *)instruction;
slot = &ref_instruction->tmp_ptr;
- assert(instruction->type_entry->id == TypeTableEntryIdPointer);
- slot_type = instruction->type_entry->data.pointer.child_type;
+ assert(instruction->value.type->id == TypeTableEntryIdPointer);
+ slot_type = instruction->value.type->data.pointer.child_type;
} else if (instruction->id == IrInstructionIdContainerInitList) {
IrInstructionContainerInitList *container_init_list_instruction = (IrInstructionContainerInitList *)instruction;
slot = &container_init_list_instruction->tmp_ptr;
@@ -2938,33 +2924,33 @@ static void do_code_gen(CodeGen *g) {
for (size_t var_i = 0; var_i < fn_table_entry->variable_list.length; var_i += 1) {
VariableTableEntry *var = fn_table_entry->variable_list.at(var_i);
- if (!type_has_bits(var->type)) {
+ if (!type_has_bits(var->value.type)) {
continue;
}
if (ir_get_var_is_comptime(var))
continue;
if (var->src_arg_index == SIZE_MAX) {
- var->value_ref = LLVMBuildAlloca(g->builder, var->type->type_ref, buf_ptr(&var->name));
+ var->value_ref = LLVMBuildAlloca(g->builder, var->value.type->type_ref, buf_ptr(&var->name));
- unsigned align_bytes = ZigLLVMGetPrefTypeAlignment(g->target_data_ref, var->type->type_ref);
+ unsigned align_bytes = ZigLLVMGetPrefTypeAlignment(g->target_data_ref, var->value.type->type_ref);
LLVMSetAlignment(var->value_ref, align_bytes);
var->di_loc_var = ZigLLVMCreateAutoVariable(g->dbuilder, get_di_scope(g, var->parent_scope),
buf_ptr(&var->name), import->di_file, var->decl_node->line + 1,
- var->type->di_type, !g->strip_debug_symbols, 0);
+ var->value.type->di_type, !g->strip_debug_symbols, 0);
} else {
assert(var->gen_arg_index != SIZE_MAX);
TypeTableEntry *gen_type;
- if (handle_is_ptr(var->type)) {
+ if (handle_is_ptr(var->value.type)) {
gen_type = fn_table_entry->type_entry->data.fn.gen_param_info[var->src_arg_index].type;
var->value_ref = LLVMGetParam(fn, var->gen_arg_index);
} else {
- gen_type = var->type;
- var->value_ref = LLVMBuildAlloca(g->builder, var->type->type_ref, buf_ptr(&var->name));
- unsigned align_bytes = ZigLLVMGetPrefTypeAlignment(g->target_data_ref, var->type->type_ref);
+ gen_type = var->value.type;
+ var->value_ref = LLVMBuildAlloca(g->builder, var->value.type->type_ref, buf_ptr(&var->name));
+ unsigned align_bytes = ZigLLVMGetPrefTypeAlignment(g->target_data_ref, var->value.type->type_ref);
LLVMSetAlignment(var->value_ref, align_bytes);
}
var->di_loc_var = ZigLLVMCreateParameterVariable(g->dbuilder, get_di_scope(g, var->parent_scope),
@@ -2991,7 +2977,7 @@ static void do_code_gen(CodeGen *g) {
assert(variable);
assert(variable->value_ref);
- if (!handle_is_ptr(variable->type)) {
+ if (!handle_is_ptr(variable->value.type)) {
clear_debug_source_node(g);
LLVMBuildStore(g->builder, LLVMGetParam(fn, variable->gen_arg_index), variable->value_ref);
}
@@ -3627,7 +3613,7 @@ static void init(CodeGen *g, Buf *source_path) {
define_builtin_fns(g);
g->invalid_instruction = allocate<IrInstruction>(1);
- g->invalid_instruction->type_entry = g->builtin_types.entry_invalid;
+ g->invalid_instruction->value.type = g->builtin_types.entry_invalid;
}
void codegen_parseh(CodeGen *g, Buf *src_dirname, Buf *src_basename, Buf *source_code) {