| ... | @@ -200,6 +200,7 @@ static T *ir_create_instruction(IrExecutable *exec, AstNode *source_node) { | ... | @@ -200,6 +200,7 @@ static T *ir_create_instruction(IrExecutable *exec, AstNode *source_node) { |
| 200 | | 200 | |
| 201 | template<typename T> | 201 | template<typename T> |
| 202 | static T *ir_build_instruction(IrBuilder *irb, AstNode *source_node) { | 202 | static T *ir_build_instruction(IrBuilder *irb, AstNode *source_node) { |
| | 203 | assert(source_node); |
| 203 | T *special_instruction = ir_create_instruction<T>(irb->exec, source_node); | 204 | T *special_instruction = ir_create_instruction<T>(irb->exec, source_node); |
| 204 | ir_instruction_append(irb->current_basic_block, &special_instruction->base); | 205 | ir_instruction_append(irb->current_basic_block, &special_instruction->base); |
| 205 | return special_instruction; | 206 | return special_instruction; |
| ... | @@ -220,7 +221,7 @@ static IrInstruction *ir_build_cast(IrBuilder *irb, AstNode *source_node, IrInst | ... | @@ -220,7 +221,7 @@ static IrInstruction *ir_build_cast(IrBuilder *irb, AstNode *source_node, IrInst |
| 220 | } | 221 | } |
| 221 | | 222 | |
| 222 | static IrInstruction *ir_build_cond_br(IrBuilder *irb, AstNode *source_node, IrInstruction *condition, | 223 | static IrInstruction *ir_build_cond_br(IrBuilder *irb, AstNode *source_node, IrInstruction *condition, |
| 223 | IrBasicBlock *then_block, IrBasicBlock *else_block) | 224 | IrBasicBlock *then_block, IrBasicBlock *else_block, bool is_inline) |
| 224 | { | 225 | { |
| 225 | IrInstructionCondBr *cond_br_instruction = ir_build_instruction<IrInstructionCondBr>(irb, source_node); | 226 | IrInstructionCondBr *cond_br_instruction = ir_build_instruction<IrInstructionCondBr>(irb, source_node); |
| 226 | cond_br_instruction->base.type_entry = irb->codegen->builtin_types.entry_unreachable; | 227 | cond_br_instruction->base.type_entry = irb->codegen->builtin_types.entry_unreachable; |
| ... | @@ -228,6 +229,7 @@ static IrInstruction *ir_build_cond_br(IrBuilder *irb, AstNode *source_node, IrI | ... | @@ -228,6 +229,7 @@ static IrInstruction *ir_build_cond_br(IrBuilder *irb, AstNode *source_node, IrI |
| 228 | cond_br_instruction->condition = condition; | 229 | cond_br_instruction->condition = condition; |
| 229 | cond_br_instruction->then_block = then_block; | 230 | cond_br_instruction->then_block = then_block; |
| 230 | cond_br_instruction->else_block = else_block; | 231 | cond_br_instruction->else_block = else_block; |
| | 232 | cond_br_instruction->is_inline = is_inline; |
| 231 | | 233 | |
| 232 | ir_ref_instruction(condition); | 234 | ir_ref_instruction(condition); |
| 233 | ir_ref_bb(then_block); | 235 | ir_ref_bb(then_block); |
| ... | @@ -237,10 +239,10 @@ static IrInstruction *ir_build_cond_br(IrBuilder *irb, AstNode *source_node, IrI | ... | @@ -237,10 +239,10 @@ static IrInstruction *ir_build_cond_br(IrBuilder *irb, AstNode *source_node, IrI |
| 237 | } | 239 | } |
| 238 | | 240 | |
| 239 | static IrInstruction *ir_build_cond_br_from(IrBuilder *irb, IrInstruction *old_instruction, | 241 | static IrInstruction *ir_build_cond_br_from(IrBuilder *irb, IrInstruction *old_instruction, |
| 240 | IrInstruction *condition, IrBasicBlock *then_block, IrBasicBlock *else_block) | 242 | IrInstruction *condition, IrBasicBlock *then_block, IrBasicBlock *else_block, bool is_inline) |
| 241 | { | 243 | { |
| 242 | IrInstruction *new_instruction = ir_build_cond_br(irb, old_instruction->source_node, | 244 | IrInstruction *new_instruction = ir_build_cond_br(irb, old_instruction->source_node, |
| 243 | condition, then_block, else_block); | 245 | condition, then_block, else_block, is_inline); |
| 244 | ir_link_new_instruction(new_instruction, old_instruction); | 246 | ir_link_new_instruction(new_instruction, old_instruction); |
| 245 | return new_instruction; | 247 | return new_instruction; |
| 246 | } | 248 | } |
| ... | @@ -517,22 +519,23 @@ static IrInstruction *ir_build_phi_from(IrBuilder *irb, IrInstruction *old_instr | ... | @@ -517,22 +519,23 @@ static IrInstruction *ir_build_phi_from(IrBuilder *irb, IrInstruction *old_instr |
| 517 | return new_instruction; | 519 | return new_instruction; |
| 518 | } | 520 | } |
| 519 | | 521 | |
| 520 | static IrInstruction *ir_build_br(IrBuilder *irb, AstNode *source_node, IrBasicBlock *dest_block) { | 522 | static IrInstruction *ir_build_br(IrBuilder *irb, AstNode *source_node, IrBasicBlock *dest_block, bool is_inline) { |
| 521 | IrInstructionBr *br_instruction = ir_build_instruction<IrInstructionBr>(irb, source_node); | 523 | IrInstructionBr *br_instruction = ir_build_instruction<IrInstructionBr>(irb, source_node); |
| 522 | br_instruction->base.type_entry = irb->codegen->builtin_types.entry_unreachable; | 524 | br_instruction->base.type_entry = irb->codegen->builtin_types.entry_unreachable; |
| 523 | br_instruction->base.static_value.ok = true; | 525 | br_instruction->base.static_value.ok = true; |
| 524 | br_instruction->dest_block = dest_block; | 526 | br_instruction->dest_block = dest_block; |
| | 527 | br_instruction->is_inline = is_inline; |
| 525 | | 528 | |
| 526 | ir_ref_bb(dest_block); | 529 | ir_ref_bb(dest_block); |
| 527 | | 530 | |
| 528 | return &br_instruction->base; | 531 | return &br_instruction->base; |
| 529 | } | 532 | } |
| 530 | | 533 | |
| 531 | //static IrInstruction *ir_build_br_from(IrBuilder *irb, IrInstruction *old_instruction, IrBasicBlock *dest_block) { | 534 | static IrInstruction *ir_build_br_from(IrBuilder *irb, IrInstruction *old_instruction, IrBasicBlock *dest_block) { |
| 532 | // IrInstruction *new_instruction = ir_build_br(irb, old_instruction->source_node, dest_block); | 535 | IrInstruction *new_instruction = ir_build_br(irb, old_instruction->source_node, dest_block, false); |
| 533 | // ir_link_new_instruction(new_instruction, old_instruction); | 536 | ir_link_new_instruction(new_instruction, old_instruction); |
| 534 | // return new_instruction; | 537 | return new_instruction; |
| 535 | //} | 538 | } |
| 536 | | 539 | |
| 537 | static IrInstruction *ir_build_un_op(IrBuilder *irb, AstNode *source_node, IrUnOp op_id, IrInstruction *value) { | 540 | static IrInstruction *ir_build_un_op(IrBuilder *irb, AstNode *source_node, IrUnOp op_id, IrInstruction *value) { |
| 538 | IrInstructionUnOp *br_instruction = ir_build_instruction<IrInstructionUnOp>(irb, source_node); | 541 | IrInstructionUnOp *br_instruction = ir_build_instruction<IrInstructionUnOp>(irb, source_node); |
| ... | @@ -634,7 +637,7 @@ static IrInstruction *ir_build_var_decl(IrBuilder *irb, AstNode *source_node, | ... | @@ -634,7 +637,7 @@ static IrInstruction *ir_build_var_decl(IrBuilder *irb, AstNode *source_node, |
| 634 | decl_var_instruction->var_type = var_type; | 637 | decl_var_instruction->var_type = var_type; |
| 635 | decl_var_instruction->init_value = init_value; | 638 | decl_var_instruction->init_value = init_value; |
| 636 | | 639 | |
| 637 | ir_ref_instruction(var_type); | 640 | if (var_type) ir_ref_instruction(var_type); |
| 638 | ir_ref_instruction(init_value); | 641 | ir_ref_instruction(init_value); |
| 639 | | 642 | |
| 640 | return &decl_var_instruction->base; | 643 | return &decl_var_instruction->base; |
| ... | @@ -775,13 +778,14 @@ static void ir_set_cursor_at_end(IrBuilder *irb, IrBasicBlock *basic_block) { | ... | @@ -775,13 +778,14 @@ static void ir_set_cursor_at_end(IrBuilder *irb, IrBasicBlock *basic_block) { |
| 775 | } | 778 | } |
| 776 | | 779 | |
| 777 | static VariableTableEntry *add_local_var(CodeGen *codegen, AstNode *node, BlockContext *scope, | 780 | static VariableTableEntry *add_local_var(CodeGen *codegen, AstNode *node, BlockContext *scope, |
| 778 | Buf *name, bool is_const, bool is_shadowable) | 781 | Buf *name, bool src_is_const, bool gen_is_const, bool is_shadowable, bool is_inline) |
| 779 | { | 782 | { |
| 780 | VariableTableEntry *variable_entry = allocate<VariableTableEntry>(1); | 783 | VariableTableEntry *variable_entry = allocate<VariableTableEntry>(1); |
| 781 | variable_entry->block_context = scope; | 784 | variable_entry->block_context = scope; |
| 782 | variable_entry->import = node->owner; | 785 | variable_entry->import = node->owner; |
| 783 | variable_entry->shadowable = is_shadowable; | 786 | variable_entry->shadowable = is_shadowable; |
| 784 | variable_entry->mem_slot_index = SIZE_MAX; | 787 | variable_entry->mem_slot_index = SIZE_MAX; |
| | 788 | variable_entry->is_inline = is_inline; |
| 785 | | 789 | |
| 786 | if (name) { | 790 | if (name) { |
| 787 | buf_init_from_buf(&variable_entry->name, name); | 791 | buf_init_from_buf(&variable_entry->name, name); |
| ... | @@ -817,7 +821,8 @@ static VariableTableEntry *add_local_var(CodeGen *codegen, AstNode *node, BlockC | ... | @@ -817,7 +821,8 @@ static VariableTableEntry *add_local_var(CodeGen *codegen, AstNode *node, BlockC |
| 817 | buf_init_from_str(&variable_entry->name, "_anon"); | 821 | buf_init_from_str(&variable_entry->name, "_anon"); |
| 818 | } | 822 | } |
| 819 | | 823 | |
| 820 | variable_entry->is_const = is_const; | 824 | variable_entry->src_is_const = src_is_const; |
| | 825 | variable_entry->gen_is_const = gen_is_const; |
| 821 | variable_entry->decl_node = node; | 826 | variable_entry->decl_node = node; |
| 822 | | 827 | |
| 823 | return variable_entry; | 828 | return variable_entry; |
| ... | @@ -825,10 +830,12 @@ static VariableTableEntry *add_local_var(CodeGen *codegen, AstNode *node, BlockC | ... | @@ -825,10 +830,12 @@ static VariableTableEntry *add_local_var(CodeGen *codegen, AstNode *node, BlockC |
| 825 | | 830 | |
| 826 | // Set name to nullptr to make the variable anonymous (not visible to programmer). | 831 | // Set name to nullptr to make the variable anonymous (not visible to programmer). |
| 827 | static VariableTableEntry *ir_add_local_var(IrBuilder *irb, AstNode *node, BlockContext *scope, Buf *name, | 832 | static VariableTableEntry *ir_add_local_var(IrBuilder *irb, AstNode *node, BlockContext *scope, Buf *name, |
| 828 | bool is_const, bool is_shadowable) | 833 | bool src_is_const, bool gen_is_const, bool is_shadowable, bool is_inline) |
| 829 | { | 834 | { |
| 830 | VariableTableEntry *var = add_local_var(irb->codegen, node, scope, name, is_const, is_shadowable); | 835 | VariableTableEntry *var = add_local_var(irb->codegen, node, scope, name, |
| 831 | var->mem_slot_index = exec_next_mem_slot(irb->exec); | 836 | src_is_const, gen_is_const, is_shadowable, is_inline); |
| | 837 | if (is_inline || gen_is_const) |
| | 838 | var->mem_slot_index = exec_next_mem_slot(irb->exec); |
| 832 | return var; | 839 | return var; |
| 833 | } | 840 | } |
| 834 | | 841 | |
| ... | @@ -1189,14 +1196,14 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, AstNode *node) { | ... | @@ -1189,14 +1196,14 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, AstNode *node) { |
| 1189 | IrBasicBlock *else_block = ir_build_basic_block(irb, "Else"); | 1196 | IrBasicBlock *else_block = ir_build_basic_block(irb, "Else"); |
| 1190 | IrBasicBlock *endif_block = ir_build_basic_block(irb, "EndIf"); | 1197 | IrBasicBlock *endif_block = ir_build_basic_block(irb, "EndIf"); |
| 1191 | | 1198 | |
| 1192 | ir_build_cond_br(irb, condition->source_node, condition, then_block, else_block); | 1199 | ir_build_cond_br(irb, condition->source_node, condition, then_block, else_block, false); |
| 1193 | | 1200 | |
| 1194 | ir_set_cursor_at_end(irb, then_block); | 1201 | ir_set_cursor_at_end(irb, then_block); |
| 1195 | IrInstruction *then_expr_result = ir_gen_node(irb, then_node, node->block_context); | 1202 | IrInstruction *then_expr_result = ir_gen_node(irb, then_node, node->block_context); |
| 1196 | if (then_expr_result == irb->codegen->invalid_instruction) | 1203 | if (then_expr_result == irb->codegen->invalid_instruction) |
| 1197 | return then_expr_result; | 1204 | return then_expr_result; |
| 1198 | IrBasicBlock *after_then_block = irb->current_basic_block; | 1205 | IrBasicBlock *after_then_block = irb->current_basic_block; |
| 1199 | ir_build_br(irb, node, endif_block); | 1206 | ir_build_br(irb, node, endif_block, false); |
| 1200 | | 1207 | |
| 1201 | ir_set_cursor_at_end(irb, else_block); | 1208 | ir_set_cursor_at_end(irb, else_block); |
| 1202 | IrInstruction *else_expr_result; | 1209 | IrInstruction *else_expr_result; |
| ... | @@ -1208,7 +1215,7 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, AstNode *node) { | ... | @@ -1208,7 +1215,7 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, AstNode *node) { |
| 1208 | else_expr_result = ir_build_const_void(irb, node); | 1215 | else_expr_result = ir_build_const_void(irb, node); |
| 1209 | } | 1216 | } |
| 1210 | IrBasicBlock *after_else_block = irb->current_basic_block; | 1217 | IrBasicBlock *after_else_block = irb->current_basic_block; |
| 1211 | ir_build_br(irb, node, endif_block); | 1218 | ir_build_br(irb, node, endif_block, false); |
| 1212 | | 1219 | |
| 1213 | ir_set_cursor_at_end(irb, endif_block); | 1220 | ir_set_cursor_at_end(irb, endif_block); |
| 1214 | IrInstruction **incoming_values = allocate<IrInstruction *>(2); | 1221 | IrInstruction **incoming_values = allocate<IrInstruction *>(2); |
| ... | @@ -1333,8 +1340,9 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, AstNode *node) { | ... | @@ -1333,8 +1340,9 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, AstNode *node) { |
| 1333 | bool is_shadowable = false; | 1340 | bool is_shadowable = false; |
| 1334 | bool is_const = variable_declaration->is_const; | 1341 | bool is_const = variable_declaration->is_const; |
| 1335 | bool is_extern = variable_declaration->is_extern; | 1342 | bool is_extern = variable_declaration->is_extern; |
| | 1343 | bool is_inline = variable_declaration->is_inline; |
| 1336 | VariableTableEntry *var = ir_add_local_var(irb, node, node->block_context, | 1344 | VariableTableEntry *var = ir_add_local_var(irb, node, node->block_context, |
| 1337 | variable_declaration->symbol, is_const, is_shadowable); | 1345 | variable_declaration->symbol, is_const, is_const, is_shadowable, is_inline); |
| 1338 | | 1346 | |
| 1339 | if (!is_extern && !variable_declaration->expr) { | 1347 | if (!is_extern && !variable_declaration->expr) { |
| 1340 | var->type = irb->codegen->builtin_types.entry_invalid; | 1348 | var->type = irb->codegen->builtin_types.entry_invalid; |
| ... | @@ -1356,18 +1364,18 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, AstNode *node) { | ... | @@ -1356,18 +1364,18 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, AstNode *node) { |
| 1356 | ir_build_basic_block(irb, "WhileContinue") : cond_block; | 1364 | ir_build_basic_block(irb, "WhileContinue") : cond_block; |
| 1357 | IrBasicBlock *end_block = ir_build_basic_block(irb, "WhileEnd"); | 1365 | IrBasicBlock *end_block = ir_build_basic_block(irb, "WhileEnd"); |
| 1358 | | 1366 | |
| 1359 | ir_build_br(irb, node, cond_block); | 1367 | bool is_inline = node->data.while_expr.is_inline; |
| | 1368 | ir_build_br(irb, node, cond_block, is_inline); |
| 1360 | | 1369 | |
| 1361 | if (continue_expr_node) { | 1370 | if (continue_expr_node) { |
| 1362 | ir_set_cursor_at_end(irb, continue_block); | 1371 | ir_set_cursor_at_end(irb, continue_block); |
| 1363 | ir_gen_node(irb, continue_expr_node, node->block_context); | 1372 | ir_gen_node(irb, continue_expr_node, node->block_context); |
| 1364 | ir_build_br(irb, node, cond_block); | 1373 | ir_build_br(irb, node, cond_block, is_inline); |
| 1365 | | | |
| 1366 | } | 1374 | } |
| 1367 | | 1375 | |
| 1368 | ir_set_cursor_at_end(irb, cond_block); | 1376 | ir_set_cursor_at_end(irb, cond_block); |
| 1369 | IrInstruction *cond_val = ir_gen_node(irb, node->data.while_expr.condition, node->block_context); | 1377 | IrInstruction *cond_val = ir_gen_node(irb, node->data.while_expr.condition, node->block_context); |
| 1370 | ir_build_cond_br(irb, node->data.while_expr.condition, cond_val, body_block, end_block); | 1378 | ir_build_cond_br(irb, node->data.while_expr.condition, cond_val, body_block, end_block, is_inline); |
| 1371 | | 1379 | |
| 1372 | ir_set_cursor_at_end(irb, body_block); | 1380 | ir_set_cursor_at_end(irb, body_block); |
| 1373 | | 1381 | |
| ... | @@ -1377,7 +1385,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, AstNode *node) { | ... | @@ -1377,7 +1385,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, AstNode *node) { |
| 1377 | irb->break_block_stack.pop(); | 1385 | irb->break_block_stack.pop(); |
| 1378 | irb->continue_block_stack.pop(); | 1386 | irb->continue_block_stack.pop(); |
| 1379 | | 1387 | |
| 1380 | ir_build_br(irb, node, continue_block); | 1388 | ir_build_br(irb, node, continue_block, is_inline); |
| 1381 | ir_set_cursor_at_end(irb, end_block); | 1389 | ir_set_cursor_at_end(irb, end_block); |
| 1382 | | 1390 | |
| 1383 | return ir_build_const_void(irb, node); | 1391 | return ir_build_const_void(irb, node); |
| ... | @@ -1411,30 +1419,36 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, AstNode *node) { | ... | @@ -1411,30 +1419,36 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, AstNode *node) { |
| 1411 | } else { | 1419 | } else { |
| 1412 | elem_var_type = ir_build_ptr_type_child(irb, elem_node, pointer_type); | 1420 | elem_var_type = ir_build_ptr_type_child(irb, elem_node, pointer_type); |
| 1413 | } | 1421 | } |
| | 1422 | bool is_inline = node->data.for_expr.is_inline; |
| 1414 | | 1423 | |
| 1415 | BlockContext *child_scope = new_block_context(node, parent_scope); | 1424 | BlockContext *child_scope = new_block_context(node, parent_scope); |
| 1416 | child_scope->parent_loop_node = node; | 1425 | child_scope->parent_loop_node = node; |
| 1417 | elem_node->block_context = child_scope; | 1426 | elem_node->block_context = child_scope; |
| 1418 | | 1427 | |
| 1419 | // TODO make it an error to write to element variable or i variable. | 1428 | // TODO make it an error to write to element variable or i variable. |
| 1420 | | | |
| 1421 | Buf *elem_var_name = elem_node->data.symbol_expr.symbol; | 1429 | Buf *elem_var_name = elem_node->data.symbol_expr.symbol; |
| 1422 | node->data.for_expr.elem_var = ir_add_local_var(irb, elem_node, child_scope, elem_var_name, false, false); | 1430 | node->data.for_expr.elem_var = ir_add_local_var(irb, elem_node, child_scope, elem_var_name, |
| | 1431 | true, false, false, is_inline); |
| 1423 | IrInstruction *undefined_value = ir_build_const_undefined(irb, elem_node); | 1432 | IrInstruction *undefined_value = ir_build_const_undefined(irb, elem_node); |
| 1424 | ir_build_var_decl(irb, elem_node, node->data.for_expr.elem_var, elem_var_type, undefined_value); | 1433 | ir_build_var_decl(irb, elem_node, node->data.for_expr.elem_var, elem_var_type, undefined_value); |
| 1425 | IrInstruction *elem_var_ptr = ir_build_var_ptr(irb, node, node->data.for_expr.elem_var); | 1434 | IrInstruction *elem_var_ptr = ir_build_var_ptr(irb, node, node->data.for_expr.elem_var); |
| 1426 | | 1435 | |
| | 1436 | AstNode *index_var_source_node; |
| 1427 | if (index_node) { | 1437 | if (index_node) { |
| | 1438 | index_var_source_node = index_node; |
| 1428 | Buf *index_var_name = index_node->data.symbol_expr.symbol; | 1439 | Buf *index_var_name = index_node->data.symbol_expr.symbol; |
| 1429 | index_node->block_context = child_scope; | 1440 | index_node->block_context = child_scope; |
| 1430 | node->data.for_expr.index_var = ir_add_local_var(irb, index_node, child_scope, index_var_name, false, false); | 1441 | node->data.for_expr.index_var = ir_add_local_var(irb, index_node, child_scope, index_var_name, |
| | 1442 | true, false, false, is_inline); |
| 1431 | } else { | 1443 | } else { |
| 1432 | node->data.for_expr.index_var = ir_add_local_var(irb, node, child_scope, nullptr, false, true); | 1444 | index_var_source_node = node; |
| | 1445 | node->data.for_expr.index_var = ir_add_local_var(irb, node, child_scope, nullptr, |
| | 1446 | true, false, true, is_inline); |
| 1433 | } | 1447 | } |
| 1434 | IrInstruction *usize = ir_build_const_type(irb, node, irb->codegen->builtin_types.entry_usize); | 1448 | IrInstruction *usize = ir_build_const_type(irb, node, irb->codegen->builtin_types.entry_usize); |
| 1435 | IrInstruction *zero = ir_build_const_usize(irb, node, 0); | 1449 | IrInstruction *zero = ir_build_const_usize(irb, node, 0); |
| 1436 | IrInstruction *one = ir_build_const_usize(irb, node, 1); | 1450 | IrInstruction *one = ir_build_const_usize(irb, node, 1); |
| 1437 | ir_build_var_decl(irb, index_node, node->data.for_expr.index_var, usize, zero); | 1451 | ir_build_var_decl(irb, index_var_source_node, node->data.for_expr.index_var, usize, zero); |
| 1438 | IrInstruction *index_ptr = ir_build_var_ptr(irb, node, node->data.for_expr.index_var); | 1452 | IrInstruction *index_ptr = ir_build_var_ptr(irb, node, node->data.for_expr.index_var); |
| 1439 | | 1453 | |
| 1440 | | 1454 | |
| ... | @@ -1444,12 +1458,12 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, AstNode *node) { | ... | @@ -1444,12 +1458,12 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, AstNode *node) { |
| 1444 | IrBasicBlock *continue_block = ir_build_basic_block(irb, "ForContinue"); | 1458 | IrBasicBlock *continue_block = ir_build_basic_block(irb, "ForContinue"); |
| 1445 | | 1459 | |
| 1446 | IrInstruction *len_val = ir_build_read_field(irb, node, array_val, irb->codegen->len_buf); | 1460 | IrInstruction *len_val = ir_build_read_field(irb, node, array_val, irb->codegen->len_buf); |
| 1447 | ir_build_br(irb, node, cond_block); | 1461 | ir_build_br(irb, node, cond_block, is_inline); |
| 1448 | | 1462 | |
| 1449 | ir_set_cursor_at_end(irb, cond_block); | 1463 | ir_set_cursor_at_end(irb, cond_block); |
| 1450 | IrInstruction *index_val = ir_build_load_ptr(irb, node, index_ptr); | 1464 | IrInstruction *index_val = ir_build_load_ptr(irb, node, index_ptr); |
| 1451 | IrInstruction *cond = ir_build_bin_op(irb, node, IrBinOpCmpLessThan, index_val, len_val); | 1465 | IrInstruction *cond = ir_build_bin_op(irb, node, IrBinOpCmpLessThan, index_val, len_val); |
| 1452 | ir_build_cond_br(irb, node, cond, body_block, end_block); | 1466 | ir_build_cond_br(irb, node, cond, body_block, end_block, is_inline); |
| 1453 | | 1467 | |
| 1454 | ir_set_cursor_at_end(irb, body_block); | 1468 | ir_set_cursor_at_end(irb, body_block); |
| 1455 | IrInstruction *elem_ptr = ir_build_elem_ptr(irb, node, array_val, index_val); | 1469 | IrInstruction *elem_ptr = ir_build_elem_ptr(irb, node, array_val, index_val); |
| ... | @@ -1467,12 +1481,12 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, AstNode *node) { | ... | @@ -1467,12 +1481,12 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, AstNode *node) { |
| 1467 | irb->break_block_stack.pop(); | 1481 | irb->break_block_stack.pop(); |
| 1468 | irb->continue_block_stack.pop(); | 1482 | irb->continue_block_stack.pop(); |
| 1469 | | 1483 | |
| 1470 | ir_build_br(irb, node, continue_block); | 1484 | ir_build_br(irb, node, continue_block, is_inline); |
| 1471 | | 1485 | |
| 1472 | ir_set_cursor_at_end(irb, continue_block); | 1486 | ir_set_cursor_at_end(irb, continue_block); |
| 1473 | IrInstruction *new_index_val = ir_build_bin_op(irb, node, IrBinOpAdd, index_val, one); | 1487 | IrInstruction *new_index_val = ir_build_bin_op(irb, node, IrBinOpAdd, index_val, one); |
| 1474 | ir_build_store_ptr(irb, node, index_ptr, new_index_val); | 1488 | ir_build_store_ptr(irb, node, index_ptr, new_index_val); |
| 1475 | ir_build_br(irb, node, cond_block); | 1489 | ir_build_br(irb, node, cond_block, is_inline); |
| 1476 | | 1490 | |
| 1477 | ir_set_cursor_at_end(irb, end_block); | 1491 | ir_set_cursor_at_end(irb, end_block); |
| 1478 | return ir_build_const_void(irb, node); | 1492 | return ir_build_const_void(irb, node); |
| ... | @@ -1911,23 +1925,41 @@ static void ir_inline_bb(IrAnalyze *ira, IrBasicBlock *old_bb) { | ... | @@ -1911,23 +1925,41 @@ static void ir_inline_bb(IrAnalyze *ira, IrBasicBlock *old_bb) { |
| 1911 | } | 1925 | } |
| 1912 | | 1926 | |
| 1913 | | 1927 | |
| 1914 | static ConstExprValue *ir_get_out_val(IrInstruction *instruction) { | 1928 | static ConstExprValue *ir_build_const_from(IrAnalyze *ira, IrInstruction *old_instruction, |
| 1915 | instruction->other = instruction; | 1929 | bool depends_on_compile_var) |
| 1916 | return &instruction->static_value; | 1930 | { |
| | 1931 | IrInstruction *new_instruction; |
| | 1932 | if (old_instruction->id == IrInstructionIdVarPtr) { |
| | 1933 | IrInstructionVarPtr *old_var_ptr_instruction = (IrInstructionVarPtr *)old_instruction; |
| | 1934 | IrInstructionVarPtr *var_ptr_instruction = ir_create_instruction<IrInstructionVarPtr>(ira->new_irb.exec, |
| | 1935 | old_instruction->source_node); |
| | 1936 | var_ptr_instruction->var = old_var_ptr_instruction->var; |
| | 1937 | new_instruction = &var_ptr_instruction->base; |
| | 1938 | } else if (old_instruction->id == IrInstructionIdFieldPtr) { |
| | 1939 | zig_panic("TODO"); |
| | 1940 | } else if (old_instruction->id == IrInstructionIdElemPtr) { |
| | 1941 | zig_panic("TODO"); |
| | 1942 | } else { |
| | 1943 | IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(ira->new_irb.exec, |
| | 1944 | old_instruction->source_node); |
| | 1945 | new_instruction = &const_instruction->base; |
| | 1946 | } |
| | 1947 | ir_link_new_instruction(new_instruction, old_instruction); |
| | 1948 | ConstExprValue *const_val = &new_instruction->static_value; |
| | 1949 | const_val->ok = true; |
| | 1950 | const_val->depends_on_compile_var = depends_on_compile_var; |
| | 1951 | return const_val; |
| 1917 | } | 1952 | } |
| 1918 | | 1953 | |
| 1919 | static TypeTableEntry *ir_analyze_void(IrAnalyze *ira, IrInstruction *instruction) { | 1954 | static TypeTableEntry *ir_analyze_void(IrAnalyze *ira, IrInstruction *instruction) { |
| 1920 | ConstExprValue *const_val = ir_get_out_val(instruction); | 1955 | ir_build_const_from(ira, instruction, false); |
| 1921 | const_val->ok = true; | | |
| 1922 | return ira->codegen->builtin_types.entry_void; | 1956 | return ira->codegen->builtin_types.entry_void; |
| 1923 | } | 1957 | } |
| 1924 | | 1958 | |
| 1925 | static TypeTableEntry *ir_analyze_const_usize(IrAnalyze *ira, IrInstruction *instruction, uint64_t value, | 1959 | static TypeTableEntry *ir_analyze_const_usize(IrAnalyze *ira, IrInstruction *instruction, uint64_t value, |
| 1926 | bool depends_on_compile_var) | 1960 | bool depends_on_compile_var) |
| 1927 | { | 1961 | { |
| 1928 | ConstExprValue *const_val = ir_get_out_val(instruction); | 1962 | ConstExprValue *const_val = ir_build_const_from(ira, instruction, depends_on_compile_var); |
| 1929 | const_val->ok = true; | | |
| 1930 | const_val->depends_on_compile_var = depends_on_compile_var; | | |
| 1931 | bignum_init_unsigned(&const_val->data.x_bignum, value); | 1963 | bignum_init_unsigned(&const_val->data.x_bignum, value); |
| 1932 | return ira->codegen->builtin_types.entry_usize; | 1964 | return ira->codegen->builtin_types.entry_usize; |
| 1933 | } | 1965 | } |
| ... | @@ -2295,7 +2327,8 @@ static TypeTableEntry *ir_analyze_bin_op_bool(IrAnalyze *ira, IrInstructionBinOp | ... | @@ -2295,7 +2327,8 @@ static TypeTableEntry *ir_analyze_bin_op_bool(IrAnalyze *ira, IrInstructionBinOp |
| 2295 | ConstExprValue *op1_val = &casted_op1->static_value; | 2327 | ConstExprValue *op1_val = &casted_op1->static_value; |
| 2296 | ConstExprValue *op2_val = &casted_op2->static_value; | 2328 | ConstExprValue *op2_val = &casted_op2->static_value; |
| 2297 | if (op1_val->ok && op2_val->ok) { | 2329 | if (op1_val->ok && op2_val->ok) { |
| 2298 | ConstExprValue *out_val = ir_get_out_val(&bin_op_instruction->base); | 2330 | bool depends_on_compile_var = op1_val->depends_on_compile_var || op2_val->depends_on_compile_var; |
| | 2331 | ConstExprValue *out_val = ir_build_const_from(ira, &bin_op_instruction->base, depends_on_compile_var); |
| 2299 | | 2332 | |
| 2300 | assert(op1->type_entry->id == TypeTableEntryIdBool); | 2333 | assert(op1->type_entry->id == TypeTableEntryIdBool); |
| 2301 | assert(op2->type_entry->id == TypeTableEntryIdBool); | 2334 | assert(op2->type_entry->id == TypeTableEntryIdBool); |
| ... | @@ -2306,14 +2339,10 @@ static TypeTableEntry *ir_analyze_bin_op_bool(IrAnalyze *ira, IrInstructionBinOp | ... | @@ -2306,14 +2339,10 @@ static TypeTableEntry *ir_analyze_bin_op_bool(IrAnalyze *ira, IrInstructionBinOp |
| 2306 | } else { | 2339 | } else { |
| 2307 | zig_unreachable(); | 2340 | zig_unreachable(); |
| 2308 | } | 2341 | } |
| 2309 | out_val->ok = true; | | |
| 2310 | out_val->depends_on_compile_var = op1_val->depends_on_compile_var || | | |
| 2311 | op2_val->depends_on_compile_var; | | |
| 2312 | return bool_type; | 2342 | return bool_type; |
| 2313 | } | 2343 | } |
| 2314 | | 2344 | |
| 2315 | ir_build_bin_op_from(&ira->new_irb, &bin_op_instruction->base, bin_op_instruction->op_id, op1->other, op2->other); | 2345 | ir_build_bin_op_from(&ira->new_irb, &bin_op_instruction->base, bin_op_instruction->op_id, op1->other, op2->other); |
| 2316 | | | |
| 2317 | return bool_type; | 2346 | return bool_type; |
| 2318 | } | 2347 | } |
| 2319 | | 2348 | |
| ... | @@ -2425,9 +2454,8 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp | ... | @@ -2425,9 +2454,8 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp |
| 2425 | } | 2454 | } |
| 2426 | } | 2455 | } |
| 2427 | | 2456 | |
| 2428 | ConstExprValue *out_val = ir_get_out_val(&bin_op_instruction->base); | 2457 | bool depends_on_compile_var = op1_val->depends_on_compile_var || op2_val->depends_on_compile_var; |
| 2429 | out_val->ok = true; | 2458 | ConstExprValue *out_val = ir_build_const_from(ira, &bin_op_instruction->base, depends_on_compile_var); |
| 2430 | out_val->depends_on_compile_var = op1_val->depends_on_compile_var || op2_val->depends_on_compile_var; | | |
| 2431 | out_val->data.x_bool = answer; | 2459 | out_val->data.x_bool = answer; |
| 2432 | return ira->codegen->builtin_types.entry_bool; | 2460 | return ira->codegen->builtin_types.entry_bool; |
| 2433 | } | 2461 | } |
| ... | @@ -4108,12 +4136,15 @@ static TypeTableEntry *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr | ... | @@ -4108,12 +4136,15 @@ static TypeTableEntry *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr |
| 4108 | | 4136 | |
| 4109 | // TODO detect backward jumps | 4137 | // TODO detect backward jumps |
| 4110 | | 4138 | |
| 4111 | ir_inline_bb(ira, old_dest_block); | 4139 | if (br_instruction->is_inline || old_dest_block->ref_count == 1) { |
| 4112 | return ira->codegen->builtin_types.entry_unreachable; | 4140 | ir_inline_bb(ira, old_dest_block); |
| | 4141 | return ira->codegen->builtin_types.entry_unreachable; |
| | 4142 | } |
| 4113 | | 4143 | |
| 4114 | //IrBasicBlock *new_bb = ir_get_new_bb(ira, old_dest_block); | 4144 | IrBasicBlock *new_bb = ir_get_new_bb(ira, old_dest_block); |
| 4115 | //ir_build_br_from(&ira->new_irb, &br_instruction->base, new_bb); | 4145 | ir_build_br_from(&ira->new_irb, &br_instruction->base, new_bb); |
| 4116 | //return ira->codegen->builtin_types.entry_unreachable; | 4146 | ir_finish_bb(ira); |
| | 4147 | return ira->codegen->builtin_types.entry_unreachable; |
| 4117 | } | 4148 | } |
| 4118 | | 4149 | |
| 4119 | static TypeTableEntry *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstructionCondBr *cond_br_instruction) { | 4150 | static TypeTableEntry *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstructionCondBr *cond_br_instruction) { |
| ... | @@ -4129,13 +4160,20 @@ static TypeTableEntry *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstruct | ... | @@ -4129,13 +4160,20 @@ static TypeTableEntry *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstruct |
| 4129 | IrBasicBlock *old_dest_block = condition->static_value.data.x_bool ? | 4160 | IrBasicBlock *old_dest_block = condition->static_value.data.x_bool ? |
| 4130 | cond_br_instruction->then_block : cond_br_instruction->else_block; | 4161 | cond_br_instruction->then_block : cond_br_instruction->else_block; |
| 4131 | | 4162 | |
| 4132 | ir_inline_bb(ira, old_dest_block); | 4163 | if (cond_br_instruction->is_inline || old_dest_block->ref_count == 1) { |
| | 4164 | ir_inline_bb(ira, old_dest_block); |
| | 4165 | return ira->codegen->builtin_types.entry_unreachable; |
| | 4166 | } |
| | 4167 | } else if (cond_br_instruction->is_inline) { |
| | 4168 | add_node_error(ira->codegen, condition->source_node, |
| | 4169 | buf_sprintf("unable to evaluate constant expression")); |
| | 4170 | ir_finish_bb(ira); |
| 4133 | return ira->codegen->builtin_types.entry_unreachable; | 4171 | return ira->codegen->builtin_types.entry_unreachable; |
| 4134 | } | 4172 | } |
| 4135 | | 4173 | |
| 4136 | IrBasicBlock *new_then_block = ir_get_new_bb(ira, cond_br_instruction->then_block); | 4174 | IrBasicBlock *new_then_block = ir_get_new_bb(ira, cond_br_instruction->then_block); |
| 4137 | IrBasicBlock *new_else_block = ir_get_new_bb(ira, cond_br_instruction->else_block); | 4175 | IrBasicBlock *new_else_block = ir_get_new_bb(ira, cond_br_instruction->else_block); |
| 4138 | ir_build_cond_br_from(&ira->new_irb, &cond_br_instruction->base, condition, new_then_block, new_else_block); | 4176 | ir_build_cond_br_from(&ira->new_irb, &cond_br_instruction->base, condition, new_then_block, new_else_block, false); |
| 4139 | ir_finish_bb(ira); | 4177 | ir_finish_bb(ira); |
| 4140 | return ira->codegen->builtin_types.entry_unreachable; | 4178 | return ira->codegen->builtin_types.entry_unreachable; |
| 4141 | } | 4179 | } |
| ... | @@ -4206,7 +4244,8 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP | ... | @@ -4206,7 +4244,8 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP |
| 4206 | IrInstruction *value = phi_instruction->incoming_values[i]->other; | 4244 | IrInstruction *value = phi_instruction->incoming_values[i]->other; |
| 4207 | assert(value->type_entry); | 4245 | assert(value->type_entry); |
| 4208 | if (value->static_value.ok) { | 4246 | if (value->static_value.ok) { |
| 4209 | ConstExprValue *out_val = ir_get_out_val(&phi_instruction->base); | 4247 | ConstExprValue *out_val = ir_build_const_from(ira, &phi_instruction->base, |
| | 4248 | value->static_value.depends_on_compile_var); |
| 4210 | *out_val = value->static_value; | 4249 | *out_val = value->static_value; |
| 4211 | } else { | 4250 | } else { |
| 4212 | phi_instruction->base.other = value; | 4251 | phi_instruction->base.other = value; |
| ... | @@ -4259,9 +4298,9 @@ static TypeTableEntry *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstruct | ... | @@ -4259,9 +4298,9 @@ static TypeTableEntry *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstruct |
| 4259 | if (var->mem_slot_index != SIZE_MAX) { | 4298 | if (var->mem_slot_index != SIZE_MAX) { |
| 4260 | ConstExprValue *mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index]; | 4299 | ConstExprValue *mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index]; |
| 4261 | if (mem_slot->ok) { | 4300 | if (mem_slot->ok) { |
| 4262 | ConstExprValue *out_val = ir_get_out_val(&var_ptr_instruction->base); | 4301 | ConstExprValue *out_val = ir_build_const_from(ira, &var_ptr_instruction->base, |
| | 4302 | mem_slot->depends_on_compile_var); |
| 4263 | | 4303 | |
| 4264 | out_val->ok = true; | | |
| 4265 | out_val->data.x_ptr.len = 1; | 4304 | out_val->data.x_ptr.len = 1; |
| 4266 | out_val->data.x_ptr.is_c_str = false; | 4305 | out_val->data.x_ptr.is_c_str = false; |
| 4267 | out_val->data.x_ptr.ptr = allocate<ConstExprValue *>(1); | 4306 | out_val->data.x_ptr.ptr = allocate<ConstExprValue *>(1); |
| ... | @@ -4477,7 +4516,8 @@ static TypeTableEntry *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstruc | ... | @@ -4477,7 +4516,8 @@ static TypeTableEntry *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstruc |
| 4477 | if (ptr->static_value.ok) { | 4516 | if (ptr->static_value.ok) { |
| 4478 | ConstExprValue *pointee = ptr->static_value.data.x_ptr.ptr[0]; | 4517 | ConstExprValue *pointee = ptr->static_value.data.x_ptr.ptr[0]; |
| 4479 | if (pointee->ok) { | 4518 | if (pointee->ok) { |
| 4480 | ConstExprValue *out_val = ir_get_out_val(&load_ptr_instruction->base); | 4519 | ConstExprValue *out_val = ir_build_const_from(ira, &load_ptr_instruction->base, |
| | 4520 | pointee->depends_on_compile_var); |
| 4481 | *out_val = *pointee; | 4521 | *out_val = *pointee; |
| 4482 | return child_type; | 4522 | return child_type; |
| 4483 | } | 4523 | } |
| ... | @@ -4576,8 +4616,7 @@ static TypeTableEntry *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructi | ... | @@ -4576,8 +4616,7 @@ static TypeTableEntry *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructi |
| 4576 | case TypeTableEntryIdFn: | 4616 | case TypeTableEntryIdFn: |
| 4577 | case TypeTableEntryIdTypeDecl: | 4617 | case TypeTableEntryIdTypeDecl: |
| 4578 | { | 4618 | { |
| 4579 | ConstExprValue *out_val = ir_get_out_val(&typeof_instruction->base); | 4619 | ConstExprValue *out_val = ir_build_const_from(ira, &typeof_instruction->base, false); |
| 4580 | out_val->ok = true; | | |
| 4581 | // TODO depends_on_compile_var should be set based on whether the type of the expression | 4620 | // TODO depends_on_compile_var should be set based on whether the type of the expression |
| 4582 | // depends_on_compile_var. but we currently don't have a thing to tell us if the type of | 4621 | // depends_on_compile_var. but we currently don't have a thing to tell us if the type of |
| 4583 | // something depends on a compile var | 4622 | // something depends on a compile var |
| ... | @@ -4609,9 +4648,8 @@ static TypeTableEntry *ir_analyze_instruction_to_ptr_type(IrAnalyze *ira, | ... | @@ -4609,9 +4648,8 @@ static TypeTableEntry *ir_analyze_instruction_to_ptr_type(IrAnalyze *ira, |
| 4609 | return ira->codegen->builtin_types.entry_invalid; | 4648 | return ira->codegen->builtin_types.entry_invalid; |
| 4610 | } | 4649 | } |
| 4611 | | 4650 | |
| 4612 | ConstExprValue *out_val = ir_get_out_val(&to_ptr_type_instruction->base); | 4651 | ConstExprValue *out_val = ir_build_const_from(ira, &to_ptr_type_instruction->base, |
| 4613 | out_val->ok = true; | 4652 | type_value->static_value.depends_on_compile_var); |
| 4614 | out_val->depends_on_compile_var = type_value->static_value.depends_on_compile_var; | | |
| 4615 | out_val->data.x_type = ptr_type; | 4653 | out_val->data.x_type = ptr_type; |
| 4616 | return ira->codegen->builtin_types.entry_type; | 4654 | return ira->codegen->builtin_types.entry_type; |
| 4617 | } | 4655 | } |
| ... | @@ -4630,9 +4668,8 @@ static TypeTableEntry *ir_analyze_instruction_ptr_type_child(IrAnalyze *ira, | ... | @@ -4630,9 +4668,8 @@ static TypeTableEntry *ir_analyze_instruction_ptr_type_child(IrAnalyze *ira, |
| 4630 | return ira->codegen->builtin_types.entry_invalid; | 4668 | return ira->codegen->builtin_types.entry_invalid; |
| 4631 | } | 4669 | } |
| 4632 | | 4670 | |
| 4633 | ConstExprValue *out_val = ir_get_out_val(&ptr_type_child_instruction->base); | 4671 | ConstExprValue *out_val = ir_build_const_from(ira, &ptr_type_child_instruction->base, |
| 4634 | out_val->ok = true; | 4672 | type_value->static_value.depends_on_compile_var); |
| 4635 | out_val->depends_on_compile_var = type_value->static_value.depends_on_compile_var; | | |
| 4636 | out_val->data.x_type = type_entry->data.pointer.child_type; | 4673 | out_val->data.x_type = type_entry->data.pointer.child_type; |
| 4637 | return ira->codegen->builtin_types.entry_type; | 4674 | return ira->codegen->builtin_types.entry_type; |
| 4638 | } | 4675 | } |
| ... | @@ -4734,10 +4771,6 @@ TypeTableEntry *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutabl | ... | @@ -4734,10 +4771,6 @@ TypeTableEntry *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutabl |
| 4734 | while (ira->block_queue_index < ira->old_bb_queue.length) { | 4771 | while (ira->block_queue_index < ira->old_bb_queue.length) { |
| 4735 | IrInstruction *old_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index); | 4772 | IrInstruction *old_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index); |
| 4736 | | 4773 | |
| 4737 | fprintf(stderr, "===%zu====", old_instruction->debug_id); | | |
| 4738 | ir_print(stderr, ira->new_irb.exec, 4); | | |
| 4739 | fprintf(stderr, "========"); | | |
| 4740 | | | |
| 4741 | if (old_instruction->ref_count == 0 && !ir_has_side_effects(old_instruction)) { | 4774 | if (old_instruction->ref_count == 0 && !ir_has_side_effects(old_instruction)) { |
| 4742 | ira->instruction_index += 1; | 4775 | ira->instruction_index += 1; |
| 4743 | continue; | 4776 | continue; |