Merge remote-tracking branch 'origin/master' into llvm10

This commit is contained in:
Andrew Kelley
2020-01-29 23:33:12 -05:00
95 changed files with 32127 additions and 10809 deletions
+532 -524
View File
@@ -20,6 +20,7 @@
#include "zig_llvm.h"
#include "userland.h"
#include "dump_analysis.hpp"
#include "softfloat.hpp"
#include <stdio.h>
#include <errno.h>
@@ -30,11 +31,6 @@ enum ResumeId {
ResumeIdCall,
};
// TODO https://github.com/ziglang/zig/issues/2883
// Until then we have this same default as Clang.
// This avoids https://github.com/ziglang/zig/issues/3275
static const char *riscv_default_features = "+a,+c,+d,+f,+m,+relax";
static void init_darwin_native(CodeGen *g) {
char *osx_target = getenv("MACOSX_DEPLOYMENT_TARGET");
char *ios_target = getenv("IPHONEOS_DEPLOYMENT_TARGET");
@@ -191,7 +187,7 @@ static void generate_error_name_table(CodeGen *g);
static bool value_is_all_undef(CodeGen *g, ZigValue *const_val);
static void gen_undef_init(CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_type, LLVMValueRef ptr);
static LLVMValueRef build_alloca(CodeGen *g, ZigType *type_entry, const char *name, uint32_t alignment);
static LLVMValueRef gen_await_early_return(CodeGen *g, IrInstruction *source_instr,
static LLVMValueRef gen_await_early_return(CodeGen *g, IrInstGen *source_instr,
LLVMValueRef target_frame_ptr, ZigType *result_type, ZigType *ptr_result_type,
LLVMValueRef result_loc, bool non_async);
static Error get_tmp_filename(CodeGen *g, Buf *out, Buf *suffix);
@@ -877,14 +873,14 @@ static LLVMValueRef get_handle_value(CodeGen *g, LLVMValueRef ptr, ZigType *type
}
}
static void ir_assert(bool ok, IrInstruction *source_instruction) {
static void ir_assert(bool ok, IrInstGen *source_instruction) {
if (ok) return;
src_assert(ok, source_instruction->source_node);
src_assert(ok, source_instruction->base.source_node);
}
static bool ir_want_fast_math(CodeGen *g, IrInstruction *instruction) {
static bool ir_want_fast_math(CodeGen *g, IrInstGen *instruction) {
// TODO memoize
Scope *scope = instruction->scope;
Scope *scope = instruction->base.scope;
while (scope) {
if (scope->id == ScopeIdBlock) {
ScopeBlock *block_scope = (ScopeBlock *)scope;
@@ -919,8 +915,8 @@ static bool ir_want_runtime_safety_scope(CodeGen *g, Scope *scope) {
g->build_mode != BuildModeSmallRelease);
}
static bool ir_want_runtime_safety(CodeGen *g, IrInstruction *instruction) {
return ir_want_runtime_safety_scope(g, instruction->scope);
static bool ir_want_runtime_safety(CodeGen *g, IrInstGen *instruction) {
return ir_want_runtime_safety_scope(g, instruction->base.scope);
}
static Buf *panic_msg_buf(PanicMsgId msg_id) {
@@ -1046,8 +1042,8 @@ static void gen_assertion_scope(CodeGen *g, PanicMsgId msg_id, Scope *source_sco
}
}
static void gen_assertion(CodeGen *g, PanicMsgId msg_id, IrInstruction *source_instruction) {
return gen_assertion_scope(g, msg_id, source_instruction->scope);
static void gen_assertion(CodeGen *g, PanicMsgId msg_id, IrInstGen *source_instruction) {
return gen_assertion_scope(g, msg_id, source_instruction->base.scope);
}
static LLVMValueRef get_stacksave_fn_val(CodeGen *g) {
@@ -1761,7 +1757,7 @@ static void gen_var_debug_decl(CodeGen *g, ZigVar *var) {
LLVMGetInsertBlock(g->builder));
}
static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstruction *instruction) {
static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstGen *instruction) {
Error err;
bool value_has_bits;
@@ -1772,8 +1768,8 @@ static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstruction *instruction) {
return nullptr;
if (!instruction->llvm_value) {
if (instruction->id == IrInstructionIdAwaitGen) {
IrInstructionAwaitGen *await = reinterpret_cast<IrInstructionAwaitGen*>(instruction);
if (instruction->id == IrInstGenIdAwait) {
IrInstGenAwait *await = reinterpret_cast<IrInstGenAwait*>(instruction);
if (await->result_loc != nullptr) {
return get_handle_value(g, ir_llvm_value(g, await->result_loc),
await->result_loc->value->type->data.pointer.child_type, await->result_loc->value->type);
@@ -1856,9 +1852,9 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
case FnWalkIdCall: {
if (src_i >= fn_walk->data.call.inst->arg_count)
return false;
IrInstruction *arg = fn_walk->data.call.inst->args[src_i];
IrInstGen *arg = fn_walk->data.call.inst->args[src_i];
ty = arg->value->type;
source_node = arg->source_node;
source_node = arg->base.source_node;
val = ir_llvm_value(g, arg);
break;
}
@@ -2091,10 +2087,10 @@ void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk) {
return;
}
if (fn_walk->id == FnWalkIdCall) {
IrInstructionCallGen *instruction = fn_walk->data.call.inst;
IrInstGenCall *instruction = fn_walk->data.call.inst;
bool is_var_args = fn_walk->data.call.is_var_args;
for (size_t call_i = 0; call_i < instruction->arg_count; call_i += 1) {
IrInstruction *param_instruction = instruction->args[call_i];
IrInstGen *param_instruction = instruction->args[call_i];
ZigType *param_type = param_instruction->value->type;
if (is_var_args || type_has_bits(param_type)) {
LLVMValueRef param_value = ir_llvm_value(g, param_instruction);
@@ -2309,14 +2305,14 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {
return fn_val;
}
static LLVMValueRef ir_render_save_err_ret_addr(CodeGen *g, IrExecutable *executable,
IrInstructionSaveErrRetAddr *save_err_ret_addr_instruction)
static LLVMValueRef ir_render_save_err_ret_addr(CodeGen *g, IrExecutableGen *executable,
IrInstGenSaveErrRetAddr *save_err_ret_addr_instruction)
{
assert(g->have_err_ret_tracing);
LLVMValueRef return_err_fn = get_return_err_fn(g);
bool is_llvm_alloca;
LLVMValueRef my_err_trace_val = get_cur_err_ret_trace_val(g, save_err_ret_addr_instruction->base.scope,
LLVMValueRef my_err_trace_val = get_cur_err_ret_trace_val(g, save_err_ret_addr_instruction->base.base.scope,
&is_llvm_alloca);
ZigLLVMBuildCall(g->builder, return_err_fn, &my_err_trace_val, 1,
get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAuto, "");
@@ -2331,7 +2327,7 @@ static LLVMValueRef ir_render_save_err_ret_addr(CodeGen *g, IrExecutable *execut
return nullptr;
}
static void gen_assert_resume_id(CodeGen *g, IrInstruction *source_instr, ResumeId resume_id, PanicMsgId msg_id,
static void gen_assert_resume_id(CodeGen *g, IrInstGen *source_instr, ResumeId resume_id, PanicMsgId msg_id,
LLVMBasicBlockRef end_bb)
{
LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
@@ -2408,7 +2404,7 @@ static LLVMValueRef gen_maybe_atomic_op(CodeGen *g, LLVMAtomicRMWBinOp op, LLVMV
}
}
static void gen_async_return(CodeGen *g, IrInstructionReturn *instruction) {
static void gen_async_return(CodeGen *g, IrInstGenReturn *instruction) {
LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
ZigType *operand_type = (instruction->operand != nullptr) ? instruction->operand->value->type : nullptr;
@@ -2487,7 +2483,7 @@ static void gen_async_return(CodeGen *g, IrInstructionReturn *instruction) {
frame_index_trace_arg(g, ret_type) + 1, "");
LLVMValueRef dest_trace_ptr = LLVMBuildLoad(g->builder, awaiter_trace_ptr_ptr, "");
bool is_llvm_alloca;
LLVMValueRef my_err_trace_val = get_cur_err_ret_trace_val(g, instruction->base.scope, &is_llvm_alloca);
LLVMValueRef my_err_trace_val = get_cur_err_ret_trace_val(g, instruction->base.base.scope, &is_llvm_alloca);
LLVMValueRef args[] = { dest_trace_ptr, my_err_trace_val };
ZigLLVMBuildCall(g->builder, get_merge_err_ret_traces_fn_val(g), args, 2,
get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAuto, "");
@@ -2502,7 +2498,7 @@ static void gen_async_return(CodeGen *g, IrInstructionReturn *instruction) {
LLVMBuildRetVoid(g->builder);
}
static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrInstructionReturn *instruction) {
static LLVMValueRef ir_render_return(CodeGen *g, IrExecutableGen *executable, IrInstGenReturn *instruction) {
if (fn_is_async(g->cur_fn)) {
gen_async_return(g, instruction);
return nullptr;
@@ -2843,12 +2839,12 @@ static LLVMValueRef gen_rem(CodeGen *g, bool want_runtime_safety, bool want_fast
}
static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
IrInstructionBinOp *bin_op_instruction)
static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutableGen *executable,
IrInstGenBinOp *bin_op_instruction)
{
IrBinOp op_id = bin_op_instruction->op_id;
IrInstruction *op1 = bin_op_instruction->op1;
IrInstruction *op2 = bin_op_instruction->op2;
IrInstGen *op1 = bin_op_instruction->op1;
IrInstGen *op2 = bin_op_instruction->op2;
ZigType *operand_type = op1->value->type;
ZigType *scalar_type = (operand_type->id == ZigTypeIdVector) ? operand_type->data.vector.elem_type : operand_type;
@@ -3053,8 +3049,8 @@ static void add_error_range_check(CodeGen *g, ZigType *err_set_type, ZigType *in
}
}
static LLVMValueRef ir_render_resize_slice(CodeGen *g, IrExecutable *executable,
IrInstructionResizeSlice *instruction)
static LLVMValueRef ir_render_resize_slice(CodeGen *g, IrExecutableGen *executable,
IrInstGenResizeSlice *instruction)
{
ZigType *actual_type = instruction->operand->value->type;
ZigType *wanted_type = instruction->base.value->type;
@@ -3121,11 +3117,17 @@ static LLVMValueRef ir_render_resize_slice(CodeGen *g, IrExecutable *executable,
return result_loc;
}
static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
IrInstructionCast *cast_instruction)
static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutableGen *executable,
IrInstGenCast *cast_instruction)
{
Error err;
ZigType *actual_type = cast_instruction->value->value->type;
ZigType *wanted_type = cast_instruction->base.value->type;
bool wanted_type_has_bits;
if ((err = type_has_bits2(g, wanted_type, &wanted_type_has_bits)))
codegen_report_errors_and_exit(g);
if (!wanted_type_has_bits)
return nullptr;
LLVMValueRef expr_val = ir_llvm_value(g, cast_instruction->value);
ir_assert(expr_val, &cast_instruction->base);
@@ -3199,8 +3201,8 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
zig_unreachable();
}
static LLVMValueRef ir_render_ptr_of_array_to_slice(CodeGen *g, IrExecutable *executable,
IrInstructionPtrOfArrayToSlice *instruction)
static LLVMValueRef ir_render_ptr_of_array_to_slice(CodeGen *g, IrExecutableGen *executable,
IrInstGenPtrOfArrayToSlice *instruction)
{
ZigType *actual_type = instruction->operand->value->type;
ZigType *slice_type = instruction->base.value->type;
@@ -3236,8 +3238,8 @@ static LLVMValueRef ir_render_ptr_of_array_to_slice(CodeGen *g, IrExecutable *ex
return result_loc;
}
static LLVMValueRef ir_render_ptr_cast(CodeGen *g, IrExecutable *executable,
IrInstructionPtrCastGen *instruction)
static LLVMValueRef ir_render_ptr_cast(CodeGen *g, IrExecutableGen *executable,
IrInstGenPtrCast *instruction)
{
ZigType *wanted_type = instruction->base.value->type;
if (!type_has_bits(wanted_type)) {
@@ -3262,8 +3264,8 @@ static LLVMValueRef ir_render_ptr_cast(CodeGen *g, IrExecutable *executable,
return result_ptr;
}
static LLVMValueRef ir_render_bit_cast(CodeGen *g, IrExecutable *executable,
IrInstructionBitCastGen *instruction)
static LLVMValueRef ir_render_bit_cast(CodeGen *g, IrExecutableGen *executable,
IrInstGenBitCast *instruction)
{
ZigType *wanted_type = instruction->base.value->type;
ZigType *actual_type = instruction->operand->value->type;
@@ -3286,8 +3288,8 @@ static LLVMValueRef ir_render_bit_cast(CodeGen *g, IrExecutable *executable,
}
}
static LLVMValueRef ir_render_widen_or_shorten(CodeGen *g, IrExecutable *executable,
IrInstructionWidenOrShorten *instruction)
static LLVMValueRef ir_render_widen_or_shorten(CodeGen *g, IrExecutableGen *executable,
IrInstGenWidenOrShorten *instruction)
{
ZigType *actual_type = instruction->target->value->type;
// TODO instead of this logic, use the Noop instruction to change the type from
@@ -3303,7 +3305,7 @@ static LLVMValueRef ir_render_widen_or_shorten(CodeGen *g, IrExecutable *executa
instruction->base.value->type, target_val);
}
static LLVMValueRef ir_render_int_to_ptr(CodeGen *g, IrExecutable *executable, IrInstructionIntToPtr *instruction) {
static LLVMValueRef ir_render_int_to_ptr(CodeGen *g, IrExecutableGen *executable, IrInstGenIntToPtr *instruction) {
ZigType *wanted_type = instruction->base.value->type;
LLVMValueRef target_val = ir_llvm_value(g, instruction->target);
@@ -3341,13 +3343,13 @@ static LLVMValueRef ir_render_int_to_ptr(CodeGen *g, IrExecutable *executable, I
return LLVMBuildIntToPtr(g->builder, target_val, get_llvm_type(g, wanted_type), "");
}
static LLVMValueRef ir_render_ptr_to_int(CodeGen *g, IrExecutable *executable, IrInstructionPtrToInt *instruction) {
static LLVMValueRef ir_render_ptr_to_int(CodeGen *g, IrExecutableGen *executable, IrInstGenPtrToInt *instruction) {
ZigType *wanted_type = instruction->base.value->type;
LLVMValueRef target_val = ir_llvm_value(g, instruction->target);
return LLVMBuildPtrToInt(g->builder, target_val, get_llvm_type(g, wanted_type), "");
}
static LLVMValueRef ir_render_int_to_enum(CodeGen *g, IrExecutable *executable, IrInstructionIntToEnum *instruction) {
static LLVMValueRef ir_render_int_to_enum(CodeGen *g, IrExecutableGen *executable, IrInstGenIntToEnum *instruction) {
ZigType *wanted_type = instruction->base.value->type;
assert(wanted_type->id == ZigTypeIdEnum);
ZigType *tag_int_type = wanted_type->data.enumeration.tag_int_type;
@@ -3374,7 +3376,7 @@ static LLVMValueRef ir_render_int_to_enum(CodeGen *g, IrExecutable *executable,
return tag_int_value;
}
static LLVMValueRef ir_render_int_to_err(CodeGen *g, IrExecutable *executable, IrInstructionIntToErr *instruction) {
static LLVMValueRef ir_render_int_to_err(CodeGen *g, IrExecutableGen *executable, IrInstGenIntToErr *instruction) {
ZigType *wanted_type = instruction->base.value->type;
assert(wanted_type->id == ZigTypeIdErrorSet);
@@ -3391,7 +3393,7 @@ static LLVMValueRef ir_render_int_to_err(CodeGen *g, IrExecutable *executable, I
return gen_widen_or_shorten(g, false, actual_type, g->err_tag_type, target_val);
}
static LLVMValueRef ir_render_err_to_int(CodeGen *g, IrExecutable *executable, IrInstructionErrToInt *instruction) {
static LLVMValueRef ir_render_err_to_int(CodeGen *g, IrExecutableGen *executable, IrInstGenErrToInt *instruction) {
ZigType *wanted_type = instruction->base.value->type;
assert(wanted_type->id == ZigTypeIdInt);
assert(!wanted_type->data.integral.is_signed);
@@ -3417,8 +3419,8 @@ static LLVMValueRef ir_render_err_to_int(CodeGen *g, IrExecutable *executable, I
}
}
static LLVMValueRef ir_render_unreachable(CodeGen *g, IrExecutable *executable,
IrInstructionUnreachable *unreachable_instruction)
static LLVMValueRef ir_render_unreachable(CodeGen *g, IrExecutableGen *executable,
IrInstGenUnreachable *unreachable_instruction)
{
if (ir_want_runtime_safety(g, &unreachable_instruction->base)) {
gen_safety_crash(g, PanicMsgIdUnreachable);
@@ -3428,8 +3430,8 @@ static LLVMValueRef ir_render_unreachable(CodeGen *g, IrExecutable *executable,
return nullptr;
}
static LLVMValueRef ir_render_cond_br(CodeGen *g, IrExecutable *executable,
IrInstructionCondBr *cond_br_instruction)
static LLVMValueRef ir_render_cond_br(CodeGen *g, IrExecutableGen *executable,
IrInstGenCondBr *cond_br_instruction)
{
LLVMBuildCondBr(g->builder,
ir_llvm_value(g, cond_br_instruction->condition),
@@ -3438,51 +3440,56 @@ static LLVMValueRef ir_render_cond_br(CodeGen *g, IrExecutable *executable,
return nullptr;
}
static LLVMValueRef ir_render_br(CodeGen *g, IrExecutable *executable, IrInstructionBr *br_instruction) {
static LLVMValueRef ir_render_br(CodeGen *g, IrExecutableGen *executable, IrInstGenBr *br_instruction) {
LLVMBuildBr(g->builder, br_instruction->dest_block->llvm_block);
return nullptr;
}
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);
ZigType *operand_type = un_op_instruction->value->value->type;
ZigType *scalar_type = (operand_type->id == ZigTypeIdVector) ? operand_type->data.vector.elem_type : operand_type;
switch (op_id) {
case IrUnOpInvalid:
case IrUnOpOptional:
case IrUnOpDereference:
zig_unreachable();
case IrUnOpNegation:
case IrUnOpNegationWrap:
{
if (scalar_type->id == ZigTypeIdFloat) {
ZigLLVMSetFastMath(g->builder, ir_want_fast_math(g, &un_op_instruction->base));
return LLVMBuildFNeg(g->builder, expr, "");
} else if (scalar_type->id == ZigTypeIdInt) {
if (op_id == IrUnOpNegationWrap) {
return LLVMBuildNeg(g->builder, expr, "");
} else if (ir_want_runtime_safety(g, &un_op_instruction->base)) {
LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(expr));
return gen_overflow_op(g, operand_type, AddSubMulSub, zero, expr);
} else if (scalar_type->data.integral.is_signed) {
return LLVMBuildNSWNeg(g->builder, expr, "");
} else {
return LLVMBuildNUWNeg(g->builder, expr, "");
}
} else {
zig_unreachable();
}
}
case IrUnOpBinNot:
return LLVMBuildNot(g->builder, expr, "");
}
zig_unreachable();
static LLVMValueRef ir_render_binary_not(CodeGen *g, IrExecutableGen *executable,
IrInstGenBinaryNot *inst)
{
LLVMValueRef operand = ir_llvm_value(g, inst->operand);
return LLVMBuildNot(g->builder, operand, "");
}
static LLVMValueRef ir_render_bool_not(CodeGen *g, IrExecutable *executable, IrInstructionBoolNot *instruction) {
static LLVMValueRef ir_gen_negation(CodeGen *g, IrInstGen *inst, IrInstGen *operand, bool wrapping) {
LLVMValueRef llvm_operand = ir_llvm_value(g, operand);
ZigType *operand_type = operand->value->type;
ZigType *scalar_type = (operand_type->id == ZigTypeIdVector) ?
operand_type->data.vector.elem_type : operand_type;
if (scalar_type->id == ZigTypeIdFloat) {
ZigLLVMSetFastMath(g->builder, ir_want_fast_math(g, inst));
return LLVMBuildFNeg(g->builder, llvm_operand, "");
} else if (scalar_type->id == ZigTypeIdInt) {
if (wrapping) {
return LLVMBuildNeg(g->builder, llvm_operand, "");
} else if (ir_want_runtime_safety(g, inst)) {
LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(llvm_operand));
return gen_overflow_op(g, operand_type, AddSubMulSub, zero, llvm_operand);
} else if (scalar_type->data.integral.is_signed) {
return LLVMBuildNSWNeg(g->builder, llvm_operand, "");
} else {
return LLVMBuildNUWNeg(g->builder, llvm_operand, "");
}
} else {
zig_unreachable();
}
}
static LLVMValueRef ir_render_negation(CodeGen *g, IrExecutableGen *executable,
IrInstGenNegation *inst)
{
return ir_gen_negation(g, &inst->base, inst->operand, false);
}
static LLVMValueRef ir_render_negation_wrapping(CodeGen *g, IrExecutableGen *executable,
IrInstGenNegationWrapping *inst)
{
return ir_gen_negation(g, &inst->base, inst->operand, true);
}
static LLVMValueRef ir_render_bool_not(CodeGen *g, IrExecutableGen *executable, IrInstGenBoolNot *instruction) {
LLVMValueRef value = ir_llvm_value(g, instruction->value);
LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(value));
return LLVMBuildICmp(g->builder, LLVMIntEQ, value, zero, "");
@@ -3496,14 +3503,15 @@ static void render_decl_var(CodeGen *g, ZigVar *var) {
gen_var_debug_decl(g, var);
}
static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable, IrInstructionDeclVarGen *instruction) {
static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutableGen *executable, IrInstGenDeclVar *instruction) {
instruction->var->ptr_instruction = instruction->var_ptr;
instruction->var->did_the_decl_codegen = true;
render_decl_var(g, instruction->var);
return nullptr;
}
static LLVMValueRef ir_render_load_ptr(CodeGen *g, IrExecutable *executable,
IrInstructionLoadPtrGen *instruction)
static LLVMValueRef ir_render_load_ptr(CodeGen *g, IrExecutableGen *executable,
IrInstGenLoadPtr *instruction)
{
ZigType *child_type = instruction->base.value->type;
if (!type_has_bits(child_type))
@@ -3705,7 +3713,7 @@ static void gen_undef_init(CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_
}
}
static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, IrInstructionStorePtr *instruction) {
static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutableGen *executable, IrInstGenStorePtr *instruction) {
Error err;
ZigType *ptr_type = instruction->ptr->value->type;
@@ -3715,7 +3723,7 @@ static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, Ir
codegen_report_errors_and_exit(g);
if (!ptr_type_has_bits)
return nullptr;
if (instruction->ptr->ref_count == 0) {
if (instruction->ptr->base.ref_count == 0) {
// In this case, this StorePtr instruction should be elided. Something happened like this:
// var t = true;
// const x = if (t) Num.Two else unreachable;
@@ -3737,8 +3745,8 @@ static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, Ir
return nullptr;
}
static LLVMValueRef ir_render_vector_store_elem(CodeGen *g, IrExecutable *executable,
IrInstructionVectorStoreElem *instruction)
static LLVMValueRef ir_render_vector_store_elem(CodeGen *g, IrExecutableGen *executable,
IrInstGenVectorStoreElem *instruction)
{
LLVMValueRef vector_ptr = ir_llvm_value(g, instruction->vector_ptr);
LLVMValueRef index = ir_llvm_value(g, instruction->index);
@@ -3750,7 +3758,7 @@ static LLVMValueRef ir_render_vector_store_elem(CodeGen *g, IrExecutable *execut
return nullptr;
}
static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutable *executable, IrInstructionVarPtr *instruction) {
static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutableGen *executable, IrInstGenVarPtr *instruction) {
if (instruction->base.value->special != ConstValSpecialRuntime)
return ir_llvm_value(g, &instruction->base);
ZigVar *var = instruction->var;
@@ -3762,8 +3770,8 @@ static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutable *executable, IrIn
}
}
static LLVMValueRef ir_render_return_ptr(CodeGen *g, IrExecutable *executable,
IrInstructionReturnPtr *instruction)
static LLVMValueRef ir_render_return_ptr(CodeGen *g, IrExecutableGen *executable,
IrInstGenReturnPtr *instruction)
{
if (!type_has_bits(instruction->base.value->type))
return nullptr;
@@ -3771,7 +3779,7 @@ static LLVMValueRef ir_render_return_ptr(CodeGen *g, IrExecutable *executable,
return g->cur_ret_ptr;
}
static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrInstructionElemPtr *instruction) {
static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutableGen *executable, IrInstGenElemPtr *instruction) {
LLVMValueRef array_ptr_ptr = ir_llvm_value(g, instruction->array_ptr);
ZigType *array_ptr_type = instruction->array_ptr->value->type;
assert(array_ptr_type->id == ZigTypeIdPointer);
@@ -3947,7 +3955,7 @@ static void render_async_spills(CodeGen *g) {
ZigType *frame_type = g->cur_fn->frame_type->data.frame.locals_struct;
for (size_t alloca_i = 0; alloca_i < g->cur_fn->alloca_gen_list.length; alloca_i += 1) {
IrInstructionAllocaGen *instruction = g->cur_fn->alloca_gen_list.at(alloca_i);
IrInstGenAlloca *instruction = g->cur_fn->alloca_gen_list.at(alloca_i);
if (instruction->field_index == SIZE_MAX)
continue;
@@ -3966,7 +3974,7 @@ static void render_async_var_decls(CodeGen *g, Scope *scope) {
return;
case ScopeIdVarDecl: {
ZigVar *var = reinterpret_cast<ScopeVarDecl *>(scope)->var;
if (var->ptr_instruction != nullptr) {
if (var->did_the_decl_codegen) {
render_decl_var(g, var);
}
// fallthrough
@@ -4014,7 +4022,7 @@ static void gen_init_stack_trace(CodeGen *g, LLVMValueRef trace_field_ptr, LLVMV
LLVMBuildStore(g->builder, LLVMConstInt(usize_type_ref, stack_trace_ptr_count, false), addrs_len_ptr);
}
static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstructionCallGen *instruction) {
static LLVMValueRef ir_render_call(CodeGen *g, IrExecutableGen *executable, IrInstGenCall *instruction) {
LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
LLVMValueRef fn_val;
@@ -4149,7 +4157,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
LLVMValueRef err_ret_trace_ptr_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc,
frame_index_trace_arg(g, src_return_type) + 1, "");
bool is_llvm_alloca;
LLVMValueRef my_err_ret_trace_val = get_cur_err_ret_trace_val(g, instruction->base.scope,
LLVMValueRef my_err_ret_trace_val = get_cur_err_ret_trace_val(g, instruction->base.base.scope,
&is_llvm_alloca);
LLVMBuildStore(g->builder, my_err_ret_trace_val, err_ret_trace_ptr_ptr);
}
@@ -4208,7 +4216,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
gen_init_stack_trace(g, trace_field_ptr, addrs_field_ptr);
bool is_llvm_alloca;
gen_param_values.append(get_cur_err_ret_trace_val(g, instruction->base.scope, &is_llvm_alloca));
gen_param_values.append(get_cur_err_ret_trace_val(g, instruction->base.base.scope, &is_llvm_alloca));
}
}
} else {
@@ -4217,7 +4225,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
}
if (prefix_arg_err_ret_stack) {
bool is_llvm_alloca;
gen_param_values.append(get_cur_err_ret_trace_val(g, instruction->base.scope, &is_llvm_alloca));
gen_param_values.append(get_cur_err_ret_trace_val(g, instruction->base.base.scope, &is_llvm_alloca));
}
}
FnWalk fn_walk = {};
@@ -4327,13 +4335,13 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
LLVMPositionBuilderAtEnd(g->builder, call_bb);
gen_assert_resume_id(g, &instruction->base, ResumeIdReturn, PanicMsgIdResumedAnAwaitingFn, nullptr);
render_async_var_decls(g, instruction->base.scope);
render_async_var_decls(g, instruction->base.base.scope);
if (!type_has_bits(src_return_type))
return nullptr;
if (result_loc != nullptr) {
if (instruction->result_loc->id == IrInstructionIdReturnPtr) {
if (instruction->result_loc->id == IrInstGenIdReturnPtr) {
instruction->base.spill = nullptr;
return g->cur_ret_ptr;
} else {
@@ -4393,8 +4401,8 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
}
}
static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executable,
IrInstructionStructFieldPtr *instruction)
static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutableGen *executable,
IrInstGenStructFieldPtr *instruction)
{
Error err;
@@ -4444,8 +4452,8 @@ static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executa
return field_ptr_val;
}
static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executable,
IrInstructionUnionFieldPtr *instruction)
static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutableGen *executable,
IrInstGenUnionFieldPtr *instruction)
{
if (instruction->base.value->special != ConstValSpecialRuntime)
return nullptr;
@@ -4544,8 +4552,8 @@ static size_t find_asm_index(CodeGen *g, AstNode *node, AsmToken *tok, Buf *src_
return SIZE_MAX;
}
static LLVMValueRef ir_render_asm_gen(CodeGen *g, IrExecutable *executable, IrInstructionAsmGen *instruction) {
AstNode *asm_node = instruction->base.source_node;
static LLVMValueRef ir_render_asm_gen(CodeGen *g, IrExecutableGen *executable, IrInstGenAsm *instruction) {
AstNode *asm_node = instruction->base.base.source_node;
assert(asm_node->type == NodeTypeAsmExpr);
AstNodeAsmExpr *asm_expr = &asm_node->data.asm_expr;
@@ -4629,7 +4637,7 @@ static LLVMValueRef ir_render_asm_gen(CodeGen *g, IrExecutable *executable, IrIn
for (size_t i = 0; i < asm_expr->input_list.length; i += 1, total_index += 1, param_index += 1) {
AsmInput *asm_input = asm_expr->input_list.at(i);
buf_replace(asm_input->constraint, ',', '|');
IrInstruction *ir_input = instruction->input_list[i];
IrInstGen *ir_input = instruction->input_list[i];
buf_append_buf(&constraint_buf, asm_input->constraint);
if (total_index + 1 < total_constraint_count) {
buf_append_char(&constraint_buf, ',');
@@ -4692,14 +4700,14 @@ static LLVMValueRef gen_non_null_bit(CodeGen *g, ZigType *maybe_type, LLVMValueR
return gen_load_untyped(g, maybe_field_ptr, 0, false, "");
}
static LLVMValueRef ir_render_test_non_null(CodeGen *g, IrExecutable *executable,
IrInstructionTestNonNull *instruction)
static LLVMValueRef ir_render_test_non_null(CodeGen *g, IrExecutableGen *executable,
IrInstGenTestNonNull *instruction)
{
return gen_non_null_bit(g, instruction->value->value->type, ir_llvm_value(g, instruction->value));
}
static LLVMValueRef ir_render_optional_unwrap_ptr(CodeGen *g, IrExecutable *executable,
IrInstructionOptionalUnwrapPtr *instruction)
static LLVMValueRef ir_render_optional_unwrap_ptr(CodeGen *g, IrExecutableGen *executable,
IrInstGenOptionalUnwrapPtr *instruction)
{
if (instruction->base.value->special != ConstValSpecialRuntime)
return nullptr;
@@ -4723,6 +4731,10 @@ static LLVMValueRef ir_render_optional_unwrap_ptr(CodeGen *g, IrExecutable *exec
LLVMPositionBuilderAtEnd(g->builder, ok_block);
}
if (!type_has_bits(child_type)) {
if (instruction->initializing) {
LLVMValueRef non_null_bit = LLVMConstInt(LLVMInt1Type(), 1, false);
gen_store_untyped(g, non_null_bit, base_ptr, 0, false);
}
return nullptr;
} else {
bool is_scalar = !handle_is_ptr(maybe_type);
@@ -4801,7 +4813,7 @@ static LLVMValueRef get_int_builtin_fn(CodeGen *g, ZigType *expr_type, BuiltinFn
return fn_val;
}
static LLVMValueRef ir_render_clz(CodeGen *g, IrExecutable *executable, IrInstructionClz *instruction) {
static LLVMValueRef ir_render_clz(CodeGen *g, IrExecutableGen *executable, IrInstGenClz *instruction) {
ZigType *int_type = instruction->op->value->type;
LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdClz);
LLVMValueRef operand = ir_llvm_value(g, instruction->op);
@@ -4813,7 +4825,7 @@ static LLVMValueRef ir_render_clz(CodeGen *g, IrExecutable *executable, IrInstru
return gen_widen_or_shorten(g, false, int_type, instruction->base.value->type, wrong_size_int);
}
static LLVMValueRef ir_render_ctz(CodeGen *g, IrExecutable *executable, IrInstructionCtz *instruction) {
static LLVMValueRef ir_render_ctz(CodeGen *g, IrExecutableGen *executable, IrInstGenCtz *instruction) {
ZigType *int_type = instruction->op->value->type;
LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdCtz);
LLVMValueRef operand = ir_llvm_value(g, instruction->op);
@@ -4825,7 +4837,7 @@ static LLVMValueRef ir_render_ctz(CodeGen *g, IrExecutable *executable, IrInstru
return gen_widen_or_shorten(g, false, int_type, instruction->base.value->type, wrong_size_int);
}
static LLVMValueRef ir_render_shuffle_vector(CodeGen *g, IrExecutable *executable, IrInstructionShuffleVector *instruction) {
static LLVMValueRef ir_render_shuffle_vector(CodeGen *g, IrExecutableGen *executable, IrInstGenShuffleVector *instruction) {
uint64_t len_a = instruction->a->value->type->data.vector.len;
uint64_t len_mask = instruction->mask->value->type->data.vector.len;
@@ -4834,7 +4846,7 @@ static LLVMValueRef ir_render_shuffle_vector(CodeGen *g, IrExecutable *executabl
// when changing code, so Zig uses negative numbers to index the
// second vector. These start at -1 and go down, and are easiest to use
// with the ~ operator. Here we convert between the two formats.
IrInstruction *mask = instruction->mask;
IrInstGen *mask = instruction->mask;
LLVMValueRef *values = allocate<LLVMValueRef>(len_mask);
for (uint64_t i = 0; i < len_mask; i++) {
if (mask->value->data.x_array.data.s_none.elements[i].special == ConstValSpecialUndef) {
@@ -4855,7 +4867,7 @@ static LLVMValueRef ir_render_shuffle_vector(CodeGen *g, IrExecutable *executabl
llvm_mask_value, "");
}
static LLVMValueRef ir_render_splat(CodeGen *g, IrExecutable *executable, IrInstructionSplatGen *instruction) {
static LLVMValueRef ir_render_splat(CodeGen *g, IrExecutableGen *executable, IrInstGenSplat *instruction) {
ZigType *result_type = instruction->base.value->type;
ir_assert(result_type->id == ZigTypeIdVector, &instruction->base);
uint32_t len = result_type->data.vector.len;
@@ -4867,7 +4879,7 @@ static LLVMValueRef ir_render_splat(CodeGen *g, IrExecutable *executable, IrInst
return LLVMBuildShuffleVector(g->builder, op_vector, undef_vector, LLVMConstNull(mask_llvm_type), "");
}
static LLVMValueRef ir_render_pop_count(CodeGen *g, IrExecutable *executable, IrInstructionPopCount *instruction) {
static LLVMValueRef ir_render_pop_count(CodeGen *g, IrExecutableGen *executable, IrInstGenPopCount *instruction) {
ZigType *int_type = instruction->op->value->type;
LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdPopCount);
LLVMValueRef operand = ir_llvm_value(g, instruction->op);
@@ -4875,7 +4887,7 @@ static LLVMValueRef ir_render_pop_count(CodeGen *g, IrExecutable *executable, Ir
return gen_widen_or_shorten(g, false, int_type, instruction->base.value->type, wrong_size_int);
}
static LLVMValueRef ir_render_switch_br(CodeGen *g, IrExecutable *executable, IrInstructionSwitchBr *instruction) {
static LLVMValueRef ir_render_switch_br(CodeGen *g, IrExecutableGen *executable, IrInstGenSwitchBr *instruction) {
ZigType *target_type = instruction->target_value->value->type;
LLVMBasicBlockRef else_block = instruction->else_block->llvm_block;
@@ -4889,7 +4901,7 @@ static LLVMValueRef ir_render_switch_br(CodeGen *g, IrExecutable *executable, Ir
(unsigned)instruction->case_count);
for (size_t i = 0; i < instruction->case_count; i += 1) {
IrInstructionSwitchBrCase *this_case = &instruction->cases[i];
IrInstGenSwitchBrCase *this_case = &instruction->cases[i];
LLVMValueRef case_value = ir_llvm_value(g, this_case->value);
if (target_type->id == ZigTypeIdPointer) {
@@ -4903,7 +4915,7 @@ static LLVMValueRef ir_render_switch_br(CodeGen *g, IrExecutable *executable, Ir
return nullptr;
}
static LLVMValueRef ir_render_phi(CodeGen *g, IrExecutable *executable, IrInstructionPhi *instruction) {
static LLVMValueRef ir_render_phi(CodeGen *g, IrExecutableGen *executable, IrInstGenPhi *instruction) {
if (!type_has_bits(instruction->base.value->type))
return nullptr;
@@ -4925,7 +4937,7 @@ static LLVMValueRef ir_render_phi(CodeGen *g, IrExecutable *executable, IrInstru
return phi;
}
static LLVMValueRef ir_render_ref(CodeGen *g, IrExecutable *executable, IrInstructionRefGen *instruction) {
static LLVMValueRef ir_render_ref(CodeGen *g, IrExecutableGen *executable, IrInstGenRef *instruction) {
if (!type_has_bits(instruction->base.value->type)) {
return nullptr;
}
@@ -4939,7 +4951,7 @@ static LLVMValueRef ir_render_ref(CodeGen *g, IrExecutable *executable, IrInstru
}
}
static LLVMValueRef ir_render_err_name(CodeGen *g, IrExecutable *executable, IrInstructionErrName *instruction) {
static LLVMValueRef ir_render_err_name(CodeGen *g, IrExecutableGen *executable, IrInstGenErrName *instruction) {
assert(g->generate_error_name_table);
if (g->errors_by_index.length == 1) {
@@ -5060,13 +5072,13 @@ static LLVMValueRef get_enum_tag_name_function(CodeGen *g, ZigType *enum_type) {
return fn_val;
}
static LLVMValueRef ir_render_enum_tag_name(CodeGen *g, IrExecutable *executable,
IrInstructionTagName *instruction)
static LLVMValueRef ir_render_enum_tag_name(CodeGen *g, IrExecutableGen *executable,
IrInstGenTagName *instruction)
{
ZigType *enum_type = instruction->target->value->type;
assert(enum_type->id == ZigTypeIdEnum);
if (enum_type->data.enumeration.non_exhaustive) {
add_node_error(g, instruction->base.source_node,
add_node_error(g, instruction->base.base.source_node,
buf_sprintf("TODO @tagName on non-exhaustive enum https://github.com/ziglang/zig/issues/3991"));
codegen_report_errors_and_exit(g);
}
@@ -5078,8 +5090,8 @@ static LLVMValueRef ir_render_enum_tag_name(CodeGen *g, IrExecutable *executable
get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAuto, "");
}
static LLVMValueRef ir_render_field_parent_ptr(CodeGen *g, IrExecutable *executable,
IrInstructionFieldParentPtr *instruction)
static LLVMValueRef ir_render_field_parent_ptr(CodeGen *g, IrExecutableGen *executable,
IrInstGenFieldParentPtr *instruction)
{
ZigType *container_ptr_type = instruction->base.value->type;
assert(container_ptr_type->id == ZigTypeIdPointer);
@@ -5105,7 +5117,7 @@ static LLVMValueRef ir_render_field_parent_ptr(CodeGen *g, IrExecutable *executa
}
}
static LLVMValueRef ir_render_align_cast(CodeGen *g, IrExecutable *executable, IrInstructionAlignCast *instruction) {
static LLVMValueRef ir_render_align_cast(CodeGen *g, IrExecutableGen *executable, IrInstGenAlignCast *instruction) {
LLVMValueRef target_val = ir_llvm_value(g, instruction->target);
assert(target_val);
@@ -5168,11 +5180,11 @@ static LLVMValueRef ir_render_align_cast(CodeGen *g, IrExecutable *executable, I
return target_val;
}
static LLVMValueRef ir_render_error_return_trace(CodeGen *g, IrExecutable *executable,
IrInstructionErrorReturnTrace *instruction)
static LLVMValueRef ir_render_error_return_trace(CodeGen *g, IrExecutableGen *executable,
IrInstGenErrorReturnTrace *instruction)
{
bool is_llvm_alloca;
LLVMValueRef cur_err_ret_trace_val = get_cur_err_ret_trace_val(g, instruction->base.scope, &is_llvm_alloca);
LLVMValueRef cur_err_ret_trace_val = get_cur_err_ret_trace_val(g, instruction->base.base.scope, &is_llvm_alloca);
if (cur_err_ret_trace_val == nullptr) {
return LLVMConstNull(get_llvm_type(g, ptr_to_stack_trace_type(g)));
}
@@ -5210,7 +5222,7 @@ static enum ZigLLVM_AtomicRMWBinOp to_ZigLLVMAtomicRMWBinOp(AtomicRmwOp op, bool
zig_unreachable();
}
static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutable *executable, IrInstructionCmpxchgGen *instruction) {
static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutableGen *executable, IrInstGenCmpxchg *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);
@@ -5251,13 +5263,13 @@ static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutable *executable, IrIn
return result_loc;
}
static LLVMValueRef ir_render_fence(CodeGen *g, IrExecutable *executable, IrInstructionFence *instruction) {
static LLVMValueRef ir_render_fence(CodeGen *g, IrExecutableGen *executable, IrInstGenFence *instruction) {
LLVMAtomicOrdering atomic_order = to_LLVMAtomicOrdering(instruction->order);
LLVMBuildFence(g->builder, atomic_order, false, "");
return nullptr;
}
static LLVMValueRef ir_render_truncate(CodeGen *g, IrExecutable *executable, IrInstructionTruncate *instruction) {
static LLVMValueRef ir_render_truncate(CodeGen *g, IrExecutableGen *executable, IrInstGenTruncate *instruction) {
LLVMValueRef target_val = ir_llvm_value(g, instruction->target);
ZigType *dest_type = instruction->base.value->type;
ZigType *src_type = instruction->target->value->type;
@@ -5272,7 +5284,7 @@ static LLVMValueRef ir_render_truncate(CodeGen *g, IrExecutable *executable, IrI
}
}
static LLVMValueRef ir_render_memset(CodeGen *g, IrExecutable *executable, IrInstructionMemset *instruction) {
static LLVMValueRef ir_render_memset(CodeGen *g, IrExecutableGen *executable, IrInstGenMemset *instruction) {
LLVMValueRef dest_ptr = ir_llvm_value(g, instruction->dest_ptr);
LLVMValueRef len_val = ir_llvm_value(g, instruction->count);
@@ -5284,7 +5296,7 @@ static LLVMValueRef ir_render_memset(CodeGen *g, IrExecutable *executable, IrIns
bool val_is_undef = value_is_all_undef(g, instruction->byte->value);
LLVMValueRef fill_char;
if (val_is_undef && ir_want_runtime_safety_scope(g, instruction->base.scope)) {
if (val_is_undef && ir_want_runtime_safety_scope(g, instruction->base.base.scope)) {
fill_char = LLVMConstInt(LLVMInt8Type(), 0xaa, false);
} else {
fill_char = ir_llvm_value(g, instruction->byte);
@@ -5298,7 +5310,7 @@ static LLVMValueRef ir_render_memset(CodeGen *g, IrExecutable *executable, IrIns
return nullptr;
}
static LLVMValueRef ir_render_memcpy(CodeGen *g, IrExecutable *executable, IrInstructionMemcpy *instruction) {
static LLVMValueRef ir_render_memcpy(CodeGen *g, IrExecutableGen *executable, IrInstGenMemcpy *instruction) {
LLVMValueRef dest_ptr = ir_llvm_value(g, instruction->dest_ptr);
LLVMValueRef src_ptr = ir_llvm_value(g, instruction->src_ptr);
LLVMValueRef len_val = ir_llvm_value(g, instruction->count);
@@ -5320,7 +5332,7 @@ static LLVMValueRef ir_render_memcpy(CodeGen *g, IrExecutable *executable, IrIns
return nullptr;
}
static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInstructionSliceGen *instruction) {
static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutableGen *executable, IrInstGenSlice *instruction) {
LLVMValueRef array_ptr_ptr = ir_llvm_value(g, instruction->ptr);
ZigType *array_ptr_type = instruction->ptr->value->type;
assert(array_ptr_type->id == ZigTypeIdPointer);
@@ -5482,13 +5494,13 @@ static LLVMValueRef get_trap_fn_val(CodeGen *g) {
}
static LLVMValueRef ir_render_breakpoint(CodeGen *g, IrExecutable *executable, IrInstructionBreakpoint *instruction) {
static LLVMValueRef ir_render_breakpoint(CodeGen *g, IrExecutableGen *executable, IrInstGenBreakpoint *instruction) {
LLVMBuildCall(g->builder, get_trap_fn_val(g), nullptr, 0, "");
return nullptr;
}
static LLVMValueRef ir_render_return_address(CodeGen *g, IrExecutable *executable,
IrInstructionReturnAddress *instruction)
static LLVMValueRef ir_render_return_address(CodeGen *g, IrExecutableGen *executable,
IrInstGenReturnAddress *instruction)
{
LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_i32->llvm_type);
LLVMValueRef ptr_val = LLVMBuildCall(g->builder, get_return_address_fn_val(g), &zero, 1, "");
@@ -5509,19 +5521,19 @@ static LLVMValueRef get_frame_address_fn_val(CodeGen *g) {
return g->frame_address_fn_val;
}
static LLVMValueRef ir_render_frame_address(CodeGen *g, IrExecutable *executable,
IrInstructionFrameAddress *instruction)
static LLVMValueRef ir_render_frame_address(CodeGen *g, IrExecutableGen *executable,
IrInstGenFrameAddress *instruction)
{
LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_i32->llvm_type);
LLVMValueRef ptr_val = LLVMBuildCall(g->builder, get_frame_address_fn_val(g), &zero, 1, "");
return LLVMBuildPtrToInt(g->builder, ptr_val, g->builtin_types.entry_usize->llvm_type, "");
}
static LLVMValueRef ir_render_handle(CodeGen *g, IrExecutable *executable, IrInstructionFrameHandle *instruction) {
static LLVMValueRef ir_render_handle(CodeGen *g, IrExecutableGen *executable, IrInstGenFrameHandle *instruction) {
return g->cur_frame_ptr;
}
static LLVMValueRef render_shl_with_overflow(CodeGen *g, IrInstructionOverflowOp *instruction) {
static LLVMValueRef render_shl_with_overflow(CodeGen *g, IrInstGenOverflowOp *instruction) {
ZigType *int_type = instruction->result_ptr_type;
assert(int_type->id == ZigTypeIdInt);
@@ -5546,7 +5558,7 @@ static LLVMValueRef render_shl_with_overflow(CodeGen *g, IrInstructionOverflowOp
return overflow_bit;
}
static LLVMValueRef ir_render_overflow_op(CodeGen *g, IrExecutable *executable, IrInstructionOverflowOp *instruction) {
static LLVMValueRef ir_render_overflow_op(CodeGen *g, IrExecutableGen *executable, IrInstGenOverflowOp *instruction) {
AddSubMul add_sub_mul;
switch (instruction->op) {
case IrOverflowOpAdd:
@@ -5584,7 +5596,7 @@ static LLVMValueRef ir_render_overflow_op(CodeGen *g, IrExecutable *executable,
return overflow_bit;
}
static LLVMValueRef ir_render_test_err(CodeGen *g, IrExecutable *executable, IrInstructionTestErrGen *instruction) {
static LLVMValueRef ir_render_test_err(CodeGen *g, IrExecutableGen *executable, IrInstGenTestErr *instruction) {
ZigType *err_union_type = instruction->err_union->value->type;
ZigType *payload_type = err_union_type->data.error_union.payload_type;
LLVMValueRef err_union_handle = ir_llvm_value(g, instruction->err_union);
@@ -5601,8 +5613,8 @@ 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)
static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, IrExecutableGen *executable,
IrInstGenUnwrapErrCode *instruction)
{
if (instruction->base.value->special != ConstValSpecialRuntime)
return nullptr;
@@ -5621,8 +5633,8 @@ 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, IrExecutableGen *executable,
IrInstGenUnwrapErrPayload *instruction)
{
Error err;
@@ -5665,7 +5677,7 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *execu
LLVMBuildCondBr(g->builder, cond_val, ok_block, err_block);
LLVMPositionBuilderAtEnd(g->builder, err_block);
gen_safety_crash_for_err(g, err_val, instruction->base.scope);
gen_safety_crash_for_err(g, err_val, instruction->base.base.scope);
LLVMPositionBuilderAtEnd(g->builder, ok_block);
}
@@ -5682,7 +5694,7 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *execu
}
}
static LLVMValueRef ir_render_optional_wrap(CodeGen *g, IrExecutable *executable, IrInstructionOptionalWrap *instruction) {
static LLVMValueRef ir_render_optional_wrap(CodeGen *g, IrExecutableGen *executable, IrInstGenOptionalWrap *instruction) {
ZigType *wanted_type = instruction->base.value->type;
assert(wanted_type->id == ZigTypeIdOptional);
@@ -5718,7 +5730,7 @@ static LLVMValueRef ir_render_optional_wrap(CodeGen *g, IrExecutable *executable
return result_loc;
}
static LLVMValueRef ir_render_err_wrap_code(CodeGen *g, IrExecutable *executable, IrInstructionErrWrapCode *instruction) {
static LLVMValueRef ir_render_err_wrap_code(CodeGen *g, IrExecutableGen *executable, IrInstGenErrWrapCode *instruction) {
ZigType *wanted_type = instruction->base.value->type;
assert(wanted_type->id == ZigTypeIdErrorUnion);
@@ -5738,7 +5750,7 @@ static LLVMValueRef ir_render_err_wrap_code(CodeGen *g, IrExecutable *executable
return result_loc;
}
static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutable *executable, IrInstructionErrWrapPayload *instruction) {
static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutableGen *executable, IrInstGenErrWrapPayload *instruction) {
ZigType *wanted_type = instruction->base.value->type;
assert(wanted_type->id == ZigTypeIdErrorUnion);
@@ -5769,7 +5781,7 @@ static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutable *executa
return result_loc;
}
static LLVMValueRef ir_render_union_tag(CodeGen *g, IrExecutable *executable, IrInstructionUnionTag *instruction) {
static LLVMValueRef ir_render_union_tag(CodeGen *g, IrExecutableGen *executable, IrInstGenUnionTag *instruction) {
ZigType *union_type = instruction->value->value->type;
ZigType *tag_type = union_type->data.unionation.tag_type;
@@ -5787,15 +5799,15 @@ static LLVMValueRef ir_render_union_tag(CodeGen *g, IrExecutable *executable, Ir
return get_handle_value(g, tag_field_ptr, tag_type, ptr_type);
}
static LLVMValueRef ir_render_panic(CodeGen *g, IrExecutable *executable, IrInstructionPanic *instruction) {
static LLVMValueRef ir_render_panic(CodeGen *g, IrExecutableGen *executable, IrInstGenPanic *instruction) {
bool is_llvm_alloca;
LLVMValueRef err_ret_trace_val = get_cur_err_ret_trace_val(g, instruction->base.scope, &is_llvm_alloca);
LLVMValueRef err_ret_trace_val = get_cur_err_ret_trace_val(g, instruction->base.base.scope, &is_llvm_alloca);
gen_panic(g, ir_llvm_value(g, instruction->msg), err_ret_trace_val, is_llvm_alloca);
return nullptr;
}
static LLVMValueRef ir_render_atomic_rmw(CodeGen *g, IrExecutable *executable,
IrInstructionAtomicRmw *instruction)
static LLVMValueRef ir_render_atomic_rmw(CodeGen *g, IrExecutableGen *executable,
IrInstGenAtomicRmw *instruction)
{
bool is_signed;
ZigType *operand_type = instruction->operand->value->type;
@@ -5805,8 +5817,8 @@ static LLVMValueRef ir_render_atomic_rmw(CodeGen *g, IrExecutable *executable,
} else {
is_signed = false;
}
enum ZigLLVM_AtomicRMWBinOp op = to_ZigLLVMAtomicRMWBinOp(instruction->resolved_op, is_signed, is_float);
LLVMAtomicOrdering ordering = to_LLVMAtomicOrdering(instruction->resolved_ordering);
enum ZigLLVM_AtomicRMWBinOp op = to_ZigLLVMAtomicRMWBinOp(instruction->op, is_signed, is_float);
LLVMAtomicOrdering ordering = to_LLVMAtomicOrdering(instruction->ordering);
LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);
LLVMValueRef operand = ir_llvm_value(g, instruction->operand);
@@ -5823,20 +5835,20 @@ static LLVMValueRef ir_render_atomic_rmw(CodeGen *g, IrExecutable *executable,
return LLVMBuildIntToPtr(g->builder, uncasted_result, get_llvm_type(g, operand_type), "");
}
static LLVMValueRef ir_render_atomic_load(CodeGen *g, IrExecutable *executable,
IrInstructionAtomicLoad *instruction)
static LLVMValueRef ir_render_atomic_load(CodeGen *g, IrExecutableGen *executable,
IrInstGenAtomicLoad *instruction)
{
LLVMAtomicOrdering ordering = to_LLVMAtomicOrdering(instruction->resolved_ordering);
LLVMAtomicOrdering ordering = to_LLVMAtomicOrdering(instruction->ordering);
LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);
LLVMValueRef load_inst = gen_load(g, ptr, instruction->ptr->value->type, "");
LLVMSetOrdering(load_inst, ordering);
return load_inst;
}
static LLVMValueRef ir_render_atomic_store(CodeGen *g, IrExecutable *executable,
IrInstructionAtomicStore *instruction)
static LLVMValueRef ir_render_atomic_store(CodeGen *g, IrExecutableGen *executable,
IrInstGenAtomicStore *instruction)
{
LLVMAtomicOrdering ordering = to_LLVMAtomicOrdering(instruction->resolved_ordering);
LLVMAtomicOrdering ordering = to_LLVMAtomicOrdering(instruction->ordering);
LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);
LLVMValueRef value = ir_llvm_value(g, instruction->value);
LLVMValueRef store_inst = gen_store(g, value, ptr, instruction->ptr->value->type);
@@ -5844,13 +5856,13 @@ static LLVMValueRef ir_render_atomic_store(CodeGen *g, IrExecutable *executable,
return nullptr;
}
static LLVMValueRef ir_render_float_op(CodeGen *g, IrExecutable *executable, IrInstructionFloatOp *instruction) {
static LLVMValueRef ir_render_float_op(CodeGen *g, IrExecutableGen *executable, IrInstGenFloatOp *instruction) {
LLVMValueRef operand = ir_llvm_value(g, instruction->operand);
LLVMValueRef fn_val = get_float_fn(g, instruction->base.value->type, ZigLLVMFnIdFloatOp, instruction->fn_id);
return LLVMBuildCall(g->builder, fn_val, &operand, 1, "");
}
static LLVMValueRef ir_render_mul_add(CodeGen *g, IrExecutable *executable, IrInstructionMulAdd *instruction) {
static LLVMValueRef ir_render_mul_add(CodeGen *g, IrExecutableGen *executable, IrInstGenMulAdd *instruction) {
LLVMValueRef op1 = ir_llvm_value(g, instruction->op1);
LLVMValueRef op2 = ir_llvm_value(g, instruction->op2);
LLVMValueRef op3 = ir_llvm_value(g, instruction->op3);
@@ -5865,7 +5877,7 @@ static LLVMValueRef ir_render_mul_add(CodeGen *g, IrExecutable *executable, IrIn
return LLVMBuildCall(g->builder, fn_val, args, 3, "");
}
static LLVMValueRef ir_render_bswap(CodeGen *g, IrExecutable *executable, IrInstructionBswap *instruction) {
static LLVMValueRef ir_render_bswap(CodeGen *g, IrExecutableGen *executable, IrInstGenBswap *instruction) {
LLVMValueRef op = ir_llvm_value(g, instruction->op);
ZigType *expr_type = instruction->base.value->type;
bool is_vector = expr_type->id == ZigTypeIdVector;
@@ -5899,7 +5911,7 @@ static LLVMValueRef ir_render_bswap(CodeGen *g, IrExecutable *executable, IrInst
return LLVMBuildTrunc(g->builder, shifted, get_llvm_type(g, expr_type), "");
}
static LLVMValueRef ir_render_bit_reverse(CodeGen *g, IrExecutable *executable, IrInstructionBitReverse *instruction) {
static LLVMValueRef ir_render_bit_reverse(CodeGen *g, IrExecutableGen *executable, IrInstGenBitReverse *instruction) {
LLVMValueRef op = ir_llvm_value(g, instruction->op);
ZigType *int_type = instruction->base.value->type;
assert(int_type->id == ZigTypeIdInt);
@@ -5907,8 +5919,8 @@ 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)
static LLVMValueRef ir_render_vector_to_array(CodeGen *g, IrExecutableGen *executable,
IrInstGenVectorToArray *instruction)
{
ZigType *array_type = instruction->base.value->type;
assert(array_type->id == ZigTypeIdArray);
@@ -5941,8 +5953,8 @@ static LLVMValueRef ir_render_vector_to_array(CodeGen *g, IrExecutable *executab
return result_loc;
}
static LLVMValueRef ir_render_array_to_vector(CodeGen *g, IrExecutable *executable,
IrInstructionArrayToVector *instruction)
static LLVMValueRef ir_render_array_to_vector(CodeGen *g, IrExecutableGen *executable,
IrInstGenArrayToVector *instruction)
{
ZigType *vector_type = instruction->base.value->type;
assert(vector_type->id == ZigTypeIdVector);
@@ -5978,8 +5990,8 @@ static LLVMValueRef ir_render_array_to_vector(CodeGen *g, IrExecutable *executab
}
}
static LLVMValueRef ir_render_assert_zero(CodeGen *g, IrExecutable *executable,
IrInstructionAssertZero *instruction)
static LLVMValueRef ir_render_assert_zero(CodeGen *g, IrExecutableGen *executable,
IrInstGenAssertZero *instruction)
{
LLVMValueRef target = ir_llvm_value(g, instruction->target);
ZigType *int_type = instruction->target->value->type;
@@ -5989,8 +6001,8 @@ static LLVMValueRef ir_render_assert_zero(CodeGen *g, IrExecutable *executable,
return nullptr;
}
static LLVMValueRef ir_render_assert_non_null(CodeGen *g, IrExecutable *executable,
IrInstructionAssertNonNull *instruction)
static LLVMValueRef ir_render_assert_non_null(CodeGen *g, IrExecutableGen *executable,
IrInstGenAssertNonNull *instruction)
{
LLVMValueRef target = ir_llvm_value(g, instruction->target);
ZigType *target_type = instruction->target->value->type;
@@ -6014,8 +6026,8 @@ static LLVMValueRef ir_render_assert_non_null(CodeGen *g, IrExecutable *executab
return nullptr;
}
static LLVMValueRef ir_render_suspend_begin(CodeGen *g, IrExecutable *executable,
IrInstructionSuspendBegin *instruction)
static LLVMValueRef ir_render_suspend_begin(CodeGen *g, IrExecutableGen *executable,
IrInstGenSuspendBegin *instruction)
{
if (fn_is_async(g->cur_fn)) {
instruction->resume_bb = gen_suspend_begin(g, "SuspendResume");
@@ -6023,8 +6035,8 @@ static LLVMValueRef ir_render_suspend_begin(CodeGen *g, IrExecutable *executable
return nullptr;
}
static LLVMValueRef ir_render_suspend_finish(CodeGen *g, IrExecutable *executable,
IrInstructionSuspendFinish *instruction)
static LLVMValueRef ir_render_suspend_finish(CodeGen *g, IrExecutableGen *executable,
IrInstGenSuspendFinish *instruction)
{
LLVMBuildRetVoid(g->builder);
@@ -6032,11 +6044,11 @@ static LLVMValueRef ir_render_suspend_finish(CodeGen *g, IrExecutable *executabl
if (ir_want_runtime_safety(g, &instruction->base)) {
LLVMBuildStore(g->builder, g->cur_bad_not_suspended_index, g->cur_async_resume_index_ptr);
}
render_async_var_decls(g, instruction->base.scope);
render_async_var_decls(g, instruction->base.base.scope);
return nullptr;
}
static LLVMValueRef gen_await_early_return(CodeGen *g, IrInstruction *source_instr,
static LLVMValueRef gen_await_early_return(CodeGen *g, IrInstGen *source_instr,
LLVMValueRef target_frame_ptr, ZigType *result_type, ZigType *ptr_result_type,
LLVMValueRef result_loc, bool non_async)
{
@@ -6062,7 +6074,7 @@ static LLVMValueRef gen_await_early_return(CodeGen *g, IrInstruction *source_ins
frame_index_trace_arg(g, result_type), "");
LLVMValueRef src_trace_ptr = LLVMBuildLoad(g->builder, their_trace_ptr_ptr, "");
bool is_llvm_alloca;
LLVMValueRef dest_trace_ptr = get_cur_err_ret_trace_val(g, source_instr->scope, &is_llvm_alloca);
LLVMValueRef dest_trace_ptr = get_cur_err_ret_trace_val(g, source_instr->base.scope, &is_llvm_alloca);
LLVMValueRef args[] = { dest_trace_ptr, src_trace_ptr };
ZigLLVMBuildCall(g->builder, get_merge_err_ret_traces_fn_val(g), args, 2,
get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAuto, "");
@@ -6075,7 +6087,7 @@ static LLVMValueRef gen_await_early_return(CodeGen *g, IrInstruction *source_ins
}
}
static LLVMValueRef ir_render_await(CodeGen *g, IrExecutable *executable, IrInstructionAwaitGen *instruction) {
static LLVMValueRef ir_render_await(CodeGen *g, IrExecutableGen *executable, IrInstGenAwait *instruction) {
LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
LLVMValueRef zero = LLVMConstNull(usize_type_ref);
LLVMValueRef target_frame_ptr = ir_llvm_value(g, instruction->frame);
@@ -6112,7 +6124,7 @@ static LLVMValueRef ir_render_await(CodeGen *g, IrExecutable *executable, IrInst
// supply the error return trace pointer
if (codegen_fn_has_err_ret_tracing_arg(g, result_type)) {
bool is_llvm_alloca;
LLVMValueRef my_err_ret_trace_val = get_cur_err_ret_trace_val(g, instruction->base.scope, &is_llvm_alloca);
LLVMValueRef my_err_ret_trace_val = get_cur_err_ret_trace_val(g, instruction->base.base.scope, &is_llvm_alloca);
assert(my_err_ret_trace_val != nullptr);
LLVMValueRef err_ret_trace_ptr_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr,
frame_index_trace_arg(g, result_type) + 1, "");
@@ -6160,7 +6172,7 @@ static LLVMValueRef ir_render_await(CodeGen *g, IrExecutable *executable, IrInst
return nullptr;
}
static LLVMValueRef ir_render_resume(CodeGen *g, IrExecutable *executable, IrInstructionResume *instruction) {
static LLVMValueRef ir_render_resume(CodeGen *g, IrExecutableGen *executable, IrInstGenResume *instruction) {
LLVMValueRef frame = ir_llvm_value(g, instruction->frame);
ZigType *frame_type = instruction->frame->value->type;
assert(frame_type->id == ZigTypeIdAnyFrame);
@@ -6169,15 +6181,15 @@ static LLVMValueRef ir_render_resume(CodeGen *g, IrExecutable *executable, IrIns
return nullptr;
}
static LLVMValueRef ir_render_frame_size(CodeGen *g, IrExecutable *executable,
IrInstructionFrameSizeGen *instruction)
static LLVMValueRef ir_render_frame_size(CodeGen *g, IrExecutableGen *executable,
IrInstGenFrameSize *instruction)
{
LLVMValueRef fn_val = ir_llvm_value(g, instruction->fn);
return gen_frame_size(g, fn_val);
}
static LLVMValueRef ir_render_spill_begin(CodeGen *g, IrExecutable *executable,
IrInstructionSpillBegin *instruction)
static LLVMValueRef ir_render_spill_begin(CodeGen *g, IrExecutableGen *executable,
IrInstGenSpillBegin *instruction)
{
if (!fn_is_async(g->cur_fn))
return nullptr;
@@ -6196,7 +6208,7 @@ static LLVMValueRef ir_render_spill_begin(CodeGen *g, IrExecutable *executable,
zig_unreachable();
}
static LLVMValueRef ir_render_spill_end(CodeGen *g, IrExecutable *executable, IrInstructionSpillEnd *instruction) {
static LLVMValueRef ir_render_spill_end(CodeGen *g, IrExecutableGen *executable, IrInstGenSpillEnd *instruction) {
if (!fn_is_async(g->cur_fn))
return ir_llvm_value(g, instruction->begin->operand);
@@ -6212,17 +6224,17 @@ static LLVMValueRef ir_render_spill_end(CodeGen *g, IrExecutable *executable, Ir
zig_unreachable();
}
static LLVMValueRef ir_render_vector_extract_elem(CodeGen *g, IrExecutable *executable,
IrInstructionVectorExtractElem *instruction)
static LLVMValueRef ir_render_vector_extract_elem(CodeGen *g, IrExecutableGen *executable,
IrInstGenVectorExtractElem *instruction)
{
LLVMValueRef vector = ir_llvm_value(g, instruction->vector);
LLVMValueRef index = ir_llvm_value(g, instruction->index);
return LLVMBuildExtractElement(g->builder, vector, index, "");
}
static void set_debug_location(CodeGen *g, IrInstruction *instruction) {
AstNode *source_node = instruction->source_node;
Scope *scope = instruction->scope;
static void set_debug_location(CodeGen *g, IrInstGen *instruction) {
AstNode *source_node = instruction->base.source_node;
Scope *scope = instruction->base.scope;
assert(source_node);
assert(scope);
@@ -6231,263 +6243,183 @@ static void set_debug_location(CodeGen *g, IrInstruction *instruction) {
(int)source_node->column + 1, get_di_scope(g, scope));
}
static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, IrInstruction *instruction) {
static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutableGen *executable, IrInstGen *instruction) {
switch (instruction->id) {
case IrInstructionIdInvalid:
case IrInstructionIdConst:
case IrInstructionIdTypeOf:
case IrInstructionIdFieldPtr:
case IrInstructionIdSetCold:
case IrInstructionIdSetRuntimeSafety:
case IrInstructionIdSetFloatMode:
case IrInstructionIdArrayType:
case IrInstructionIdAnyFrameType:
case IrInstructionIdSliceType:
case IrInstructionIdSizeOf:
case IrInstructionIdSwitchTarget:
case IrInstructionIdContainerInitFields:
case IrInstructionIdCompileErr:
case IrInstructionIdCompileLog:
case IrInstructionIdImport:
case IrInstructionIdCImport:
case IrInstructionIdCInclude:
case IrInstructionIdCDefine:
case IrInstructionIdCUndef:
case IrInstructionIdEmbedFile:
case IrInstructionIdIntType:
case IrInstructionIdVectorType:
case IrInstructionIdMemberCount:
case IrInstructionIdMemberType:
case IrInstructionIdMemberName:
case IrInstructionIdAlignOf:
case IrInstructionIdFnProto:
case IrInstructionIdTestComptime:
case IrInstructionIdCheckSwitchProngs:
case IrInstructionIdCheckStatementIsVoid:
case IrInstructionIdTypeName:
case IrInstructionIdDeclRef:
case IrInstructionIdSwitchVar:
case IrInstructionIdSwitchElseVar:
case IrInstructionIdByteOffsetOf:
case IrInstructionIdBitOffsetOf:
case IrInstructionIdTypeInfo:
case IrInstructionIdType:
case IrInstructionIdHasField:
case IrInstructionIdTypeId:
case IrInstructionIdSetEvalBranchQuota:
case IrInstructionIdPtrType:
case IrInstructionIdOpaqueType:
case IrInstructionIdSetAlignStack:
case IrInstructionIdArgType:
case IrInstructionIdTagType:
case IrInstructionIdExport:
case IrInstructionIdErrorUnion:
case IrInstructionIdAddImplicitReturnType:
case IrInstructionIdIntCast:
case IrInstructionIdFloatCast:
case IrInstructionIdIntToFloat:
case IrInstructionIdFloatToInt:
case IrInstructionIdBoolToInt:
case IrInstructionIdErrSetCast:
case IrInstructionIdFromBytes:
case IrInstructionIdToBytes:
case IrInstructionIdEnumToInt:
case IrInstructionIdCheckRuntimeScope:
case IrInstructionIdDeclVarSrc:
case IrInstructionIdPtrCastSrc:
case IrInstructionIdCmpxchgSrc:
case IrInstructionIdLoadPtr:
case IrInstructionIdHasDecl:
case IrInstructionIdUndeclaredIdent:
case IrInstructionIdCallExtra:
case IrInstructionIdCallSrc:
case IrInstructionIdCallSrcArgs:
case IrInstructionIdAllocaSrc:
case IrInstructionIdEndExpr:
case IrInstructionIdImplicitCast:
case IrInstructionIdResolveResult:
case IrInstructionIdResetResult:
case IrInstructionIdContainerInitList:
case IrInstructionIdSliceSrc:
case IrInstructionIdRef:
case IrInstructionIdBitCastSrc:
case IrInstructionIdTestErrSrc:
case IrInstructionIdUnionInitNamedField:
case IrInstructionIdFrameType:
case IrInstructionIdFrameSizeSrc:
case IrInstructionIdAllocaGen:
case IrInstructionIdAwaitSrc:
case IrInstructionIdSplatSrc:
case IrInstructionIdMergeErrSets:
case IrInstructionIdAsmSrc:
case IrInstGenIdInvalid:
case IrInstGenIdConst:
case IrInstGenIdAlloca:
zig_unreachable();
case IrInstructionIdDeclVarGen:
return ir_render_decl_var(g, executable, (IrInstructionDeclVarGen *)instruction);
case IrInstructionIdReturn:
return ir_render_return(g, executable, (IrInstructionReturn *)instruction);
case IrInstructionIdBinOp:
return ir_render_bin_op(g, executable, (IrInstructionBinOp *)instruction);
case IrInstructionIdCast:
return ir_render_cast(g, executable, (IrInstructionCast *)instruction);
case IrInstructionIdUnreachable:
return ir_render_unreachable(g, executable, (IrInstructionUnreachable *)instruction);
case IrInstructionIdCondBr:
return ir_render_cond_br(g, executable, (IrInstructionCondBr *)instruction);
case IrInstructionIdBr:
return ir_render_br(g, executable, (IrInstructionBr *)instruction);
case IrInstructionIdUnOp:
return ir_render_un_op(g, executable, (IrInstructionUnOp *)instruction);
case IrInstructionIdLoadPtrGen:
return ir_render_load_ptr(g, executable, (IrInstructionLoadPtrGen *)instruction);
case IrInstructionIdStorePtr:
return ir_render_store_ptr(g, executable, (IrInstructionStorePtr *)instruction);
case IrInstructionIdVectorStoreElem:
return ir_render_vector_store_elem(g, executable, (IrInstructionVectorStoreElem *)instruction);
case IrInstructionIdVarPtr:
return ir_render_var_ptr(g, executable, (IrInstructionVarPtr *)instruction);
case IrInstructionIdReturnPtr:
return ir_render_return_ptr(g, executable, (IrInstructionReturnPtr *)instruction);
case IrInstructionIdElemPtr:
return ir_render_elem_ptr(g, executable, (IrInstructionElemPtr *)instruction);
case IrInstructionIdCallGen:
return ir_render_call(g, executable, (IrInstructionCallGen *)instruction);
case IrInstructionIdStructFieldPtr:
return ir_render_struct_field_ptr(g, executable, (IrInstructionStructFieldPtr *)instruction);
case IrInstructionIdUnionFieldPtr:
return ir_render_union_field_ptr(g, executable, (IrInstructionUnionFieldPtr *)instruction);
case IrInstructionIdAsmGen:
return ir_render_asm_gen(g, executable, (IrInstructionAsmGen *)instruction);
case IrInstructionIdTestNonNull:
return ir_render_test_non_null(g, executable, (IrInstructionTestNonNull *)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:
return ir_render_ctz(g, executable, (IrInstructionCtz *)instruction);
case IrInstructionIdPopCount:
return ir_render_pop_count(g, executable, (IrInstructionPopCount *)instruction);
case IrInstructionIdSwitchBr:
return ir_render_switch_br(g, executable, (IrInstructionSwitchBr *)instruction);
case IrInstructionIdBswap:
return ir_render_bswap(g, executable, (IrInstructionBswap *)instruction);
case IrInstructionIdBitReverse:
return ir_render_bit_reverse(g, executable, (IrInstructionBitReverse *)instruction);
case IrInstructionIdPhi:
return ir_render_phi(g, executable, (IrInstructionPhi *)instruction);
case IrInstructionIdRefGen:
return ir_render_ref(g, executable, (IrInstructionRefGen *)instruction);
case IrInstructionIdErrName:
return ir_render_err_name(g, executable, (IrInstructionErrName *)instruction);
case IrInstructionIdCmpxchgGen:
return ir_render_cmpxchg(g, executable, (IrInstructionCmpxchgGen *)instruction);
case IrInstructionIdFence:
return ir_render_fence(g, executable, (IrInstructionFence *)instruction);
case IrInstructionIdTruncate:
return ir_render_truncate(g, executable, (IrInstructionTruncate *)instruction);
case IrInstructionIdBoolNot:
return ir_render_bool_not(g, executable, (IrInstructionBoolNot *)instruction);
case IrInstructionIdMemset:
return ir_render_memset(g, executable, (IrInstructionMemset *)instruction);
case IrInstructionIdMemcpy:
return ir_render_memcpy(g, executable, (IrInstructionMemcpy *)instruction);
case IrInstructionIdSliceGen:
return ir_render_slice(g, executable, (IrInstructionSliceGen *)instruction);
case IrInstructionIdBreakpoint:
return ir_render_breakpoint(g, executable, (IrInstructionBreakpoint *)instruction);
case IrInstructionIdReturnAddress:
return ir_render_return_address(g, executable, (IrInstructionReturnAddress *)instruction);
case IrInstructionIdFrameAddress:
return ir_render_frame_address(g, executable, (IrInstructionFrameAddress *)instruction);
case IrInstructionIdFrameHandle:
return ir_render_handle(g, executable, (IrInstructionFrameHandle *)instruction);
case IrInstructionIdOverflowOp:
return ir_render_overflow_op(g, executable, (IrInstructionOverflowOp *)instruction);
case IrInstructionIdTestErrGen:
return ir_render_test_err(g, executable, (IrInstructionTestErrGen *)instruction);
case IrInstructionIdUnwrapErrCode:
return ir_render_unwrap_err_code(g, executable, (IrInstructionUnwrapErrCode *)instruction);
case IrInstructionIdUnwrapErrPayload:
return ir_render_unwrap_err_payload(g, executable, (IrInstructionUnwrapErrPayload *)instruction);
case IrInstructionIdOptionalWrap:
return ir_render_optional_wrap(g, executable, (IrInstructionOptionalWrap *)instruction);
case IrInstructionIdErrWrapCode:
return ir_render_err_wrap_code(g, executable, (IrInstructionErrWrapCode *)instruction);
case IrInstructionIdErrWrapPayload:
return ir_render_err_wrap_payload(g, executable, (IrInstructionErrWrapPayload *)instruction);
case IrInstructionIdUnionTag:
return ir_render_union_tag(g, executable, (IrInstructionUnionTag *)instruction);
case IrInstructionIdPtrCastGen:
return ir_render_ptr_cast(g, executable, (IrInstructionPtrCastGen *)instruction);
case IrInstructionIdBitCastGen:
return ir_render_bit_cast(g, executable, (IrInstructionBitCastGen *)instruction);
case IrInstructionIdWidenOrShorten:
return ir_render_widen_or_shorten(g, executable, (IrInstructionWidenOrShorten *)instruction);
case IrInstructionIdPtrToInt:
return ir_render_ptr_to_int(g, executable, (IrInstructionPtrToInt *)instruction);
case IrInstructionIdIntToPtr:
return ir_render_int_to_ptr(g, executable, (IrInstructionIntToPtr *)instruction);
case IrInstructionIdIntToEnum:
return ir_render_int_to_enum(g, executable, (IrInstructionIntToEnum *)instruction);
case IrInstructionIdIntToErr:
return ir_render_int_to_err(g, executable, (IrInstructionIntToErr *)instruction);
case IrInstructionIdErrToInt:
return ir_render_err_to_int(g, executable, (IrInstructionErrToInt *)instruction);
case IrInstructionIdPanic:
return ir_render_panic(g, executable, (IrInstructionPanic *)instruction);
case IrInstructionIdTagName:
return ir_render_enum_tag_name(g, executable, (IrInstructionTagName *)instruction);
case IrInstructionIdFieldParentPtr:
return ir_render_field_parent_ptr(g, executable, (IrInstructionFieldParentPtr *)instruction);
case IrInstructionIdAlignCast:
return ir_render_align_cast(g, executable, (IrInstructionAlignCast *)instruction);
case IrInstructionIdErrorReturnTrace:
return ir_render_error_return_trace(g, executable, (IrInstructionErrorReturnTrace *)instruction);
case IrInstructionIdAtomicRmw:
return ir_render_atomic_rmw(g, executable, (IrInstructionAtomicRmw *)instruction);
case IrInstructionIdAtomicLoad:
return ir_render_atomic_load(g, executable, (IrInstructionAtomicLoad *)instruction);
case IrInstructionIdAtomicStore:
return ir_render_atomic_store(g, executable, (IrInstructionAtomicStore *)instruction);
case IrInstructionIdSaveErrRetAddr:
return ir_render_save_err_ret_addr(g, executable, (IrInstructionSaveErrRetAddr *)instruction);
case IrInstructionIdFloatOp:
return ir_render_float_op(g, executable, (IrInstructionFloatOp *)instruction);
case IrInstructionIdMulAdd:
return ir_render_mul_add(g, executable, (IrInstructionMulAdd *)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);
case IrInstructionIdAssertZero:
return ir_render_assert_zero(g, executable, (IrInstructionAssertZero *)instruction);
case IrInstructionIdAssertNonNull:
return ir_render_assert_non_null(g, executable, (IrInstructionAssertNonNull *)instruction);
case IrInstructionIdResizeSlice:
return ir_render_resize_slice(g, executable, (IrInstructionResizeSlice *)instruction);
case IrInstructionIdPtrOfArrayToSlice:
return ir_render_ptr_of_array_to_slice(g, executable, (IrInstructionPtrOfArrayToSlice *)instruction);
case IrInstructionIdSuspendBegin:
return ir_render_suspend_begin(g, executable, (IrInstructionSuspendBegin *)instruction);
case IrInstructionIdSuspendFinish:
return ir_render_suspend_finish(g, executable, (IrInstructionSuspendFinish *)instruction);
case IrInstructionIdResume:
return ir_render_resume(g, executable, (IrInstructionResume *)instruction);
case IrInstructionIdFrameSizeGen:
return ir_render_frame_size(g, executable, (IrInstructionFrameSizeGen *)instruction);
case IrInstructionIdAwaitGen:
return ir_render_await(g, executable, (IrInstructionAwaitGen *)instruction);
case IrInstructionIdSpillBegin:
return ir_render_spill_begin(g, executable, (IrInstructionSpillBegin *)instruction);
case IrInstructionIdSpillEnd:
return ir_render_spill_end(g, executable, (IrInstructionSpillEnd *)instruction);
case IrInstructionIdShuffleVector:
return ir_render_shuffle_vector(g, executable, (IrInstructionShuffleVector *) instruction);
case IrInstructionIdSplatGen:
return ir_render_splat(g, executable, (IrInstructionSplatGen *) instruction);
case IrInstructionIdVectorExtractElem:
return ir_render_vector_extract_elem(g, executable, (IrInstructionVectorExtractElem *) instruction);
case IrInstGenIdDeclVar:
return ir_render_decl_var(g, executable, (IrInstGenDeclVar *)instruction);
case IrInstGenIdReturn:
return ir_render_return(g, executable, (IrInstGenReturn *)instruction);
case IrInstGenIdBinOp:
return ir_render_bin_op(g, executable, (IrInstGenBinOp *)instruction);
case IrInstGenIdCast:
return ir_render_cast(g, executable, (IrInstGenCast *)instruction);
case IrInstGenIdUnreachable:
return ir_render_unreachable(g, executable, (IrInstGenUnreachable *)instruction);
case IrInstGenIdCondBr:
return ir_render_cond_br(g, executable, (IrInstGenCondBr *)instruction);
case IrInstGenIdBr:
return ir_render_br(g, executable, (IrInstGenBr *)instruction);
case IrInstGenIdBinaryNot:
return ir_render_binary_not(g, executable, (IrInstGenBinaryNot *)instruction);
case IrInstGenIdNegation:
return ir_render_negation(g, executable, (IrInstGenNegation *)instruction);
case IrInstGenIdNegationWrapping:
return ir_render_negation_wrapping(g, executable, (IrInstGenNegationWrapping *)instruction);
case IrInstGenIdLoadPtr:
return ir_render_load_ptr(g, executable, (IrInstGenLoadPtr *)instruction);
case IrInstGenIdStorePtr:
return ir_render_store_ptr(g, executable, (IrInstGenStorePtr *)instruction);
case IrInstGenIdVectorStoreElem:
return ir_render_vector_store_elem(g, executable, (IrInstGenVectorStoreElem *)instruction);
case IrInstGenIdVarPtr:
return ir_render_var_ptr(g, executable, (IrInstGenVarPtr *)instruction);
case IrInstGenIdReturnPtr:
return ir_render_return_ptr(g, executable, (IrInstGenReturnPtr *)instruction);
case IrInstGenIdElemPtr:
return ir_render_elem_ptr(g, executable, (IrInstGenElemPtr *)instruction);
case IrInstGenIdCall:
return ir_render_call(g, executable, (IrInstGenCall *)instruction);
case IrInstGenIdStructFieldPtr:
return ir_render_struct_field_ptr(g, executable, (IrInstGenStructFieldPtr *)instruction);
case IrInstGenIdUnionFieldPtr:
return ir_render_union_field_ptr(g, executable, (IrInstGenUnionFieldPtr *)instruction);
case IrInstGenIdAsm:
return ir_render_asm_gen(g, executable, (IrInstGenAsm *)instruction);
case IrInstGenIdTestNonNull:
return ir_render_test_non_null(g, executable, (IrInstGenTestNonNull *)instruction);
case IrInstGenIdOptionalUnwrapPtr:
return ir_render_optional_unwrap_ptr(g, executable, (IrInstGenOptionalUnwrapPtr *)instruction);
case IrInstGenIdClz:
return ir_render_clz(g, executable, (IrInstGenClz *)instruction);
case IrInstGenIdCtz:
return ir_render_ctz(g, executable, (IrInstGenCtz *)instruction);
case IrInstGenIdPopCount:
return ir_render_pop_count(g, executable, (IrInstGenPopCount *)instruction);
case IrInstGenIdSwitchBr:
return ir_render_switch_br(g, executable, (IrInstGenSwitchBr *)instruction);
case IrInstGenIdBswap:
return ir_render_bswap(g, executable, (IrInstGenBswap *)instruction);
case IrInstGenIdBitReverse:
return ir_render_bit_reverse(g, executable, (IrInstGenBitReverse *)instruction);
case IrInstGenIdPhi:
return ir_render_phi(g, executable, (IrInstGenPhi *)instruction);
case IrInstGenIdRef:
return ir_render_ref(g, executable, (IrInstGenRef *)instruction);
case IrInstGenIdErrName:
return ir_render_err_name(g, executable, (IrInstGenErrName *)instruction);
case IrInstGenIdCmpxchg:
return ir_render_cmpxchg(g, executable, (IrInstGenCmpxchg *)instruction);
case IrInstGenIdFence:
return ir_render_fence(g, executable, (IrInstGenFence *)instruction);
case IrInstGenIdTruncate:
return ir_render_truncate(g, executable, (IrInstGenTruncate *)instruction);
case IrInstGenIdBoolNot:
return ir_render_bool_not(g, executable, (IrInstGenBoolNot *)instruction);
case IrInstGenIdMemset:
return ir_render_memset(g, executable, (IrInstGenMemset *)instruction);
case IrInstGenIdMemcpy:
return ir_render_memcpy(g, executable, (IrInstGenMemcpy *)instruction);
case IrInstGenIdSlice:
return ir_render_slice(g, executable, (IrInstGenSlice *)instruction);
case IrInstGenIdBreakpoint:
return ir_render_breakpoint(g, executable, (IrInstGenBreakpoint *)instruction);
case IrInstGenIdReturnAddress:
return ir_render_return_address(g, executable, (IrInstGenReturnAddress *)instruction);
case IrInstGenIdFrameAddress:
return ir_render_frame_address(g, executable, (IrInstGenFrameAddress *)instruction);
case IrInstGenIdFrameHandle:
return ir_render_handle(g, executable, (IrInstGenFrameHandle *)instruction);
case IrInstGenIdOverflowOp:
return ir_render_overflow_op(g, executable, (IrInstGenOverflowOp *)instruction);
case IrInstGenIdTestErr:
return ir_render_test_err(g, executable, (IrInstGenTestErr *)instruction);
case IrInstGenIdUnwrapErrCode:
return ir_render_unwrap_err_code(g, executable, (IrInstGenUnwrapErrCode *)instruction);
case IrInstGenIdUnwrapErrPayload:
return ir_render_unwrap_err_payload(g, executable, (IrInstGenUnwrapErrPayload *)instruction);
case IrInstGenIdOptionalWrap:
return ir_render_optional_wrap(g, executable, (IrInstGenOptionalWrap *)instruction);
case IrInstGenIdErrWrapCode:
return ir_render_err_wrap_code(g, executable, (IrInstGenErrWrapCode *)instruction);
case IrInstGenIdErrWrapPayload:
return ir_render_err_wrap_payload(g, executable, (IrInstGenErrWrapPayload *)instruction);
case IrInstGenIdUnionTag:
return ir_render_union_tag(g, executable, (IrInstGenUnionTag *)instruction);
case IrInstGenIdPtrCast:
return ir_render_ptr_cast(g, executable, (IrInstGenPtrCast *)instruction);
case IrInstGenIdBitCast:
return ir_render_bit_cast(g, executable, (IrInstGenBitCast *)instruction);
case IrInstGenIdWidenOrShorten:
return ir_render_widen_or_shorten(g, executable, (IrInstGenWidenOrShorten *)instruction);
case IrInstGenIdPtrToInt:
return ir_render_ptr_to_int(g, executable, (IrInstGenPtrToInt *)instruction);
case IrInstGenIdIntToPtr:
return ir_render_int_to_ptr(g, executable, (IrInstGenIntToPtr *)instruction);
case IrInstGenIdIntToEnum:
return ir_render_int_to_enum(g, executable, (IrInstGenIntToEnum *)instruction);
case IrInstGenIdIntToErr:
return ir_render_int_to_err(g, executable, (IrInstGenIntToErr *)instruction);
case IrInstGenIdErrToInt:
return ir_render_err_to_int(g, executable, (IrInstGenErrToInt *)instruction);
case IrInstGenIdPanic:
return ir_render_panic(g, executable, (IrInstGenPanic *)instruction);
case IrInstGenIdTagName:
return ir_render_enum_tag_name(g, executable, (IrInstGenTagName *)instruction);
case IrInstGenIdFieldParentPtr:
return ir_render_field_parent_ptr(g, executable, (IrInstGenFieldParentPtr *)instruction);
case IrInstGenIdAlignCast:
return ir_render_align_cast(g, executable, (IrInstGenAlignCast *)instruction);
case IrInstGenIdErrorReturnTrace:
return ir_render_error_return_trace(g, executable, (IrInstGenErrorReturnTrace *)instruction);
case IrInstGenIdAtomicRmw:
return ir_render_atomic_rmw(g, executable, (IrInstGenAtomicRmw *)instruction);
case IrInstGenIdAtomicLoad:
return ir_render_atomic_load(g, executable, (IrInstGenAtomicLoad *)instruction);
case IrInstGenIdAtomicStore:
return ir_render_atomic_store(g, executable, (IrInstGenAtomicStore *)instruction);
case IrInstGenIdSaveErrRetAddr:
return ir_render_save_err_ret_addr(g, executable, (IrInstGenSaveErrRetAddr *)instruction);
case IrInstGenIdFloatOp:
return ir_render_float_op(g, executable, (IrInstGenFloatOp *)instruction);
case IrInstGenIdMulAdd:
return ir_render_mul_add(g, executable, (IrInstGenMulAdd *)instruction);
case IrInstGenIdArrayToVector:
return ir_render_array_to_vector(g, executable, (IrInstGenArrayToVector *)instruction);
case IrInstGenIdVectorToArray:
return ir_render_vector_to_array(g, executable, (IrInstGenVectorToArray *)instruction);
case IrInstGenIdAssertZero:
return ir_render_assert_zero(g, executable, (IrInstGenAssertZero *)instruction);
case IrInstGenIdAssertNonNull:
return ir_render_assert_non_null(g, executable, (IrInstGenAssertNonNull *)instruction);
case IrInstGenIdResizeSlice:
return ir_render_resize_slice(g, executable, (IrInstGenResizeSlice *)instruction);
case IrInstGenIdPtrOfArrayToSlice:
return ir_render_ptr_of_array_to_slice(g, executable, (IrInstGenPtrOfArrayToSlice *)instruction);
case IrInstGenIdSuspendBegin:
return ir_render_suspend_begin(g, executable, (IrInstGenSuspendBegin *)instruction);
case IrInstGenIdSuspendFinish:
return ir_render_suspend_finish(g, executable, (IrInstGenSuspendFinish *)instruction);
case IrInstGenIdResume:
return ir_render_resume(g, executable, (IrInstGenResume *)instruction);
case IrInstGenIdFrameSize:
return ir_render_frame_size(g, executable, (IrInstGenFrameSize *)instruction);
case IrInstGenIdAwait:
return ir_render_await(g, executable, (IrInstGenAwait *)instruction);
case IrInstGenIdSpillBegin:
return ir_render_spill_begin(g, executable, (IrInstGenSpillBegin *)instruction);
case IrInstGenIdSpillEnd:
return ir_render_spill_end(g, executable, (IrInstGenSpillEnd *)instruction);
case IrInstGenIdShuffleVector:
return ir_render_shuffle_vector(g, executable, (IrInstGenShuffleVector *) instruction);
case IrInstGenIdSplat:
return ir_render_splat(g, executable, (IrInstGenSplat *) instruction);
case IrInstGenIdVectorExtractElem:
return ir_render_vector_extract_elem(g, executable, (IrInstGenVectorExtractElem *) instruction);
}
zig_unreachable();
}
@@ -6495,21 +6427,21 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
static void ir_render(CodeGen *g, ZigFn *fn_entry) {
assert(fn_entry);
IrExecutable *executable = &fn_entry->analyzed_executable;
IrExecutableGen *executable = &fn_entry->analyzed_executable;
assert(executable->basic_block_list.length > 0);
for (size_t block_i = 0; block_i < executable->basic_block_list.length; block_i += 1) {
IrBasicBlock *current_block = executable->basic_block_list.at(block_i);
IrBasicBlockGen *current_block = executable->basic_block_list.at(block_i);
if (get_scope_typeof(current_block->scope) != nullptr) {
LLVMBuildBr(g->builder, current_block->llvm_block);
}
assert(current_block->llvm_block);
LLVMPositionBuilderAtEnd(g->builder, current_block->llvm_block);
for (size_t instr_i = 0; instr_i < current_block->instruction_list.length; instr_i += 1) {
IrInstruction *instruction = current_block->instruction_list.at(instr_i);
if (instruction->ref_count == 0 && !ir_has_side_effects(instruction))
IrInstGen *instruction = current_block->instruction_list.at(instr_i);
if (instruction->base.ref_count == 0 && !ir_inst_gen_has_side_effects(instruction))
continue;
if (get_scope_typeof(instruction->scope) != nullptr)
if (get_scope_typeof(instruction->base.scope) != nullptr)
continue;
if (!g->strip_debug_symbols) {
@@ -7401,7 +7333,7 @@ static void generate_error_name_table(CodeGen *g) {
}
static void build_all_basic_blocks(CodeGen *g, ZigFn *fn) {
IrExecutable *executable = &fn->analyzed_executable;
IrExecutableGen *executable = &fn->analyzed_executable;
assert(executable->basic_block_list.length > 0);
LLVMValueRef fn_val = fn_llvm_value(g, fn);
LLVMBasicBlockRef first_bb = nullptr;
@@ -7410,7 +7342,7 @@ static void build_all_basic_blocks(CodeGen *g, ZigFn *fn) {
g->cur_preamble_llvm_block = first_bb;
}
for (size_t block_i = 0; block_i < executable->basic_block_list.length; block_i += 1) {
IrBasicBlock *bb = executable->basic_block_list.at(block_i);
IrBasicBlockGen *bb = executable->basic_block_list.at(block_i);
bb->llvm_block = LLVMAppendBasicBlock(fn_val, bb->name_hint);
}
if (first_bb == nullptr) {
@@ -7609,7 +7541,7 @@ static void do_code_gen(CodeGen *g) {
} else {
if (want_sret) {
g->cur_ret_ptr = LLVMGetParam(fn, 0);
} else if (handle_is_ptr(fn_type_id->return_type)) {
} else if (type_has_bits(fn_type_id->return_type)) {
g->cur_ret_ptr = build_alloca(g, fn_type_id->return_type, "result", 0);
// TODO add debug info variable for this
} else {
@@ -7643,10 +7575,10 @@ static void do_code_gen(CodeGen *g) {
if (!is_async) {
// allocate async frames for noasync calls & awaits to async functions
ZigType *largest_call_frame_type = nullptr;
IrInstruction *all_calls_alloca = ir_create_alloca(g, &fn_table_entry->fndef_scope->base,
IrInstGen *all_calls_alloca = ir_create_alloca(g, &fn_table_entry->fndef_scope->base,
fn_table_entry->body_node, fn_table_entry, g->builtin_types.entry_void, "@async_call_frame");
for (size_t i = 0; i < fn_table_entry->call_list.length; i += 1) {
IrInstructionCallGen *call = fn_table_entry->call_list.at(i);
IrInstGenCall *call = fn_table_entry->call_list.at(i);
if (call->fn_entry == nullptr)
continue;
if (!fn_is_async(call->fn_entry))
@@ -7668,7 +7600,7 @@ static void do_code_gen(CodeGen *g) {
}
// allocate temporary stack data
for (size_t alloca_i = 0; alloca_i < fn_table_entry->alloca_gen_list.length; alloca_i += 1) {
IrInstructionAllocaGen *instruction = fn_table_entry->alloca_gen_list.at(alloca_i);
IrInstGenAlloca *instruction = fn_table_entry->alloca_gen_list.at(alloca_i);
ZigType *ptr_type = instruction->base.value->type;
assert(ptr_type->id == ZigTypeIdPointer);
ZigType *child_type = ptr_type->data.pointer.child_type;
@@ -7676,7 +7608,7 @@ static void do_code_gen(CodeGen *g) {
zig_unreachable();
if (!type_has_bits(child_type))
continue;
if (instruction->base.ref_count == 0)
if (instruction->base.base.ref_count == 0)
continue;
if (instruction->base.value->special != ConstValSpecialRuntime) {
if (const_ptr_pointee(nullptr, g, instruction->base.value, nullptr)->special !=
@@ -7793,7 +7725,7 @@ static void do_code_gen(CodeGen *g) {
ZigLLVMSetCurrentDebugLocation(g->builder, (int)source_node->line + 1,
(int)source_node->column + 1, get_di_scope(g, fn_table_entry->child_scope));
}
IrExecutable *executable = &fn_table_entry->analyzed_executable;
IrExecutableGen *executable = &fn_table_entry->analyzed_executable;
LLVMBasicBlockRef bad_resume_block = LLVMAppendBasicBlock(g->cur_fn_val, "BadResume");
LLVMPositionBuilderAtEnd(g->builder, bad_resume_block);
gen_assertion_scope(g, PanicMsgIdBadResume, fn_table_entry->child_scope);
@@ -7820,7 +7752,7 @@ static void do_code_gen(CodeGen *g) {
g->cur_async_switch_instr = switch_instr;
LLVMValueRef zero = LLVMConstNull(usize_type_ref);
IrBasicBlock *entry_block = executable->basic_block_list.at(0);
IrBasicBlockGen *entry_block = executable->basic_block_list.at(0);
LLVMAddCase(switch_instr, zero, entry_block->llvm_block);
g->cur_resume_block_count += 1;
@@ -7852,7 +7784,7 @@ static void do_code_gen(CodeGen *g) {
gen_init_stack_trace(g, trace_field_ptr, addrs_field_ptr);
}
render_async_var_decls(g, entry_block->instruction_list.at(0)->scope);
render_async_var_decls(g, entry_block->instruction_list.at(0)->base.scope);
} else {
// create debug variable declarations for parameters
// rely on the first variables in the variable_list being parameters.
@@ -7941,6 +7873,12 @@ static void zig_llvm_emit_output(CodeGen *g) {
default:
zig_unreachable();
}
LLVMDisposeModule(g->module);
g->module = nullptr;
LLVMDisposeTargetData(g->target_data_ref);
g->target_data_ref = nullptr;
LLVMDisposeTargetMachine(g->target_machine);
g->target_machine = nullptr;
}
struct CIntTypeInfo {
@@ -8427,6 +8365,25 @@ static bool detect_err_ret_tracing(CodeGen *g) {
g->build_mode != BuildModeSmallRelease;
}
static LLVMCodeModel to_llvm_code_model(CodeGen *g) {
switch (g->code_model) {
case CodeModelDefault:
return LLVMCodeModelDefault;
case CodeModelTiny:
return LLVMCodeModelTiny;
case CodeModelSmall:
return LLVMCodeModelSmall;
case CodeModelKernel:
return LLVMCodeModelKernel;
case CodeModelMedium:
return LLVMCodeModelMedium;
case CodeModelLarge:
return LLVMCodeModelLarge;
}
zig_unreachable();
}
Buf *codegen_generate_builtin_source(CodeGen *g) {
g->have_dynamic_link = detect_dynamic_link(g);
g->have_pic = detect_pic(g);
@@ -8578,6 +8535,17 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
buf_appendf(contents, "pub const os = Os.%s;\n", cur_os);
buf_appendf(contents, "pub const arch = %s;\n", cur_arch);
buf_appendf(contents, "pub const abi = Abi.%s;\n", cur_abi);
{
buf_append_str(contents, "pub const cpu_features: CpuFeatures = ");
if (g->zig_target->cpu_features != nullptr) {
const char *ptr;
size_t len;
stage2_cpu_features_get_builtin_str(g->zig_target->cpu_features, &ptr, &len);
buf_append_mem(contents, ptr, len);
} else {
buf_append_str(contents, "arch.getBaselineCpuFeatures();\n");
}
}
if (g->libc_link_lib != nullptr && g->zig_target->glibc_version != nullptr) {
buf_appendf(contents,
"pub const glibc_version: ?Version = Version{.major = %d, .minor = %d, .patch = %d};\n",
@@ -8595,6 +8563,34 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
buf_appendf(contents, "pub const position_independent_code = %s;\n", bool_to_str(g->have_pic));
buf_appendf(contents, "pub const strip_debug_info = %s;\n", bool_to_str(g->strip_debug_symbols));
{
const char *code_model;
switch (g->code_model) {
case CodeModelDefault:
code_model = "default";
break;
case CodeModelTiny:
code_model = "tiny";
break;
case CodeModelSmall:
code_model = "small";
break;
case CodeModelKernel:
code_model = "kernel";
break;
case CodeModelMedium:
code_model = "medium";
break;
case CodeModelLarge:
code_model = "large";
break;
default:
zig_unreachable();
}
buf_appendf(contents, "pub const code_model = CodeModel.%s;\n", code_model);
}
{
TargetSubsystem detected_subsystem = detect_subsystem(g);
if (detected_subsystem != TargetSubsystemAuto) {
@@ -8639,12 +8635,19 @@ static Error define_builtin_compile_vars(CodeGen *g) {
cache_bool(&cache_hash, g->is_dynamic);
cache_bool(&cache_hash, g->is_test_build);
cache_bool(&cache_hash, g->is_single_threaded);
cache_int(&cache_hash, g->code_model);
cache_int(&cache_hash, g->zig_target->is_native);
cache_int(&cache_hash, g->zig_target->arch);
cache_int(&cache_hash, g->zig_target->sub_arch);
cache_int(&cache_hash, g->zig_target->vendor);
cache_int(&cache_hash, g->zig_target->os);
cache_int(&cache_hash, g->zig_target->abi);
if (g->zig_target->cpu_features != nullptr) {
const char *ptr;
size_t len;
stage2_cpu_features_get_cache_hash(g->zig_target->cpu_features, &ptr, &len);
cache_str(&cache_hash, ptr);
}
if (g->zig_target->glibc_version != nullptr) {
cache_int(&cache_hash, g->zig_target->glibc_version->major);
cache_int(&cache_hash, g->zig_target->glibc_version->minor);
@@ -8769,40 +8772,28 @@ static void init(CodeGen *g) {
reloc_mode = LLVMRelocStatic;
}
const char *target_specific_cpu_args;
const char *target_specific_features;
const char *target_specific_cpu_args = "";
const char *target_specific_features = "";
if (g->zig_target->is_native) {
// LLVM creates invalid binaries on Windows sometimes.
// See https://github.com/ziglang/zig/issues/508
// As a workaround we do not use target native features on Windows.
if (g->zig_target->os == OsWindows || g->zig_target->os == OsUefi) {
target_specific_cpu_args = "";
target_specific_features = "";
} else {
target_specific_cpu_args = ZigLLVMGetHostCPUName();
target_specific_features = ZigLLVMGetNativeFeatures();
}
} else if (target_is_riscv(g->zig_target)) {
// TODO https://github.com/ziglang/zig/issues/2883
// Be aware of https://github.com/ziglang/zig/issues/3275
target_specific_cpu_args = "";
target_specific_features = riscv_default_features;
} else if (g->zig_target->arch == ZigLLVM_x86) {
// This is because we're really targeting i686 rather than i386.
// It's pretty much impossible to use many of the language features
// such as fp16 if you stick use the x87 only. This is also what clang
// uses as base cpu.
// TODO https://github.com/ziglang/zig/issues/2883
target_specific_cpu_args = "pentium4";
target_specific_features = (g->zig_target->os == OsFreestanding) ? "-sse": "";
} else {
target_specific_cpu_args = "";
target_specific_features = "";
target_specific_cpu_args = ZigLLVMGetHostCPUName();
target_specific_features = ZigLLVMGetNativeFeatures();
}
// Override CPU and features if defined by user.
if (g->zig_target->cpu_features != nullptr) {
target_specific_cpu_args = stage2_cpu_features_get_llvm_cpu(g->zig_target->cpu_features);
target_specific_features = stage2_cpu_features_get_llvm_features(g->zig_target->cpu_features);
}
if (g->verbose_llvm_cpu_features) {
fprintf(stderr, "name=%s triple=%s\n", buf_ptr(g->root_out_name), buf_ptr(&g->llvm_triple_str));
fprintf(stderr, "name=%s target_specific_cpu_args=%s\n", buf_ptr(g->root_out_name), target_specific_cpu_args);
fprintf(stderr, "name=%s target_specific_features=%s\n", buf_ptr(g->root_out_name), target_specific_features);
}
g->target_machine = ZigLLVMCreateTargetMachine(target_ref, buf_ptr(&g->llvm_triple_str),
target_specific_cpu_args, target_specific_features, opt_level, reloc_mode,
LLVMCodeModelDefault, g->function_sections);
to_llvm_code_model(g), g->function_sections);
g->target_data_ref = LLVMCreateTargetDataLayout(g->target_machine);
@@ -8846,15 +8837,17 @@ static void init(CodeGen *g) {
define_builtin_types(g);
define_intern_values(g);
IrInstruction *sentinel_instructions = allocate<IrInstruction>(2);
g->invalid_instruction = &sentinel_instructions[0];
g->invalid_instruction->value = allocate<ZigValue>(1, "ZigValue");
g->invalid_instruction->value->type = g->builtin_types.entry_invalid;
IrInstGen *sentinel_instructions = allocate<IrInstGen>(2);
g->invalid_inst_gen = &sentinel_instructions[0];
g->invalid_inst_gen->value = allocate<ZigValue>(1, "ZigValue");
g->invalid_inst_gen->value->type = g->builtin_types.entry_invalid;
g->unreach_instruction = &sentinel_instructions[1];
g->unreach_instruction->value = allocate<ZigValue>(1, "ZigValue");
g->unreach_instruction->value->type = g->builtin_types.entry_unreachable;
g->invalid_inst_src = allocate<IrInstSrc>(1);
define_builtin_fns(g);
Error err;
if ((err = define_builtin_compile_vars(g))) {
@@ -8996,7 +8989,10 @@ static void detect_libc(CodeGen *g) {
"See `zig libc --help` for more details.\n", err_str(err));
exit(1);
}
if ((err = os_make_path(g->cache_dir))) {
Buf libc_txt_dir = BUF_INIT;
os_path_dirname(libc_txt, &libc_txt_dir);
buf_deinit(&libc_txt_dir);
if ((err = os_make_path(&libc_txt_dir))) {
fprintf(stderr, "Unable to create %s directory: %s\n",
buf_ptr(g->cache_dir), err_str(err));
exit(1);
@@ -9125,21 +9121,22 @@ void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_pa
args.append("-target");
args.append(buf_ptr(&g->llvm_triple_str));
if (target_is_musl(g->zig_target) && target_is_riscv(g->zig_target)) {
// Musl depends on atomic instructions, which are disabled by default in Clang/LLVM's
// cross compilation CPU info for RISCV.
// TODO: https://github.com/ziglang/zig/issues/2883
const char *llvm_cpu = stage2_cpu_features_get_llvm_cpu(g->zig_target->cpu_features);
if (llvm_cpu != nullptr) {
args.append("-Xclang");
args.append("-target-cpu");
args.append("-Xclang");
args.append(llvm_cpu);
}
const char *llvm_target_features = stage2_cpu_features_get_llvm_features(g->zig_target->cpu_features);
if (llvm_target_features != nullptr) {
args.append("-Xclang");
args.append("-target-feature");
args.append("-Xclang");
args.append(riscv_default_features);
} else if (g->zig_target->os == OsFreestanding && g->zig_target->arch == ZigLLVM_x86) {
args.append("-Xclang");
args.append("-target-feature");
args.append("-Xclang");
args.append("-sse");
args.append(llvm_target_features);
}
}
if (g->zig_target->os == OsFreestanding) {
args.append("-ffreestanding");
}
@@ -9578,6 +9575,8 @@ Error create_c_object_cache(CodeGen *g, CacheHash **out_cache_hash, bool verbose
cache_bool(cache_hash, g->have_sanitize_c);
cache_bool(cache_hash, want_valgrind_support(g));
cache_bool(cache_hash, g->function_sections);
cache_int(cache_hash, g->code_model);
for (size_t arg_i = 0; arg_i < g->clang_argv_len; arg_i += 1) {
cache_str(cache_hash, g->clang_argv[arg_i]);
}
@@ -9787,6 +9786,7 @@ static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, ZigType *type_e
zig_unreachable();
case ZigTypeIdVoid:
case ZigTypeIdUnreachable:
return;
case ZigTypeIdBool:
g->c_want_stdbool = true;
return;
@@ -10333,6 +10333,12 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
cache_int(ch, g->zig_target->vendor);
cache_int(ch, g->zig_target->os);
cache_int(ch, g->zig_target->abi);
if (g->zig_target->cpu_features != nullptr) {
const char *ptr;
size_t len;
stage2_cpu_features_get_cache_hash(g->zig_target->cpu_features, &ptr, &len);
cache_str(ch, ptr);
}
if (g->zig_target->glibc_version != nullptr) {
cache_int(ch, g->zig_target->glibc_version->major);
cache_int(ch, g->zig_target->glibc_version->minor);
@@ -10673,6 +10679,7 @@ CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType o
child_gen->verbose_llvm_ir = parent_gen->verbose_llvm_ir;
child_gen->verbose_cimport = parent_gen->verbose_cimport;
child_gen->verbose_cc = parent_gen->verbose_cc;
child_gen->verbose_llvm_cpu_features = parent_gen->verbose_llvm_cpu_features;
child_gen->llvm_argv = parent_gen->llvm_argv;
child_gen->dynamic_linker_path = parent_gen->dynamic_linker_path;
@@ -10739,6 +10746,7 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget
g->one_possible_values.init(32);
g->is_test_build = is_test_build;
g->is_single_threaded = false;
g->code_model = CodeModelDefault;
buf_resize(&g->global_asm, 0);
for (size_t i = 0; i < array_length(symbols_that_llvm_depends_on); i += 1) {