| ... | @@ -41,6 +41,9 @@ struct IrAnalyze { | ... | @@ -41,6 +41,9 @@ struct IrAnalyze { |
| 41 | ZigList<IrInstruction *> src_implicit_return_type_list; | 41 | ZigList<IrInstruction *> src_implicit_return_type_list; |
| 42 | ZigList<IrSuspendPosition> resume_stack; | 42 | ZigList<IrSuspendPosition> resume_stack; |
| 43 | IrBasicBlock *const_predecessor_bb; | 43 | IrBasicBlock *const_predecessor_bb; |
| | 44 | |
| | 45 | // For the purpose of using in a debugger |
| | 46 | void dump(); |
| 44 | }; | 47 | }; |
| 45 | | 48 | |
| 46 | enum ConstCastResultId { | 49 | enum ConstCastResultId { |
| ... | @@ -350,6 +353,7 @@ static bool types_have_same_zig_comptime_repr(CodeGen *codegen, ZigType *expecte | ... | @@ -350,6 +353,7 @@ static bool types_have_same_zig_comptime_repr(CodeGen *codegen, ZigType *expecte |
| 350 | case ZigTypeIdErrorSet: | 353 | case ZigTypeIdErrorSet: |
| 351 | case ZigTypeIdOpaque: | 354 | case ZigTypeIdOpaque: |
| 352 | case ZigTypeIdAnyFrame: | 355 | case ZigTypeIdAnyFrame: |
| | 356 | case ZigTypeIdFn: |
| 353 | return true; | 357 | return true; |
| 354 | case ZigTypeIdFloat: | 358 | case ZigTypeIdFloat: |
| 355 | return expected->data.floating.bit_count == actual->data.floating.bit_count; | 359 | return expected->data.floating.bit_count == actual->data.floating.bit_count; |
| ... | @@ -361,7 +365,6 @@ static bool types_have_same_zig_comptime_repr(CodeGen *codegen, ZigType *expecte | ... | @@ -361,7 +365,6 @@ static bool types_have_same_zig_comptime_repr(CodeGen *codegen, ZigType *expecte |
| 361 | case ZigTypeIdErrorUnion: | 365 | case ZigTypeIdErrorUnion: |
| 362 | case ZigTypeIdEnum: | 366 | case ZigTypeIdEnum: |
| 363 | case ZigTypeIdUnion: | 367 | case ZigTypeIdUnion: |
| 364 | case ZigTypeIdFn: | | |
| 365 | case ZigTypeIdArgTuple: | 368 | case ZigTypeIdArgTuple: |
| 366 | case ZigTypeIdVector: | 369 | case ZigTypeIdVector: |
| 367 | case ZigTypeIdFnFrame: | 370 | case ZigTypeIdFnFrame: |
| ... | @@ -3941,6 +3944,7 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode | ... | @@ -3941,6 +3944,7 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3941 | scope_block->peer_parent = allocate<ResultLocPeerParent>(1, "ResultLocPeerParent"); | 3944 | scope_block->peer_parent = allocate<ResultLocPeerParent>(1, "ResultLocPeerParent"); |
| 3942 | scope_block->peer_parent->base.id = ResultLocIdPeerParent; | 3945 | scope_block->peer_parent->base.id = ResultLocIdPeerParent; |
| 3943 | scope_block->peer_parent->base.source_instruction = scope_block->is_comptime; | 3946 | scope_block->peer_parent->base.source_instruction = scope_block->is_comptime; |
| | 3947 | scope_block->peer_parent->base.allow_write_through_const = result_loc->allow_write_through_const; |
| 3944 | scope_block->peer_parent->end_bb = scope_block->end_block; | 3948 | scope_block->peer_parent->end_bb = scope_block->end_block; |
| 3945 | scope_block->peer_parent->is_comptime = scope_block->is_comptime; | 3949 | scope_block->peer_parent->is_comptime = scope_block->is_comptime; |
| 3946 | scope_block->peer_parent->parent = result_loc; | 3950 | scope_block->peer_parent->parent = result_loc; |
| ... | @@ -4195,6 +4199,7 @@ static ResultLocPeerParent *ir_build_result_peers(IrBuilder *irb, IrInstruction | ... | @@ -4195,6 +4199,7 @@ static ResultLocPeerParent *ir_build_result_peers(IrBuilder *irb, IrInstruction |
| 4195 | ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1); | 4199 | ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1); |
| 4196 | peer_parent->base.id = ResultLocIdPeerParent; | 4200 | peer_parent->base.id = ResultLocIdPeerParent; |
| 4197 | peer_parent->base.source_instruction = cond_br_inst; | 4201 | peer_parent->base.source_instruction = cond_br_inst; |
| | 4202 | peer_parent->base.allow_write_through_const = parent->allow_write_through_const; |
| 4198 | peer_parent->end_bb = end_block; | 4203 | peer_parent->end_bb = end_block; |
| 4199 | peer_parent->is_comptime = is_comptime; | 4204 | peer_parent->is_comptime = is_comptime; |
| 4200 | peer_parent->parent = parent; | 4205 | peer_parent->parent = parent; |
| ... | @@ -6388,6 +6393,7 @@ static ResultLocVar *ir_build_var_result_loc(IrBuilder *irb, IrInstruction *allo | ... | @@ -6388,6 +6393,7 @@ static ResultLocVar *ir_build_var_result_loc(IrBuilder *irb, IrInstruction *allo |
| 6388 | ResultLocVar *result_loc_var = allocate<ResultLocVar>(1); | 6393 | ResultLocVar *result_loc_var = allocate<ResultLocVar>(1); |
| 6389 | result_loc_var->base.id = ResultLocIdVar; | 6394 | result_loc_var->base.id = ResultLocIdVar; |
| 6390 | result_loc_var->base.source_instruction = alloca; | 6395 | result_loc_var->base.source_instruction = alloca; |
| | 6396 | result_loc_var->base.allow_write_through_const = true; |
| 6391 | result_loc_var->var = var; | 6397 | result_loc_var->var = var; |
| 6392 | | 6398 | |
| 6393 | ir_build_reset_result(irb, alloca->scope, alloca->source_node, &result_loc_var->base); | 6399 | ir_build_reset_result(irb, alloca->scope, alloca->source_node, &result_loc_var->base); |
| ... | @@ -6401,6 +6407,7 @@ static ResultLocCast *ir_build_cast_result_loc(IrBuilder *irb, IrInstruction *de | ... | @@ -6401,6 +6407,7 @@ static ResultLocCast *ir_build_cast_result_loc(IrBuilder *irb, IrInstruction *de |
| 6401 | ResultLocCast *result_loc_cast = allocate<ResultLocCast>(1); | 6407 | ResultLocCast *result_loc_cast = allocate<ResultLocCast>(1); |
| 6402 | result_loc_cast->base.id = ResultLocIdCast; | 6408 | result_loc_cast->base.id = ResultLocIdCast; |
| 6403 | result_loc_cast->base.source_instruction = dest_type; | 6409 | result_loc_cast->base.source_instruction = dest_type; |
| | 6410 | result_loc_cast->base.allow_write_through_const = parent_result_loc->allow_write_through_const; |
| 6404 | ir_ref_instruction(dest_type, irb->current_basic_block); | 6411 | ir_ref_instruction(dest_type, irb->current_basic_block); |
| 6405 | result_loc_cast->parent = parent_result_loc; | 6412 | result_loc_cast->parent = parent_result_loc; |
| 6406 | | 6413 | |
| ... | @@ -7581,6 +7588,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -7581,6 +7588,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 7581 | | 7588 | |
| 7582 | ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1); | 7589 | ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1); |
| 7583 | peer_parent->base.id = ResultLocIdPeerParent; | 7590 | peer_parent->base.id = ResultLocIdPeerParent; |
| | 7591 | peer_parent->base.allow_write_through_const = result_loc->allow_write_through_const; |
| 7584 | peer_parent->end_bb = end_block; | 7592 | peer_parent->end_bb = end_block; |
| 7585 | peer_parent->is_comptime = is_comptime; | 7593 | peer_parent->is_comptime = is_comptime; |
| 7586 | peer_parent->parent = result_loc; | 7594 | peer_parent->parent = result_loc; |
| ... | @@ -13396,16 +13404,24 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -13396,16 +13404,24 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 13396 | return ir_analyze_undefined_to_anything(ira, source_instr, value, wanted_type); | 13404 | return ir_analyze_undefined_to_anything(ira, source_instr, value, wanted_type); |
| 13397 | } | 13405 | } |
| 13398 | | 13406 | |
| 13399 | // T to ?E!T | 13407 | // T to ?U, where T implicitly casts to U |
| 13400 | if (wanted_type->id == ZigTypeIdOptional && wanted_type->data.maybe.child_type->id == ZigTypeIdErrorUnion && | 13408 | if (wanted_type->id == ZigTypeIdOptional && actual_type->id != ZigTypeIdOptional) { |
| 13401 | actual_type->id != ZigTypeIdOptional) | | |
| 13402 | { | | |
| 13403 | IrInstruction *cast1 = ir_implicit_cast2(ira, source_instr, value, wanted_type->data.maybe.child_type); | 13409 | IrInstruction *cast1 = ir_implicit_cast2(ira, source_instr, value, wanted_type->data.maybe.child_type); |
| 13404 | if (type_is_invalid(cast1->value->type)) | 13410 | if (type_is_invalid(cast1->value->type)) |
| 13405 | return ira->codegen->invalid_instruction; | 13411 | return ira->codegen->invalid_instruction; |
| 13406 | return ir_implicit_cast2(ira, source_instr, cast1, wanted_type); | 13412 | return ir_implicit_cast2(ira, source_instr, cast1, wanted_type); |
| 13407 | } | 13413 | } |
| 13408 | | 13414 | |
| | 13415 | // T to E!U, where T implicitly casts to U |
| | 13416 | if (wanted_type->id == ZigTypeIdErrorUnion && actual_type->id != ZigTypeIdErrorUnion && |
| | 13417 | actual_type->id != ZigTypeIdErrorSet) |
| | 13418 | { |
| | 13419 | IrInstruction *cast1 = ir_implicit_cast2(ira, source_instr, value, wanted_type->data.error_union.payload_type); |
| | 13420 | if (type_is_invalid(cast1->value->type)) |
| | 13421 | return ira->codegen->invalid_instruction; |
| | 13422 | return ir_implicit_cast2(ira, source_instr, cast1, wanted_type); |
| | 13423 | } |
| | 13424 | |
| 13409 | ErrorMsg *parent_msg = ir_add_error_node(ira, source_instr->source_node, | 13425 | ErrorMsg *parent_msg = ir_add_error_node(ira, source_instr->source_node, |
| 13410 | buf_sprintf("expected type '%s', found '%s'", | 13426 | buf_sprintf("expected type '%s', found '%s'", |
| 13411 | buf_ptr(&wanted_type->name), | 13427 | buf_ptr(&wanted_type->name), |
| ... | @@ -16046,7 +16062,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe | ... | @@ -16046,7 +16062,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe |
| 16046 | bool force_comptime; | 16062 | bool force_comptime; |
| 16047 | if (!ir_resolve_comptime(ira, alloca_src->is_comptime->child, &force_comptime)) | 16063 | if (!ir_resolve_comptime(ira, alloca_src->is_comptime->child, &force_comptime)) |
| 16048 | return ira->codegen->invalid_instruction; | 16064 | return ira->codegen->invalid_instruction; |
| 16049 | bool is_comptime = force_comptime || (value != nullptr && | 16065 | bool is_comptime = force_comptime || (!force_runtime && value != nullptr && |
| 16050 | value->value->special != ConstValSpecialRuntime && result_loc_var->var->gen_is_const); | 16066 | value->value->special != ConstValSpecialRuntime && result_loc_var->var->gen_is_const); |
| 16051 | | 16067 | |
| 16052 | if (alloca_src->base.child == nullptr || is_comptime) { | 16068 | if (alloca_src->base.child == nullptr || is_comptime) { |
| ... | @@ -16064,7 +16080,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe | ... | @@ -16064,7 +16080,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe |
| 16064 | alloca_gen = ir_analyze_alloca(ira, result_loc->source_instruction, value_type, align, | 16080 | alloca_gen = ir_analyze_alloca(ira, result_loc->source_instruction, value_type, align, |
| 16065 | alloca_src->name_hint, force_comptime); | 16081 | alloca_src->name_hint, force_comptime); |
| 16066 | } | 16082 | } |
| 16067 | if (alloca_src->base.child != nullptr) { | 16083 | if (alloca_src->base.child != nullptr && !result_loc->written) { |
| 16068 | alloca_src->base.child->ref_count = 0; | 16084 | alloca_src->base.child->ref_count = 0; |
| 16069 | } | 16085 | } |
| 16070 | alloca_src->base.child = alloca_gen; | 16086 | alloca_src->base.child = alloca_gen; |
| ... | @@ -16079,6 +16095,10 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe | ... | @@ -16079,6 +16095,10 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe |
| 16079 | return result_loc->resolved_loc; | 16095 | return result_loc->resolved_loc; |
| 16080 | } | 16096 | } |
| 16081 | case ResultLocIdReturn: { | 16097 | case ResultLocIdReturn: { |
| | 16098 | if (value != nullptr) { |
| | 16099 | reinterpret_cast<ResultLocReturn *>(result_loc)->implicit_return_type_done = true; |
| | 16100 | ira->src_implicit_return_type_list.append(value); |
| | 16101 | } |
| 16082 | if (!non_null_comptime) { | 16102 | if (!non_null_comptime) { |
| 16083 | bool is_comptime = value != nullptr && value->value->special != ConstValSpecialRuntime; | 16103 | bool is_comptime = value != nullptr && value->value->special != ConstValSpecialRuntime; |
| 16084 | if (is_comptime) | 16104 | if (is_comptime) |
| ... | @@ -16121,10 +16141,10 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe | ... | @@ -16121,10 +16141,10 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe |
| 16121 | return result_loc->resolved_loc; | 16141 | return result_loc->resolved_loc; |
| 16122 | } | 16142 | } |
| 16123 | | 16143 | |
| 16124 | bool is_comptime; | 16144 | bool is_condition_comptime; |
| 16125 | if (!ir_resolve_comptime(ira, peer_parent->is_comptime->child, &is_comptime)) | 16145 | if (!ir_resolve_comptime(ira, peer_parent->is_comptime->child, &is_condition_comptime)) |
| 16126 | return ira->codegen->invalid_instruction; | 16146 | return ira->codegen->invalid_instruction; |
| 16127 | if (is_comptime) { | 16147 | if (is_condition_comptime) { |
| 16128 | peer_parent->skipped = true; | 16148 | peer_parent->skipped = true; |
| 16129 | if (non_null_comptime) { | 16149 | if (non_null_comptime) { |
| 16130 | return ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, | 16150 | return ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, |
| ... | @@ -16136,17 +16156,18 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe | ... | @@ -16136,17 +16156,18 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe |
| 16136 | if ((err = ir_result_has_type(ira, peer_parent->parent, &peer_parent_has_type))) | 16156 | if ((err = ir_result_has_type(ira, peer_parent->parent, &peer_parent_has_type))) |
| 16137 | return ira->codegen->invalid_instruction; | 16157 | return ira->codegen->invalid_instruction; |
| 16138 | if (peer_parent_has_type) { | 16158 | if (peer_parent_has_type) { |
| 16139 | if (peer_parent->parent->id == ResultLocIdReturn && value != nullptr) { | | |
| 16140 | reinterpret_cast<ResultLocReturn *>(peer_parent->parent)->implicit_return_type_done = true; | | |
| 16141 | ira->src_implicit_return_type_list.append(value); | | |
| 16142 | } | | |
| 16143 | peer_parent->skipped = true; | 16159 | peer_parent->skipped = true; |
| 16144 | IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, | 16160 | IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, |
| 16145 | value_type, value, force_runtime || !is_comptime, true, true); | 16161 | value_type, value, force_runtime || !is_condition_comptime, true, true); |
| 16146 | if (parent_result_loc != nullptr) { | 16162 | if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value->type) || |
| 16147 | peer_parent->parent->written = true; | 16163 | parent_result_loc->value->type->id == ZigTypeIdUnreachable) |
| | 16164 | { |
| | 16165 | return parent_result_loc; |
| 16148 | } | 16166 | } |
| 16149 | return parent_result_loc; | 16167 | peer_parent->parent->written = true; |
| | 16168 | result_loc->written = true; |
| | 16169 | result_loc->resolved_loc = parent_result_loc; |
| | 16170 | return result_loc->resolved_loc; |
| 16150 | } | 16171 | } |
| 16151 | | 16172 | |
| 16152 | if (peer_parent->resolved_type == nullptr) { | 16173 | if (peer_parent->resolved_type == nullptr) { |
| ... | @@ -16168,14 +16189,14 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe | ... | @@ -16168,14 +16189,14 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe |
| 16168 | { | 16189 | { |
| 16169 | return parent_result_loc; | 16190 | return parent_result_loc; |
| 16170 | } | 16191 | } |
| 16171 | // because is_comptime is false, we mark this a runtime pointer | 16192 | // because is_condition_comptime is false, we mark this a runtime pointer |
| 16172 | parent_result_loc->value->special = ConstValSpecialRuntime; | 16193 | parent_result_loc->value->special = ConstValSpecialRuntime; |
| 16173 | result_loc->written = true; | 16194 | result_loc->written = true; |
| 16174 | result_loc->resolved_loc = parent_result_loc; | 16195 | result_loc->resolved_loc = parent_result_loc; |
| 16175 | return result_loc->resolved_loc; | 16196 | return result_loc->resolved_loc; |
| 16176 | } | 16197 | } |
| 16177 | case ResultLocIdCast: { | 16198 | case ResultLocIdCast: { |
| 16178 | if (value != nullptr && value->value->special != ConstValSpecialRuntime) | 16199 | if (value != nullptr && value->value->special != ConstValSpecialRuntime && !non_null_comptime) |
| 16179 | return nullptr; | 16200 | return nullptr; |
| 16180 | ResultLocCast *result_cast = reinterpret_cast<ResultLocCast *>(result_loc); | 16201 | ResultLocCast *result_cast = reinterpret_cast<ResultLocCast *>(result_loc); |
| 16181 | ZigType *dest_type = ir_resolve_type(ira, result_cast->base.source_instruction->child); | 16202 | ZigType *dest_type = ir_resolve_type(ira, result_cast->base.source_instruction->child); |
| ... | @@ -16204,6 +16225,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe | ... | @@ -16204,6 +16225,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe |
| 16204 | { | 16225 | { |
| 16205 | return parent_result_loc; | 16226 | return parent_result_loc; |
| 16206 | } | 16227 | } |
| | 16228 | |
| 16207 | ZigType *parent_ptr_type = parent_result_loc->value->type; | 16229 | ZigType *parent_ptr_type = parent_result_loc->value->type; |
| 16208 | assert(parent_ptr_type->id == ZigTypeIdPointer); | 16230 | assert(parent_ptr_type->id == ZigTypeIdPointer); |
| 16209 | if ((err = type_resolve(ira->codegen, parent_ptr_type->data.pointer.child_type, | 16231 | if ((err = type_resolve(ira->codegen, parent_ptr_type->data.pointer.child_type, |
| ... | @@ -16354,7 +16376,7 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s | ... | @@ -16354,7 +16376,7 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s |
| 16354 | { | 16376 | { |
| 16355 | result_loc_pass1->written = false; | 16377 | result_loc_pass1->written = false; |
| 16356 | return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, result_loc, false, true); | 16378 | return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, result_loc, false, true); |
| 16357 | } else if (actual_elem_type->id == ZigTypeIdErrorUnion && value_type->id != ZigTypeIdErrorUnion) { | 16379 | } else if (actual_elem_type->id == ZigTypeIdErrorUnion && value_type->id != ZigTypeIdErrorUnion && value == nullptr) { |
| 16358 | if (value_type->id == ZigTypeIdErrorSet) { | 16380 | if (value_type->id == ZigTypeIdErrorSet) { |
| 16359 | return ir_analyze_unwrap_err_code(ira, suspend_source_instr, result_loc, true); | 16381 | return ir_analyze_unwrap_err_code(ira, suspend_source_instr, result_loc, true); |
| 16360 | } else { | 16382 | } else { |
| ... | @@ -28238,3 +28260,11 @@ void IrInstruction::dump() { | ... | @@ -28238,3 +28260,11 @@ void IrInstruction::dump() { |
| 28238 | ir_print_instruction(inst->scope->codegen, stderr, inst->child, 0, IrPassGen); | 28260 | ir_print_instruction(inst->scope->codegen, stderr, inst->child, 0, IrPassGen); |
| 28239 | } | 28261 | } |
| 28240 | } | 28262 | } |
| | 28263 | |
| | 28264 | void IrAnalyze::dump() { |
| | 28265 | ir_print(this->codegen, stderr, this->new_irb.exec, 0, IrPassGen); |
| | 28266 | if (this->new_irb.current_basic_block != nullptr) { |
| | 28267 | fprintf(stderr, "Current basic block:\n"); |
| | 28268 | ir_print_basic_block(this->codegen, stderr, this->new_irb.current_basic_block, 1, IrPassGen); |
| | 28269 | } |
| | 28270 | } |