| ... | @@ -42,6 +42,7 @@ struct IrAnalyze { | ... | @@ -42,6 +42,7 @@ struct IrAnalyze { |
| 42 | ZigList<IrSuspendPosition> resume_stack; | 42 | ZigList<IrSuspendPosition> resume_stack; |
| 43 | IrBasicBlock *const_predecessor_bb; | 43 | IrBasicBlock *const_predecessor_bb; |
| 44 | size_t ref_count; | 44 | size_t ref_count; |
| | 45 | size_t break_debug_id; // for debugging purposes |
| 45 | | 46 | |
| 46 | // For the purpose of using in a debugger | 47 | // For the purpose of using in a debugger |
| 47 | void dump(); | 48 | void dump(); |
| ... | @@ -198,6 +199,14 @@ struct ConstCastIntShorten { | ... | @@ -198,6 +199,14 @@ struct ConstCastIntShorten { |
| 198 | ZigType *actual_type; | 199 | ZigType *actual_type; |
| 199 | }; | 200 | }; |
| 200 | | 201 | |
| | 202 | // for debugging purposes |
| | 203 | struct DbgIrBreakPoint { |
| | 204 | const char *src_file; |
| | 205 | uint32_t line; |
| | 206 | }; |
| | 207 | DbgIrBreakPoint dbg_ir_breakpoints_buf[20]; |
| | 208 | size_t dbg_ir_breakpoints_count = 0; |
| | 209 | |
| 201 | static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope); | 210 | static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope); |
| 202 | static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval, | 211 | static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval, |
| 203 | ResultLoc *result_loc); | 212 | ResultLoc *result_loc); |
| ... | @@ -11355,8 +11364,12 @@ static void copy_const_val(ZigValue *dest, ZigValue *src) { | ... | @@ -11355,8 +11364,12 @@ static void copy_const_val(ZigValue *dest, ZigValue *src) { |
| 11355 | dest->data.x_struct.fields = alloc_const_vals_ptrs(dest->type->data.structure.src_field_count); | 11364 | dest->data.x_struct.fields = alloc_const_vals_ptrs(dest->type->data.structure.src_field_count); |
| 11356 | for (size_t i = 0; i < dest->type->data.structure.src_field_count; i += 1) { | 11365 | for (size_t i = 0; i < dest->type->data.structure.src_field_count; i += 1) { |
| 11357 | copy_const_val(dest->data.x_struct.fields[i], src->data.x_struct.fields[i]); | 11366 | copy_const_val(dest->data.x_struct.fields[i], src->data.x_struct.fields[i]); |
| | 11367 | dest->data.x_struct.fields[i]->parent.id = ConstParentIdStruct; |
| | 11368 | dest->data.x_struct.fields[i]->parent.data.p_struct.struct_val = dest; |
| | 11369 | dest->data.x_struct.fields[i]->parent.data.p_struct.field_index = i; |
| 11358 | } | 11370 | } |
| 11359 | } | 11371 | } |
| | 11372 | dest->parent.id = ConstParentIdNone; |
| 11360 | } | 11373 | } |
| 11361 | | 11374 | |
| 11362 | static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInstruction *source_instr, | 11375 | static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInstruction *source_instr, |
| ... | @@ -11474,6 +11487,14 @@ static IrInstruction *ir_const_noval(IrAnalyze *ira, IrInstruction *old_instruct | ... | @@ -11474,6 +11487,14 @@ static IrInstruction *ir_const_noval(IrAnalyze *ira, IrInstruction *old_instruct |
| 11474 | return &const_instruction->base; | 11487 | return &const_instruction->base; |
| 11475 | } | 11488 | } |
| 11476 | | 11489 | |
| | 11490 | // This function initializes the new IrInstruction with the provided ZigValue, |
| | 11491 | // rather than creating a new one. |
| | 11492 | static IrInstruction *ir_const_move(IrAnalyze *ira, IrInstruction *old_instruction, ZigValue *val) { |
| | 11493 | IrInstruction *result = ir_const_noval(ira, old_instruction); |
| | 11494 | result->value = val; |
| | 11495 | return result; |
| | 11496 | } |
| | 11497 | |
| 11477 | static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, | 11498 | static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, |
| 11478 | ZigType *wanted_type, CastOp cast_op) | 11499 | ZigType *wanted_type, CastOp cast_op) |
| 11479 | { | 11500 | { |
| ... | @@ -14216,9 +14237,7 @@ static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructio | ... | @@ -14216,9 +14237,7 @@ static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructio |
| 14216 | } | 14237 | } |
| 14217 | | 14238 | |
| 14218 | static IrInstruction *ir_analyze_instruction_const(IrAnalyze *ira, IrInstructionConst *instruction) { | 14239 | static IrInstruction *ir_analyze_instruction_const(IrAnalyze *ira, IrInstructionConst *instruction) { |
| 14219 | IrInstruction *result = ir_const(ira, &instruction->base, nullptr); | 14240 | return ir_const_move(ira, &instruction->base, instruction->base.value); |
| 14220 | copy_const_val(result->value, instruction->base.value); | | |
| 14221 | return result; | | |
| 14222 | } | 14241 | } |
| 14223 | | 14242 | |
| 14224 | static IrInstruction *ir_analyze_bin_op_bool(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) { | 14243 | static IrInstruction *ir_analyze_bin_op_bool(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) { |
| ... | @@ -16633,6 +16652,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe | ... | @@ -16633,6 +16652,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe |
| 16633 | | 16652 | |
| 16634 | ZigType *parent_ptr_type = parent_result_loc->value->type; | 16653 | ZigType *parent_ptr_type = parent_result_loc->value->type; |
| 16635 | assert(parent_ptr_type->id == ZigTypeIdPointer); | 16654 | assert(parent_ptr_type->id == ZigTypeIdPointer); |
| | 16655 | |
| 16636 | if ((err = type_resolve(ira->codegen, parent_ptr_type->data.pointer.child_type, | 16656 | if ((err = type_resolve(ira->codegen, parent_ptr_type->data.pointer.child_type, |
| 16637 | ResolveStatusAlignmentKnown))) | 16657 | ResolveStatusAlignmentKnown))) |
| 16638 | { | 16658 | { |
| ... | @@ -17283,6 +17303,7 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source | ... | @@ -17283,6 +17303,7 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source |
| 17283 | return ira->codegen->invalid_instruction; | 17303 | return ira->codegen->invalid_instruction; |
| 17284 | if (dest_val->special != ConstValSpecialRuntime) { | 17304 | if (dest_val->special != ConstValSpecialRuntime) { |
| 17285 | copy_const_val(dest_val, value->value); | 17305 | copy_const_val(dest_val, value->value); |
| | 17306 | |
| 17286 | if (ptr->value->data.x_ptr.mut == ConstPtrMutComptimeVar && | 17307 | if (ptr->value->data.x_ptr.mut == ConstPtrMutComptimeVar && |
| 17287 | !ira->new_irb.current_basic_block->must_be_comptime_source_instr) | 17308 | !ira->new_irb.current_basic_block->must_be_comptime_source_instr) |
| 17288 | { | 17309 | { |
| ... | @@ -17556,9 +17577,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c | ... | @@ -17556,9 +17577,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c |
| 17556 | } | 17577 | } |
| 17557 | } | 17578 | } |
| 17558 | | 17579 | |
| 17559 | IrInstruction *new_instruction = ir_const(ira, &call_instruction->base, result->type); | 17580 | IrInstruction *new_instruction = ir_const_move(ira, &call_instruction->base, result); |
| 17560 | copy_const_val(new_instruction->value, result); | | |
| 17561 | new_instruction->value->type = return_type; | | |
| 17562 | return ir_finish_anal(ira, new_instruction); | 17581 | return ir_finish_anal(ira, new_instruction); |
| 17563 | } | 17582 | } |
| 17564 | | 17583 | |
| ... | @@ -27978,7 +27997,24 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_ | ... | @@ -27978,7 +27997,24 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_ |
| 27978 | } | 27997 | } |
| 27979 | | 27998 | |
| 27980 | if (ira->codegen->verbose_ir) { | 27999 | if (ira->codegen->verbose_ir) { |
| 27981 | fprintf(stderr, "analyze #%" PRIu32 "\n", old_instruction->debug_id); | 28000 | fprintf(stderr, "~ "); |
| | 28001 | old_instruction->src(); |
| | 28002 | fprintf(stderr, "~ "); |
| | 28003 | ir_print_instruction(codegen, stderr, old_instruction, 0, IrPassSrc); |
| | 28004 | bool want_break = false; |
| | 28005 | if (ira->break_debug_id == old_instruction->debug_id) { |
| | 28006 | want_break = true; |
| | 28007 | } else if (old_instruction->source_node != nullptr) { |
| | 28008 | for (size_t i = 0; i < dbg_ir_breakpoints_count; i += 1) { |
| | 28009 | if (dbg_ir_breakpoints_buf[i].line == old_instruction->source_node->line + 1 && |
| | 28010 | buf_ends_with_str(old_instruction->source_node->owner->data.structure.root_struct->path, |
| | 28011 | dbg_ir_breakpoints_buf[i].src_file)) |
| | 28012 | { |
| | 28013 | want_break = true; |
| | 28014 | } |
| | 28015 | } |
| | 28016 | } |
| | 28017 | if (want_break) BREAKPOINT; |
| 27982 | } | 28018 | } |
| 27983 | IrInstruction *new_instruction = ir_analyze_instruction_base(ira, old_instruction); | 28019 | IrInstruction *new_instruction = ir_analyze_instruction_base(ira, old_instruction); |
| 27984 | if (new_instruction != nullptr) { | 28020 | if (new_instruction != nullptr) { |
| ... | @@ -27986,6 +28022,10 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_ | ... | @@ -27986,6 +28022,10 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_ |
| 27986 | old_instruction->child = new_instruction; | 28022 | old_instruction->child = new_instruction; |
| 27987 | | 28023 | |
| 27988 | if (type_is_invalid(new_instruction->value->type)) { | 28024 | if (type_is_invalid(new_instruction->value->type)) { |
| | 28025 | if (ira->codegen->verbose_ir) { |
| | 28026 | fprintf(stderr, "-> (invalid)"); |
| | 28027 | } |
| | 28028 | |
| 27989 | if (new_exec->first_err_trace_msg != nullptr) { | 28029 | if (new_exec->first_err_trace_msg != nullptr) { |
| 27990 | ira->codegen->trace_err = new_exec->first_err_trace_msg; | 28030 | ira->codegen->trace_err = new_exec->first_err_trace_msg; |
| 27991 | } else { | 28031 | } else { |
| ... | @@ -27999,11 +28039,22 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_ | ... | @@ -27999,11 +28039,22 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_ |
| 27999 | old_instruction->source_node, buf_create_from_str("referenced here")); | 28039 | old_instruction->source_node, buf_create_from_str("referenced here")); |
| 28000 | } | 28040 | } |
| 28001 | return ira->codegen->builtin_types.entry_invalid; | 28041 | return ira->codegen->builtin_types.entry_invalid; |
| | 28042 | } else if (ira->codegen->verbose_ir) { |
| | 28043 | fprintf(stderr, "-> "); |
| | 28044 | if (instr_is_unreachable(new_instruction)) { |
| | 28045 | fprintf(stderr, "(noreturn)\n"); |
| | 28046 | } else { |
| | 28047 | ir_print_instruction(codegen, stderr, new_instruction, 0, IrPassGen); |
| | 28048 | } |
| 28002 | } | 28049 | } |
| 28003 | | 28050 | |
| 28004 | // unreachable instructions do their own control flow. | 28051 | // unreachable instructions do their own control flow. |
| 28005 | if (new_instruction->value->type->id == ZigTypeIdUnreachable) | 28052 | if (new_instruction->value->type->id == ZigTypeIdUnreachable) |
| 28006 | continue; | 28053 | continue; |
| | 28054 | } else { |
| | 28055 | if (ira->codegen->verbose_ir) { |
| | 28056 | fprintf(stderr, "-> (null"); |
| | 28057 | } |
| 28007 | } | 28058 | } |
| 28008 | | 28059 | |
| 28009 | ira->instruction_index += 1; | 28060 | ira->instruction_index += 1; |
| ... | @@ -28667,18 +28718,27 @@ Error ir_resolve_lazy(CodeGen *codegen, AstNode *source_node, ZigValue *val) { | ... | @@ -28667,18 +28718,27 @@ Error ir_resolve_lazy(CodeGen *codegen, AstNode *source_node, ZigValue *val) { |
| 28667 | return ErrorNone; | 28718 | return ErrorNone; |
| 28668 | } | 28719 | } |
| 28669 | | 28720 | |
| 28670 | void IrInstruction::dump() { | 28721 | void IrInstruction::src() { |
| 28671 | IrInstruction *inst = this; | 28722 | IrInstruction *inst = this; |
| 28672 | if (inst->source_node != nullptr) { | 28723 | if (inst->source_node != nullptr) { |
| 28673 | inst->source_node->src(); | 28724 | inst->source_node->src(); |
| 28674 | } else { | 28725 | } else { |
| 28675 | fprintf(stderr, "(null source node)\n"); | 28726 | fprintf(stderr, "(null source node)\n"); |
| 28676 | } | 28727 | } |
| | 28728 | } |
| | 28729 | |
| | 28730 | void IrInstruction::dump() { |
| | 28731 | IrInstruction *inst = this; |
| | 28732 | inst->src(); |
| 28677 | IrPass pass = (inst->child == nullptr) ? IrPassGen : IrPassSrc; | 28733 | IrPass pass = (inst->child == nullptr) ? IrPassGen : IrPassSrc; |
| 28678 | ir_print_instruction(inst->scope->codegen, stderr, inst, 0, pass); | 28734 | if (inst->scope == nullptr) { |
| 28679 | if (pass == IrPassSrc) { | 28735 | fprintf(stderr, "(null scope)\n"); |
| 28680 | fprintf(stderr, "-> "); | 28736 | } else { |
| 28681 | ir_print_instruction(inst->scope->codegen, stderr, inst->child, 0, IrPassGen); | 28737 | ir_print_instruction(inst->scope->codegen, stderr, inst, 0, pass); |
| | 28738 | if (pass == IrPassSrc) { |
| | 28739 | fprintf(stderr, "-> "); |
| | 28740 | ir_print_instruction(inst->scope->codegen, stderr, inst->child, 0, IrPassGen); |
| | 28741 | } |
| 28682 | } | 28742 | } |
| 28683 | } | 28743 | } |
| 28684 | | 28744 | |
| ... | @@ -28689,3 +28749,11 @@ void IrAnalyze::dump() { | ... | @@ -28689,3 +28749,11 @@ void IrAnalyze::dump() { |
| 28689 | ir_print_basic_block(this->codegen, stderr, this->new_irb.current_basic_block, 1, IrPassGen); | 28749 | ir_print_basic_block(this->codegen, stderr, this->new_irb.current_basic_block, 1, IrPassGen); |
| 28690 | } | 28750 | } |
| 28691 | } | 28751 | } |
| | 28752 | |
| | 28753 | void dbg_ir_break(const char *src_file, uint32_t line) { |
| | 28754 | dbg_ir_breakpoints_buf[dbg_ir_breakpoints_count] = {src_file, line}; |
| | 28755 | dbg_ir_breakpoints_count += 1; |
| | 28756 | } |
| | 28757 | void dbg_ir_clear(void) { |
| | 28758 | dbg_ir_breakpoints_count = 0; |
| | 28759 | } |