| ... | ... | @@ -41,6 +41,9 @@ struct IrAnalyze { |
| 41 | 41 | ZigList<IrInstruction *> src_implicit_return_type_list; |
| 42 | 42 | ZigList<IrSuspendPosition> resume_stack; |
| 43 | 43 | IrBasicBlock *const_predecessor_bb; |
| 44 | |
| 45 | // For the purpose of using in a debugger |
| 46 | void dump(); |
| 44 | 47 | }; |
| 45 | 48 | |
| 46 | 49 | enum ConstCastResultId { |
| ... | ... | @@ -350,6 +353,7 @@ static bool types_have_same_zig_comptime_repr(CodeGen *codegen, ZigType *expecte |
| 350 | 353 | case ZigTypeIdErrorSet: |
| 351 | 354 | case ZigTypeIdOpaque: |
| 352 | 355 | case ZigTypeIdAnyFrame: |
| 356 | case ZigTypeIdFn: |
| 353 | 357 | return true; |
| 354 | 358 | case ZigTypeIdFloat: |
| 355 | 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 | 365 | case ZigTypeIdErrorUnion: |
| 362 | 366 | case ZigTypeIdEnum: |
| 363 | 367 | case ZigTypeIdUnion: |
| 364 | | case ZigTypeIdFn: |
| 365 | 368 | case ZigTypeIdArgTuple: |
| 366 | 369 | case ZigTypeIdVector: |
| 367 | 370 | case ZigTypeIdFnFrame: |
| ... | ... | @@ -3941,6 +3944,7 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3941 | 3944 | scope_block->peer_parent = allocate<ResultLocPeerParent>(1, "ResultLocPeerParent"); |
| 3942 | 3945 | scope_block->peer_parent->base.id = ResultLocIdPeerParent; |
| 3943 | 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 | 3948 | scope_block->peer_parent->end_bb = scope_block->end_block; |
| 3945 | 3949 | scope_block->peer_parent->is_comptime = scope_block->is_comptime; |
| 3946 | 3950 | scope_block->peer_parent->parent = result_loc; |
| ... | ... | @@ -4195,6 +4199,7 @@ static ResultLocPeerParent *ir_build_result_peers(IrBuilder *irb, IrInstruction |
| 4195 | 4199 | ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1); |
| 4196 | 4200 | peer_parent->base.id = ResultLocIdPeerParent; |
| 4197 | 4201 | peer_parent->base.source_instruction = cond_br_inst; |
| 4202 | peer_parent->base.allow_write_through_const = parent->allow_write_through_const; |
| 4198 | 4203 | peer_parent->end_bb = end_block; |
| 4199 | 4204 | peer_parent->is_comptime = is_comptime; |
| 4200 | 4205 | peer_parent->parent = parent; |
| ... | ... | @@ -6388,6 +6393,7 @@ static ResultLocVar *ir_build_var_result_loc(IrBuilder *irb, IrInstruction *allo |
| 6388 | 6393 | ResultLocVar *result_loc_var = allocate<ResultLocVar>(1); |
| 6389 | 6394 | result_loc_var->base.id = ResultLocIdVar; |
| 6390 | 6395 | result_loc_var->base.source_instruction = alloca; |
| 6396 | result_loc_var->base.allow_write_through_const = true; |
| 6391 | 6397 | result_loc_var->var = var; |
| 6392 | 6398 | |
| 6393 | 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 | 6407 | ResultLocCast *result_loc_cast = allocate<ResultLocCast>(1); |
| 6402 | 6408 | result_loc_cast->base.id = ResultLocIdCast; |
| 6403 | 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 | 6411 | ir_ref_instruction(dest_type, irb->current_basic_block); |
| 6405 | 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 | 7588 | |
| 7582 | 7589 | ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1); |
| 7583 | 7590 | peer_parent->base.id = ResultLocIdPeerParent; |
| 7591 | peer_parent->base.allow_write_through_const = result_loc->allow_write_through_const; |
| 7584 | 7592 | peer_parent->end_bb = end_block; |
| 7585 | 7593 | peer_parent->is_comptime = is_comptime; |
| 7586 | 7594 | peer_parent->parent = result_loc; |
| ... | ... | @@ -13396,16 +13404,24 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 13396 | 13404 | return ir_analyze_undefined_to_anything(ira, source_instr, value, wanted_type); |
| 13397 | 13405 | } |
| 13398 | 13406 | |
| 13399 | | // T to ?E!T |
| 13400 | | if (wanted_type->id == ZigTypeIdOptional && wanted_type->data.maybe.child_type->id == ZigTypeIdErrorUnion && |
| 13401 | | actual_type->id != ZigTypeIdOptional) |
| 13402 | | { |
| 13407 | // T to ?U, where T implicitly casts to U |
| 13408 | if (wanted_type->id == ZigTypeIdOptional && actual_type->id != ZigTypeIdOptional) { |
| 13403 | 13409 | IrInstruction *cast1 = ir_implicit_cast2(ira, source_instr, value, wanted_type->data.maybe.child_type); |
| 13404 | 13410 | if (type_is_invalid(cast1->value->type)) |
| 13405 | 13411 | return ira->codegen->invalid_instruction; |
| 13406 | 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 | 13425 | ErrorMsg *parent_msg = ir_add_error_node(ira, source_instr->source_node, |
| 13410 | 13426 | buf_sprintf("expected type '%s', found '%s'", |
| 13411 | 13427 | buf_ptr(&wanted_type->name), |
| ... | ... | @@ -16046,7 +16062,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe |
| 16046 | 16062 | bool force_comptime; |
| 16047 | 16063 | if (!ir_resolve_comptime(ira, alloca_src->is_comptime->child, &force_comptime)) |
| 16048 | 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 | 16066 | value->value->special != ConstValSpecialRuntime && result_loc_var->var->gen_is_const); |
| 16051 | 16067 | |
| 16052 | 16068 | if (alloca_src->base.child == nullptr || is_comptime) { |
| ... | ... | @@ -16064,7 +16080,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe |
| 16064 | 16080 | alloca_gen = ir_analyze_alloca(ira, result_loc->source_instruction, value_type, align, |
| 16065 | 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 | 16084 | alloca_src->base.child->ref_count = 0; |
| 16069 | 16085 | } |
| 16070 | 16086 | alloca_src->base.child = alloca_gen; |
| ... | ... | @@ -16079,6 +16095,10 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe |
| 16079 | 16095 | return result_loc->resolved_loc; |
| 16080 | 16096 | } |
| 16081 | 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 | 16102 | if (!non_null_comptime) { |
| 16083 | 16103 | bool is_comptime = value != nullptr && value->value->special != ConstValSpecialRuntime; |
| 16084 | 16104 | if (is_comptime) |
| ... | ... | @@ -16121,10 +16141,10 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe |
| 16121 | 16141 | return result_loc->resolved_loc; |
| 16122 | 16142 | } |
| 16123 | 16143 | |
| 16124 | | bool is_comptime; |
| 16125 | | if (!ir_resolve_comptime(ira, peer_parent->is_comptime->child, &is_comptime)) |
| 16144 | bool is_condition_comptime; |
| 16145 | if (!ir_resolve_comptime(ira, peer_parent->is_comptime->child, &is_condition_comptime)) |
| 16126 | 16146 | return ira->codegen->invalid_instruction; |
| 16127 | | if (is_comptime) { |
| 16147 | if (is_condition_comptime) { |
| 16128 | 16148 | peer_parent->skipped = true; |
| 16129 | 16149 | if (non_null_comptime) { |
| 16130 | 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 | 16156 | if ((err = ir_result_has_type(ira, peer_parent->parent, &peer_parent_has_type))) |
| 16137 | 16157 | return ira->codegen->invalid_instruction; |
| 16138 | 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 | 16159 | peer_parent->skipped = true; |
| 16144 | 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); |
| 16146 | | if (parent_result_loc != nullptr) { |
| 16147 | | peer_parent->parent->written = true; |
| 16161 | value_type, value, force_runtime || !is_condition_comptime, true, true); |
| 16162 | if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value->type) || |
| 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 | 16173 | if (peer_parent->resolved_type == nullptr) { |
| ... | ... | @@ -16168,14 +16189,14 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe |
| 16168 | 16189 | { |
| 16169 | 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 | 16193 | parent_result_loc->value->special = ConstValSpecialRuntime; |
| 16173 | 16194 | result_loc->written = true; |
| 16174 | 16195 | result_loc->resolved_loc = parent_result_loc; |
| 16175 | 16196 | return result_loc->resolved_loc; |
| 16176 | 16197 | } |
| 16177 | 16198 | case ResultLocIdCast: { |
| 16178 | | if (value != nullptr && value->value->special != ConstValSpecialRuntime) |
| 16199 | if (value != nullptr && value->value->special != ConstValSpecialRuntime && !non_null_comptime) |
| 16179 | 16200 | return nullptr; |
| 16180 | 16201 | ResultLocCast *result_cast = reinterpret_cast<ResultLocCast *>(result_loc); |
| 16181 | 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 | 16225 | { |
| 16205 | 16226 | return parent_result_loc; |
| 16206 | 16227 | } |
| 16228 | |
| 16207 | 16229 | ZigType *parent_ptr_type = parent_result_loc->value->type; |
| 16208 | 16230 | assert(parent_ptr_type->id == ZigTypeIdPointer); |
| 16209 | 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 | 16376 | { |
| 16355 | 16377 | result_loc_pass1->written = false; |
| 16356 | 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 | 16380 | if (value_type->id == ZigTypeIdErrorSet) { |
| 16359 | 16381 | return ir_analyze_unwrap_err_code(ira, suspend_source_instr, result_loc, true); |
| 16360 | 16382 | } else { |
| ... | ... | @@ -28238,3 +28260,11 @@ void IrInstruction::dump() { |
| 28238 | 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 | } |