stage1: eliminate the IrInst base struct

This commit intentions to have no functional changes. The only purpose
is to delete the struct IrInst, which is the common base struct that
both IrInstSrc (ZIR) and IrInstGen (AIR) instructions embed.

This untangles stage1 ZIR and AIR memory layout, paving the way for a
following commit to reduce memory usage.
This commit is contained in:
Andrew Kelley 2021-07-02 19:46:12 -07:00
parent bb98620c10
commit af20fdbce7
6 changed files with 2011 additions and 1945 deletions

View File

@ -31,7 +31,6 @@ struct BuiltinFnEntry;
struct TypeStructField;
struct CodeGen;
struct ZigValue;
struct IrInst;
struct IrInstSrc;
struct IrInstGen;
struct IrInstGenCast;
@ -313,7 +312,7 @@ struct ConstErrValue {
struct ConstBoundFnValue {
ZigFn *fn;
IrInstGen *first_arg;
IrInst *first_arg_src;
AstNode *first_arg_src;
};
struct ConstArgTuple {
@ -394,7 +393,7 @@ struct LazyValueTypeInfoDecls {
IrAnalyze *ira;
ScopeDecls *decls_scope;
IrInst *source_instr;
AstNode *source_node;
};
struct LazyValueAlignOf {
@ -2444,7 +2443,7 @@ struct Stage1ZirBasicBlock {
IrBasicBlockGen *child;
Scope *scope;
const char *name_hint;
IrInst *suspend_instruction_ref;
IrInstSrc *suspend_instruction_ref;
uint32_t ref_count;
uint32_t index; // index into the basic block list
@ -2463,11 +2462,11 @@ struct IrBasicBlockGen {
// The instruction that referenced this basic block and caused us to
// analyze the basic block. If the same instruction wants us to emit
// the same basic block, then we re-generate it instead of saving it.
IrInst *ref_instruction;
IrInstSrc *ref_instruction;
// When this is non-null, a branch to this basic block is only allowed
// if the branch is comptime. The instruction points to the reason
// the basic block must be comptime.
IrInst *must_be_comptime_source_instr;
AstNode *must_be_comptime_source_node;
uint32_t debug_id;
bool already_appended;
@ -2714,24 +2713,13 @@ enum IrInstGenId {
IrInstGenIdExtern,
};
// Common fields between IrInstSrc and IrInstGen.
struct IrInst {
// if ref_count is zero and the instruction has no side effects,
// the instruction can be omitted in codegen
struct IrInstSrc {
uint32_t ref_count;
uint32_t debug_id;
Scope *scope;
AstNode *source_node;
// for debugging purposes, these are useful to call to inspect the instruction
void dump();
void src();
};
struct IrInstSrc {
IrInst base;
IrInstSrcId id;
// When analyzing IR, instructions that point to this instruction in the "old ir"
@ -2746,9 +2734,14 @@ struct IrInstSrc {
};
struct IrInstGen {
IrInst base;
IrInstGenId id;
// if ref_count is zero and the instruction has no side effects,
// the instruction can be omitted in codegen
uint32_t ref_count;
uint32_t debug_id;
Scope *scope;
AstNode *source_node;
LLVMValueRef llvm_value;
ZigValue *value;

View File

@ -5076,7 +5076,7 @@ static void analyze_fn_async(CodeGen *g, ZigFn *fn, bool resolve_frame) {
// TODO function pointer call here, could be anything
continue;
}
switch (analyze_callee_async(g, fn, call->fn_entry, call->base.base.source_node, must_not_be_async,
switch (analyze_callee_async(g, fn, call->fn_entry, call->base.source_node, must_not_be_async,
call->modifier))
{
case ErrorSemanticAnalyzeFail:
@ -5096,7 +5096,7 @@ static void analyze_fn_async(CodeGen *g, ZigFn *fn, bool resolve_frame) {
for (size_t i = 0; i < fn->await_list.length; i += 1) {
IrInstGenAwait *await = fn->await_list.at(i);
if (await->is_nosuspend) continue;
switch (analyze_callee_async(g, fn, await->target_fn, await->base.base.source_node, must_not_be_async,
switch (analyze_callee_async(g, fn, await->target_fn, await->base.source_node, must_not_be_async,
CallModifierNone))
{
case ErrorSemanticAnalyzeFail:
@ -6736,11 +6736,11 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
if (fn->analyzed_executable.need_err_code_spill) {
IrInstGenAlloca *alloca_gen = heap::c_allocator.create<IrInstGenAlloca>();
alloca_gen->base.id = IrInstGenIdAlloca;
alloca_gen->base.base.source_node = fn->proto_node;
alloca_gen->base.base.scope = fn->child_scope;
alloca_gen->base.source_node = fn->proto_node;
alloca_gen->base.scope = fn->child_scope;
alloca_gen->base.value = g->pass1_arena->create<ZigValue>();
alloca_gen->base.value->type = get_pointer_to_type(g, g->builtin_types.entry_global_error_set, false);
alloca_gen->base.base.ref_count = 1;
alloca_gen->base.ref_count = 1;
alloca_gen->name_hint = "";
fn->alloca_gen_list.append(alloca_gen);
fn->err_code_spill = &alloca_gen->base;
@ -6762,7 +6762,7 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
if (call->fn_ref->value->type->data.fn.fn_type_id.cc != CallingConventionAsync) {
continue;
}
add_node_error(g, call->base.base.source_node,
add_node_error(g, call->base.source_node,
buf_sprintf("function is not comptime-known; @asyncCall required"));
return ErrorSemanticAnalyzeFail;
}
@ -6772,14 +6772,14 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
if (callee->anal_state == FnAnalStateProbing) {
ErrorMsg *msg = add_node_error(g, fn->proto_node,
buf_sprintf("unable to determine async function frame of '%s'", buf_ptr(&fn->symbol_name)));
g->trace_err = add_error_note(g, msg, call->base.base.source_node,
g->trace_err = add_error_note(g, msg, call->base.source_node,
buf_sprintf("analysis of function '%s' depends on the frame", buf_ptr(&callee->symbol_name)));
return ErrorSemanticAnalyzeFail;
}
ZigType *callee_frame_type = get_fn_frame_type(g, callee);
frame_type->data.frame.resolve_loop_type = callee_frame_type;
frame_type->data.frame.resolve_loop_src_node = call->base.base.source_node;
frame_type->data.frame.resolve_loop_src_node = call->base.source_node;
analyze_fn_body(g, callee);
if (callee->anal_state == FnAnalStateInvalid) {
@ -6795,7 +6795,7 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
if (!fn_is_async(callee))
continue;
mark_suspension_point(call->base.base.scope);
mark_suspension_point(call->base.scope);
if ((err = type_resolve(g, callee_frame_type, ResolveStatusSizeKnown))) {
return err;
@ -6840,17 +6840,17 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
}
// This await is a suspend point, but it might not need a spill.
// We do need to mark the ExprScope as having a suspend point in it.
mark_suspension_point(await->base.base.scope);
mark_suspension_point(await->base.scope);
if (await->result_loc != nullptr) {
// If there's a result location, that is the spill
continue;
}
if (await->base.base.ref_count == 0)
if (await->base.ref_count == 0)
continue;
if (!type_has_bits(g, await->base.value->type))
continue;
await->result_loc = ir_create_alloca(g, await->base.base.scope, await->base.base.source_node, fn,
await->result_loc = ir_create_alloca(g, await->base.scope, await->base.source_node, fn,
await->base.value->type, "");
}
for (size_t block_i = 0; block_i < fn->analyzed_executable.basic_block_list.length; block_i += 1) {
@ -6858,7 +6858,7 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
for (size_t instr_i = 0; instr_i < block->instruction_list.length; instr_i += 1) {
IrInstGen *instruction = block->instruction_list.at(instr_i);
if (instruction->id == IrInstGenIdSuspendFinish) {
mark_suspension_point(instruction->base.scope);
mark_suspension_point(instruction->scope);
}
}
}
@ -6885,14 +6885,14 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
}
if (instruction->value->special != ConstValSpecialRuntime)
continue;
if (instruction->base.ref_count == 0)
if (instruction->ref_count == 0)
continue;
if ((err = type_resolve(g, instruction->value->type, ResolveStatusZeroBitsKnown)))
return ErrorSemanticAnalyzeFail;
if (!type_has_bits(g, instruction->value->type))
continue;
if (scope_needs_spill(instruction->base.scope)) {
instruction->spill = ir_create_alloca(g, instruction->base.scope, instruction->base.source_node,
if (scope_needs_spill(instruction->scope)) {
instruction->spill = ir_create_alloca(g, instruction->scope, instruction->source_node,
fn, instruction->value->type, "");
}
}
@ -6950,7 +6950,7 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
ZigType *child_type = resolve_type_isf(ptr_type->data.pointer.child_type);
if (!type_has_bits(g, child_type))
continue;
if (instruction->base.base.ref_count == 0)
if (instruction->base.ref_count == 0)
continue;
if (instruction->base.value->special != ConstValSpecialRuntime) {
if (const_ptr_pointee(nullptr, g, instruction->base.value, nullptr)->special !=
@ -6961,7 +6961,7 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
}
frame_type->data.frame.resolve_loop_type = child_type;
frame_type->data.frame.resolve_loop_src_node = instruction->base.base.source_node;
frame_type->data.frame.resolve_loop_src_node = instruction->base.source_node;
if ((err = type_resolve(g, child_type, ResolveStatusSizeKnown))) {
return err;
}

View File

@ -39,7 +39,7 @@ static ZigVar *ir_create_var(Stage1AstGen *ag, AstNode *node, Scope *scope, Buf
static void build_decl_var_and_init(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
ZigVar *var, IrInstSrc *init, const char *name_hint, IrInstSrc *is_comptime);
static void ir_assert_impl(bool ok, IrInst *source_instruction, char const *file, unsigned int line) {
static void ir_assert_impl(bool ok, IrInstSrc *source_instruction, char const *file, unsigned int line) {
if (ok) return;
src_assert_impl(ok, source_instruction->source_node, file, line);
}
@ -386,7 +386,7 @@ static void ir_ref_bb(Stage1ZirBasicBlock *bb) {
static void ir_ref_instruction(IrInstSrc *instruction, Stage1ZirBasicBlock *cur_bb) {
assert(instruction->id != IrInstSrcIdInvalid);
instruction->base.ref_count += 1;
instruction->ref_count += 1;
if (instruction->owner_bb != cur_bb && !instr_is_unreachable(instruction)
&& instruction->id != IrInstSrcIdConst)
{
@ -939,9 +939,9 @@ template<typename T>
static T *ir_create_instruction(Stage1AstGen *ag, Scope *scope, AstNode *source_node) {
T *special_instruction = heap::c_allocator.create<T>();
special_instruction->base.id = ir_inst_id(special_instruction);
special_instruction->base.base.scope = scope;
special_instruction->base.base.source_node = source_node;
special_instruction->base.base.debug_id = irb_next_debug_id(ag);
special_instruction->base.scope = scope;
special_instruction->base.source_node = source_node;
special_instruction->base.debug_id = irb_next_debug_id(ag);
special_instruction->base.owner_bb = ag->current_basic_block;
return special_instruction;
}
@ -1325,9 +1325,9 @@ static IrInstSrc *ir_build_ptr_type_simple(Stage1AstGen *ag, Scope *scope, AstNo
{
IrInstSrcPtrTypeSimple *inst = heap::c_allocator.create<IrInstSrcPtrTypeSimple>();
inst->base.id = is_const ? IrInstSrcIdPtrTypeSimpleConst : IrInstSrcIdPtrTypeSimple;
inst->base.base.scope = scope;
inst->base.base.source_node = source_node;
inst->base.base.debug_id = irb_next_debug_id(ag);
inst->base.scope = scope;
inst->base.source_node = source_node;
inst->base.debug_id = irb_next_debug_id(ag);
inst->base.owner_bb = ag->current_basic_block;
ir_instruction_append(ag->current_basic_block, &inst->base);
@ -2391,9 +2391,9 @@ static IrInstSrc *ir_build_check_switch_prongs(Stage1AstGen *ag, Scope *scope, A
IrInstSrcCheckSwitchProngs *instruction = heap::c_allocator.create<IrInstSrcCheckSwitchProngs>();
instruction->base.id = have_underscore_prong ?
IrInstSrcIdCheckSwitchProngsUnderYes : IrInstSrcIdCheckSwitchProngsUnderNo;
instruction->base.base.scope = scope;
instruction->base.base.source_node = source_node;
instruction->base.base.debug_id = irb_next_debug_id(ag);
instruction->base.scope = scope;
instruction->base.source_node = source_node;
instruction->base.debug_id = irb_next_debug_id(ag);
instruction->base.owner_bb = ag->current_basic_block;
ir_instruction_append(ag->current_basic_block, &instruction->base);
@ -2582,9 +2582,9 @@ static IrInstSrc *ir_build_arg_type(Stage1AstGen *ag, Scope *scope, AstNode *sou
IrInstSrcArgType *instruction = heap::c_allocator.create<IrInstSrcArgType>();
instruction->base.id = allow_var ?
IrInstSrcIdArgTypeAllowVarTrue : IrInstSrcIdArgTypeAllowVarFalse;
instruction->base.base.scope = scope;
instruction->base.base.source_node = source_node;
instruction->base.base.debug_id = irb_next_debug_id(ag);
instruction->base.scope = scope;
instruction->base.source_node = source_node;
instruction->base.debug_id = irb_next_debug_id(ag);
instruction->base.owner_bb = ag->current_basic_block;
ir_instruction_append(ag->current_basic_block, &instruction->base);
@ -3157,7 +3157,7 @@ ZigVar *create_local_var(CodeGen *codegen, AstNode *node, Scope *parent_scope,
variable_entry->const_value = codegen->pass1_arena->create<ZigValue>();
if (is_comptime != nullptr) {
is_comptime->base.ref_count += 1;
is_comptime->ref_count += 1;
}
if (name) {
@ -3405,7 +3405,7 @@ static IrInstSrc *astgen_block(Stage1AstGen *ag, Scope *parent_scope, AstNode *b
ir_build_end_expr(ag, parent_scope, block_node, result, &result_loc_ret->base);
if (!astgen_defers_for_block(ag, child_scope, outer_block_scope, nullptr, nullptr))
return ag->codegen->invalid_inst_src;
return ir_build_return_src(ag, child_scope, result->base.source_node, result);
return ir_build_return_src(ag, child_scope, result->source_node, result);
}
static IrInstSrc *astgen_bin_op_id(Stage1AstGen *ag, Scope *scope, AstNode *node, IrBinOp op_id) {
@ -3565,9 +3565,9 @@ static ResultLocPeerParent *ir_build_result_peers(Stage1AstGen *ag, IrInstSrc *c
peer_parent->parent = parent;
IrInstSrc *popped_inst = ag->current_basic_block->instruction_list.pop();
ir_assert(popped_inst == cond_br_inst, &cond_br_inst->base);
ir_assert(popped_inst == cond_br_inst, cond_br_inst);
ir_build_reset_result(ag, cond_br_inst->base.scope, cond_br_inst->base.source_node, &peer_parent->base);
ir_build_reset_result(ag, cond_br_inst->scope, cond_br_inst->source_node, &peer_parent->base);
ag->current_basic_block->instruction_list.append(popped_inst);
return peer_parent;
@ -5436,7 +5436,7 @@ static IrInstSrc *astgen_prefix_op_id(Stage1AstGen *ag, Scope *scope, AstNode *n
static IrInstSrc *ir_expr_wrap(Stage1AstGen *ag, Scope *scope, IrInstSrc *inst, ResultLoc *result_loc) {
if (inst == ag->codegen->invalid_inst_src) return inst;
ir_build_end_expr(ag, scope, inst->base.source_node, inst, result_loc);
ir_build_end_expr(ag, scope, inst->source_node, inst, result_loc);
return inst;
}
@ -5447,7 +5447,7 @@ static IrInstSrc *ir_lval_wrap(Stage1AstGen *ag, Scope *scope, IrInstSrc *value,
// [STMT_EXPR_TEST_THING] <--- (search this token)
if (value == ag->codegen->invalid_inst_src ||
instr_is_unreachable(value) ||
value->base.source_node->type == NodeTypeDefer ||
value->source_node->type == NodeTypeDefer ||
value->id == IrInstSrcIdDeclVar)
{
return value;
@ -5457,7 +5457,7 @@ static IrInstSrc *ir_lval_wrap(Stage1AstGen *ag, Scope *scope, IrInstSrc *value,
if (lval == LValPtr) {
// We needed a pointer to a value, but we got a value. So we create
// an instruction which just makes a pointer of it.
return ir_build_ref_src(ag, scope, value->base.source_node, value);
return ir_build_ref_src(ag, scope, value->source_node, value);
} else if (result_loc != nullptr) {
return ir_expr_wrap(ag, scope, value, result_loc);
} else {
@ -5690,11 +5690,11 @@ static IrInstSrc *astgen_container_init_expr(Stage1AstGen *ag, Scope *scope, Ast
result_loc_cast = ir_build_cast_result_loc(ag, container_type, parent_result_loc);
child_result_loc = &result_loc_cast->base;
init_array_type_source_node = container_type->base.source_node;
init_array_type_source_node = container_type->source_node;
} else {
child_result_loc = parent_result_loc;
if (parent_result_loc->source_instruction != nullptr) {
init_array_type_source_node = parent_result_loc->source_instruction->base.source_node;
init_array_type_source_node = parent_result_loc->source_instruction->source_node;
} else {
init_array_type_source_node = node;
}
@ -5784,7 +5784,7 @@ static ResultLocVar *ir_build_var_result_loc(Stage1AstGen *ag, IrInstSrc *alloca
result_loc_var->base.allow_write_through_const = true;
result_loc_var->var = var;
ir_build_reset_result(ag, alloca->base.scope, alloca->base.source_node, &result_loc_var->base);
ir_build_reset_result(ag, alloca->scope, alloca->source_node, &result_loc_var->base);
return result_loc_var;
}
@ -5799,7 +5799,7 @@ static ResultLocCast *ir_build_cast_result_loc(Stage1AstGen *ag, IrInstSrc *dest
ir_ref_instruction(dest_type, ag->current_basic_block);
result_loc_cast->parent = parent_result_loc;
ir_build_reset_result(ag, dest_type->base.scope, dest_type->base.source_node, &result_loc_cast->base);
ir_build_reset_result(ag, dest_type->scope, dest_type->source_node, &result_loc_cast->base);
return result_loc_cast;
}
@ -5897,7 +5897,7 @@ static IrInstSrc *astgen_var_decl(Stage1AstGen *ag, Scope *scope, AstNode *node)
return ag->codegen->invalid_inst_src;
if (result_loc_cast != nullptr) {
IrInstSrc *implicit_cast = ir_build_implicit_cast(ag, scope, init_value->base.source_node,
IrInstSrc *implicit_cast = ir_build_implicit_cast(ag, scope, init_value->source_node,
init_value, result_loc_cast);
ir_build_end_expr(ag, scope, node, implicit_cast, &result_loc_var->base);
}
@ -8066,13 +8066,13 @@ bool stage1_astgen(CodeGen *codegen, AstNode *node, Scope *scope, Stage1Zir *sta
}
if (!instr_is_unreachable(result)) {
ir_build_add_implicit_return_type(ag, scope, result->base.source_node, result, nullptr);
ir_build_add_implicit_return_type(ag, scope, result->source_node, result, nullptr);
// no need for save_err_ret_addr because this cannot return error
ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>();
result_loc_ret->base.id = ResultLocIdReturn;
ir_build_reset_result(ag, scope, node, &result_loc_ret->base);
ir_build_end_expr(ag, scope, node, result, &result_loc_ret->base);
ir_build_return_src(ag, scope, result->base.source_node, result);
ir_build_return_src(ag, scope, result->source_node, result);
}
return true;
@ -8113,3 +8113,12 @@ void ir_add_call_stack_errors_gen(CodeGen *codegen, Stage1Air *exec, ErrorMsg *e
ir_add_call_stack_errors_gen(codegen, exec->parent_exec, err_msg, limit - 1);
}
void IrInstSrc::src() {
IrInstSrc *inst = this;
if (inst->source_node != nullptr) {
inst->source_node->src();
} else {
fprintf(stderr, "(null source node)\n");
}
}

View File

@ -908,14 +908,14 @@ static LLVMValueRef get_handle_value(CodeGen *g, LLVMValueRef ptr, ZigType *type
static void ir_assert_impl(bool ok, IrInstGen *source_instruction, const char *file, unsigned int line) {
if (ok) return;
src_assert_impl(ok, source_instruction->base.source_node, file, line);
src_assert_impl(ok, source_instruction->source_node, file, line);
}
#define ir_assert(OK, SOURCE_INSTRUCTION) ir_assert_impl((OK), (SOURCE_INSTRUCTION), __FILE__, __LINE__)
static bool ir_want_fast_math(CodeGen *g, IrInstGen *instruction) {
// TODO memoize
Scope *scope = instruction->base.scope;
Scope *scope = instruction->scope;
while (scope) {
if (scope->id == ScopeIdBlock) {
ScopeBlock *block_scope = (ScopeBlock *)scope;
@ -951,7 +951,7 @@ static bool ir_want_runtime_safety_scope(CodeGen *g, Scope *scope) {
}
static bool ir_want_runtime_safety(CodeGen *g, IrInstGen *instruction) {
return ir_want_runtime_safety_scope(g, instruction->base.scope);
return ir_want_runtime_safety_scope(g, instruction->scope);
}
static Buf *panic_msg_buf(PanicMsgId msg_id) {
@ -1078,7 +1078,7 @@ static void gen_assertion_scope(CodeGen *g, PanicMsgId msg_id, Scope *source_sco
}
static void gen_assertion(CodeGen *g, PanicMsgId msg_id, IrInstGen *source_instruction) {
return gen_assertion_scope(g, msg_id, source_instruction->base.scope);
return gen_assertion_scope(g, msg_id, source_instruction->scope);
}
static LLVMValueRef gen_wasm_memory_size(CodeGen *g) {
@ -1923,7 +1923,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
return false;
IrInstGen *arg = fn_walk->data.call.inst->args[src_i];
ty = arg->value->type;
source_node = arg->base.source_node;
source_node = arg->source_node;
val = ir_llvm_value(g, arg);
break;
}
@ -2451,7 +2451,7 @@ static LLVMValueRef ir_render_save_err_ret_addr(CodeGen *g, Stage1Air *executabl
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.base.scope,
LLVMValueRef my_err_trace_val = get_cur_err_ret_trace_val(g, save_err_ret_addr_instruction->base.scope,
&is_llvm_alloca);
ZigLLVMBuildCall(g->builder, return_err_fn, &my_err_trace_val, 1,
get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAuto, "");
@ -2622,7 +2622,7 @@ static void gen_async_return(CodeGen *g, IrInstGenReturn *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.base.scope, &is_llvm_alloca);
LLVMValueRef my_err_trace_val = get_cur_err_ret_trace_val(g, instruction->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, "");
@ -3900,7 +3900,7 @@ static LLVMValueRef ir_render_store_ptr(CodeGen *g, Stage1Air *executable, IrIns
codegen_report_errors_and_exit(g);
if (!ptr_type_has_bits)
return nullptr;
if (instruction->ptr->base.ref_count == 0) {
if (instruction->ptr->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;
@ -4365,7 +4365,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, IrInstGenC
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.base.scope,
LLVMValueRef my_err_ret_trace_val = get_cur_err_ret_trace_val(g, instruction->base.scope,
&is_llvm_alloca);
LLVMBuildStore(g->builder, my_err_ret_trace_val, err_ret_trace_ptr_ptr);
}
@ -4424,7 +4424,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, IrInstGenC
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.base.scope, &is_llvm_alloca));
gen_param_values.append(get_cur_err_ret_trace_val(g, instruction->base.scope, &is_llvm_alloca));
}
}
} else {
@ -4433,7 +4433,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, IrInstGenC
}
if (prefix_arg_err_ret_stack) {
bool is_llvm_alloca;
gen_param_values.append(get_cur_err_ret_trace_val(g, instruction->base.base.scope, &is_llvm_alloca));
gen_param_values.append(get_cur_err_ret_trace_val(g, instruction->base.scope, &is_llvm_alloca));
}
}
FnWalk fn_walk = {};
@ -4567,7 +4567,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, IrInstGenC
LLVMPositionBuilderAtEnd(g->builder, call_bb);
gen_assert_resume_id(g, &instruction->base, ResumeIdReturn, PanicMsgIdResumedAnAwaitingFn, nullptr);
render_async_var_decls(g, instruction->base.base.scope);
render_async_var_decls(g, instruction->base.scope);
if (!type_has_bits(g, src_return_type))
return nullptr;
@ -4795,7 +4795,7 @@ static size_t find_asm_index(CodeGen *g, AstNode *node, AsmToken *tok, Buf *src_
}
static LLVMValueRef ir_render_asm_gen(CodeGen *g, Stage1Air *executable, IrInstGenAsm *instruction) {
AstNode *asm_node = instruction->base.base.source_node;
AstNode *asm_node = instruction->base.source_node;
assert(asm_node->type == NodeTypeAsmExpr);
AstNodeAsmExpr *asm_expr = &asm_node->data.asm_expr;
@ -5463,7 +5463,7 @@ static LLVMValueRef ir_render_error_return_trace(CodeGen *g, Stage1Air *executab
IrInstGenErrorReturnTrace *instruction)
{
bool is_llvm_alloca;
LLVMValueRef cur_err_ret_trace_val = get_cur_err_ret_trace_val(g, instruction->base.base.scope, &is_llvm_alloca);
LLVMValueRef cur_err_ret_trace_val = get_cur_err_ret_trace_val(g, instruction->base.scope, &is_llvm_alloca);
if (cur_err_ret_trace_val == nullptr) {
return LLVMConstNull(get_llvm_type(g, ptr_to_stack_trace_type(g)));
}
@ -5692,7 +5692,7 @@ static LLVMValueRef ir_render_memset(CodeGen *g, Stage1Air *executable, IrInstGe
bool val_is_undef = value_is_all_undef(g, instruction->byte->value);
LLVMValueRef fill_char;
if (val_is_undef) {
if (ir_want_runtime_safety_scope(g, instruction->base.base.scope)) {
if (ir_want_runtime_safety_scope(g, instruction->base.scope)) {
fill_char = LLVMConstInt(LLVMInt8Type(), 0xaa, false);
} else {
return nullptr;
@ -6179,7 +6179,7 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, Stage1Air *executab
LLVMBuildCondBr(g->builder, cond_val, ok_block, err_block);
LLVMPositionBuilderAtEnd(g->builder, err_block);
gen_safety_crash_for_err(g, err_val, instruction->base.base.scope);
gen_safety_crash_for_err(g, err_val, instruction->base.scope);
LLVMPositionBuilderAtEnd(g->builder, ok_block);
}
@ -6306,7 +6306,7 @@ static LLVMValueRef ir_render_union_tag(CodeGen *g, Stage1Air *executable, IrIns
static LLVMValueRef ir_render_panic(CodeGen *g, Stage1Air *executable, IrInstGenPanic *instruction) {
bool is_llvm_alloca;
LLVMValueRef err_ret_trace_val = get_cur_err_ret_trace_val(g, instruction->base.base.scope, &is_llvm_alloca);
LLVMValueRef err_ret_trace_val = get_cur_err_ret_trace_val(g, instruction->base.scope, &is_llvm_alloca);
gen_panic(g, ir_llvm_value(g, instruction->msg), err_ret_trace_val, is_llvm_alloca);
return nullptr;
}
@ -6619,7 +6619,7 @@ static LLVMValueRef ir_render_suspend_finish(CodeGen *g, Stage1Air *executable,
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.base.scope);
render_async_var_decls(g, instruction->base.scope);
return nullptr;
}
@ -6649,7 +6649,7 @@ static LLVMValueRef gen_await_early_return(CodeGen *g, IrInstGen *source_instr,
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->base.scope, &is_llvm_alloca);
LLVMValueRef dest_trace_ptr = get_cur_err_ret_trace_val(g, source_instr->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, "");
@ -6701,7 +6701,7 @@ static LLVMValueRef ir_render_await(CodeGen *g, Stage1Air *executable, IrInstGen
// 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.base.scope, &is_llvm_alloca);
LLVMValueRef my_err_ret_trace_val = get_cur_err_ret_trace_val(g, instruction->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, "");
@ -6810,8 +6810,8 @@ static LLVMValueRef ir_render_vector_extract_elem(CodeGen *g, Stage1Air *executa
}
static void set_debug_location(CodeGen *g, IrInstGen *instruction) {
AstNode *source_node = instruction->base.source_node;
Scope *scope = instruction->base.scope;
AstNode *source_node = instruction->source_node;
Scope *scope = instruction->scope;
assert(source_node);
assert(scope);
@ -7020,9 +7020,9 @@ static void ir_render(CodeGen *g, ZigFn *fn_entry) {
LLVMPositionBuilderAtEnd(g->builder, current_block->llvm_block);
for (size_t instr_i = 0; instr_i < current_block->instruction_list.length; instr_i += 1) {
IrInstGen *instruction = current_block->instruction_list.at(instr_i);
if (instruction->base.ref_count == 0 && !ir_inst_gen_has_side_effects(instruction))
if (instruction->ref_count == 0 && !ir_inst_gen_has_side_effects(instruction))
continue;
if (get_scope_typeof(instruction->base.scope) != nullptr)
if (get_scope_typeof(instruction->scope) != nullptr)
continue;
if (!g->strip_debug_symbols) {
@ -8270,7 +8270,7 @@ static void do_code_gen(CodeGen *g) {
zig_unreachable();
if (!type_has_bits(g, child_type))
continue;
if (instruction->base.base.ref_count == 0)
if (instruction->base.ref_count == 0)
continue;
if (instruction->base.value->special != ConstValSpecialRuntime) {
if (const_ptr_pointee(nullptr, g, instruction->base.value, nullptr)->special !=
@ -8448,7 +8448,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)->base.scope);
render_async_var_decls(g, entry_block->instruction_list.at(0)->scope);
} else {
// create debug variable declarations for parameters
// rely on the first variables in the variable_list being parameters.

File diff suppressed because it is too large Load Diff

View File

@ -581,8 +581,8 @@ static void ir_print_prefix_src(IrPrintSrc *irp, IrInstSrc *instruction, bool tr
type_name = "(unknown)";
}
const char *ref_count = ir_inst_src_has_side_effects(instruction) ?
"-" : buf_ptr(buf_sprintf("%" PRIu32 "", instruction->base.ref_count));
fprintf(irp->f, "%c%-3" PRIu32 "| %-22s| %-12s| %-2s| ", mark, instruction->base.debug_id,
"-" : buf_ptr(buf_sprintf("%" PRIu32 "", instruction->ref_count));
fprintf(irp->f, "%c%-3" PRIu32 "| %-22s| %-12s| %-2s| ", mark, instruction->debug_id,
ir_inst_src_type_str(instruction->id), type_name, ref_count);
}
@ -591,17 +591,17 @@ static void ir_print_prefix_gen(IrPrintGen *irp, IrInstGen *instruction, bool tr
const char mark = trailing ? ':' : '#';
const char *type_name = instruction->value->type ? buf_ptr(&instruction->value->type->name) : "(unknown)";
const char *ref_count = ir_inst_gen_has_side_effects(instruction) ?
"-" : buf_ptr(buf_sprintf("%" PRIu32 "", instruction->base.ref_count));
fprintf(irp->f, "%c%-3" PRIu32 "| %-22s| %-12s| %-2s| ", mark, instruction->base.debug_id,
"-" : buf_ptr(buf_sprintf("%" PRIu32 "", instruction->ref_count));
fprintf(irp->f, "%c%-3" PRIu32 "| %-22s| %-12s| %-2s| ", mark, instruction->debug_id,
ir_inst_gen_type_str(instruction->id), type_name, ref_count);
}
static void ir_print_var_src(IrPrintSrc *irp, IrInstSrc *inst) {
fprintf(irp->f, "#%" PRIu32 "", inst->base.debug_id);
fprintf(irp->f, "#%" PRIu32 "", inst->debug_id);
}
static void ir_print_var_gen(IrPrintGen *irp, IrInstGen *inst) {
fprintf(irp->f, "#%" PRIu32 "", inst->base.debug_id);
fprintf(irp->f, "#%" PRIu32 "", inst->debug_id);
if (irp->printed.maybe_get(inst) == nullptr) {
irp->printed.put(inst, 0);
irp->pending.append(inst);
@ -1231,8 +1231,8 @@ static void ir_print_any_frame_type(IrPrintSrc *irp, IrInstSrcAnyFrameType *inst
}
static void ir_print_asm_src(IrPrintSrc *irp, IrInstSrcAsm *instruction) {
assert(instruction->base.base.source_node->type == NodeTypeAsmExpr);
AstNodeAsmExpr *asm_expr = &instruction->base.base.source_node->data.asm_expr;
assert(instruction->base.source_node->type == NodeTypeAsmExpr);
AstNodeAsmExpr *asm_expr = &instruction->base.source_node->data.asm_expr;
const char *volatile_kw = instruction->has_side_effects ? " volatile" : "";
fprintf(irp->f, "asm%s (", volatile_kw);
ir_print_other_inst_src(irp, instruction->asm_template);
@ -1274,8 +1274,8 @@ static void ir_print_asm_src(IrPrintSrc *irp, IrInstSrcAsm *instruction) {
}
static void ir_print_asm_gen(IrPrintGen *irp, IrInstGenAsm *instruction) {
assert(instruction->base.base.source_node->type == NodeTypeAsmExpr);
AstNodeAsmExpr *asm_expr = &instruction->base.base.source_node->data.asm_expr;
assert(instruction->base.source_node->type == NodeTypeAsmExpr);
AstNodeAsmExpr *asm_expr = &instruction->base.source_node->data.asm_expr;
const char *volatile_kw = instruction->has_side_effects ? " volatile" : "";
fprintf(irp->f, "asm%s (\"%s\") : ", volatile_kw, buf_ptr(instruction->asm_template));
@ -2003,10 +2003,10 @@ static void ir_print_err_wrap_payload(IrPrintGen *irp, IrInstGenErrWrapPayload *
static void ir_print_fn_proto(IrPrintSrc *irp, IrInstSrcFnProto *instruction) {
fprintf(irp->f, "fn(");
for (size_t i = 0; i < instruction->base.base.source_node->data.fn_proto.params.length; i += 1) {
for (size_t i = 0; i < instruction->base.source_node->data.fn_proto.params.length; i += 1) {
if (i != 0)
fprintf(irp->f, ",");
if (instruction->is_var_args && i == instruction->base.base.source_node->data.fn_proto.params.length - 1) {
if (instruction->is_var_args && i == instruction->base.source_node->data.fn_proto.params.length - 1) {
fprintf(irp->f, "...");
} else {
ir_print_other_inst_src(irp, instruction->param_types[i]);
@ -3450,3 +3450,15 @@ void ir_print_inst_gen(CodeGen *codegen, FILE *f, IrInstGen *instruction, int in
ir_print_inst_gen(irp, instruction, false);
}
void IrInstSrc::dump() {
IrInstSrc *inst = this;
inst->src();
if (inst->scope == nullptr) {
fprintf(stderr, "(null scope)\n");
} else {
ir_print_inst_src(inst->scope->codegen, stderr, inst, 0);
fprintf(stderr, "-> ");
ir_print_inst_gen(inst->scope->codegen, stderr, inst->child, 0);
}
}