| author | |
| committer | |
| log | d7a2b05a813a7badf0606726c9a4b1423befd437 |
| tree | b4f1f0caa664d10b26a0ca4be31d1aeb125c802b |
| parent | a9a6f77a1f0a6e173d85fee42aec0a8d5e22a64d |
6 files changed, 522 insertions(+), 280 deletions(-)
CMakeLists.txt+1-1| ... | @@ -38,6 +38,7 @@ include_directories( | ... | @@ -38,6 +38,7 @@ include_directories( |
| 38 | ) | 38 | ) |
| 39 | 39 | ||
| 40 | set(ZIG_SOURCES | 40 | set(ZIG_SOURCES |
| 41 | "${CMAKE_SOURCE_DIR}/src/ir.cpp" | ||
| 41 | "${CMAKE_SOURCE_DIR}/src/analyze.cpp" | 42 | "${CMAKE_SOURCE_DIR}/src/analyze.cpp" |
| 42 | "${CMAKE_SOURCE_DIR}/src/ast_render.cpp" | 43 | "${CMAKE_SOURCE_DIR}/src/ast_render.cpp" |
| 43 | "${CMAKE_SOURCE_DIR}/src/bignum.cpp" | 44 | "${CMAKE_SOURCE_DIR}/src/bignum.cpp" |
| ... | @@ -47,7 +48,6 @@ set(ZIG_SOURCES | ... | @@ -47,7 +48,6 @@ set(ZIG_SOURCES |
| 47 | "${CMAKE_SOURCE_DIR}/src/errmsg.cpp" | 48 | "${CMAKE_SOURCE_DIR}/src/errmsg.cpp" |
| 48 | "${CMAKE_SOURCE_DIR}/src/error.cpp" | 49 | "${CMAKE_SOURCE_DIR}/src/error.cpp" |
| 49 | "${CMAKE_SOURCE_DIR}/src/eval.cpp" | 50 | "${CMAKE_SOURCE_DIR}/src/eval.cpp" |
| 50 | "${CMAKE_SOURCE_DIR}/src/ir.cpp" | ||
| 51 | "${CMAKE_SOURCE_DIR}/src/ir_print.cpp" | 51 | "${CMAKE_SOURCE_DIR}/src/ir_print.cpp" |
| 52 | "${CMAKE_SOURCE_DIR}/src/link.cpp" | 52 | "${CMAKE_SOURCE_DIR}/src/link.cpp" |
| 53 | "${CMAKE_SOURCE_DIR}/src/main.cpp" | 53 | "${CMAKE_SOURCE_DIR}/src/main.cpp" |
src/all_types.hpp+30-7| ... | @@ -34,7 +34,7 @@ struct IrBasicBlock; | ... | @@ -34,7 +34,7 @@ struct IrBasicBlock; |
| 34 | 34 | ||
| 35 | struct IrExecutable { | 35 | struct IrExecutable { |
| 36 | ZigList<IrBasicBlock *> basic_block_list; | 36 | ZigList<IrBasicBlock *> basic_block_list; |
| 37 | size_t var_slot_count; | 37 | size_t mem_slot_count; |
| 38 | size_t next_debug_id; | 38 | size_t next_debug_id; |
| 39 | }; | 39 | }; |
| 40 | 40 | ||
| ... | @@ -1349,7 +1349,7 @@ struct VariableTableEntry { | ... | @@ -1349,7 +1349,7 @@ struct VariableTableEntry { |
| 1349 | bool force_depends_on_compile_var; | 1349 | bool force_depends_on_compile_var; |
| 1350 | ImportTableEntry *import; | 1350 | ImportTableEntry *import; |
| 1351 | bool shadowable; | 1351 | bool shadowable; |
| 1352 | size_t slot_index; | 1352 | size_t mem_slot_index; |
| 1353 | size_t ref_count; | 1353 | size_t ref_count; |
| 1354 | }; | 1354 | }; |
| 1355 | 1355 | ||
| ... | @@ -1425,8 +1425,11 @@ enum IrInstructionId { | ... | @@ -1425,8 +1425,11 @@ enum IrInstructionId { |
| 1425 | IrInstructionIdUnOp, | 1425 | IrInstructionIdUnOp, |
| 1426 | IrInstructionIdBinOp, | 1426 | IrInstructionIdBinOp, |
| 1427 | IrInstructionIdDeclVar, | 1427 | IrInstructionIdDeclVar, |
| 1428 | IrInstructionIdLoadVar, | 1428 | IrInstructionIdLoadPtr, |
| 1429 | IrInstructionIdStoreVar, | 1429 | IrInstructionIdStorePtr, |
| 1430 | IrInstructionIdFieldPtr, | ||
| 1431 | IrInstructionIdElemPtr, | ||
| 1432 | IrInstructionIdVarPtr, | ||
| 1430 | IrInstructionIdCall, | 1433 | IrInstructionIdCall, |
| 1431 | IrInstructionIdBuiltinCall, | 1434 | IrInstructionIdBuiltinCall, |
| 1432 | IrInstructionIdConst, | 1435 | IrInstructionIdConst, |
| ... | @@ -1554,16 +1557,36 @@ struct IrInstructionDeclVar { | ... | @@ -1554,16 +1557,36 @@ struct IrInstructionDeclVar { |
| 1554 | IrInstruction *init_value; | 1557 | IrInstruction *init_value; |
| 1555 | }; | 1558 | }; |
| 1556 | 1559 | ||
| 1557 | struct IrInstructionLoadVar { | 1560 | struct IrInstructionLoadPtr { |
| 1558 | IrInstruction base; | 1561 | IrInstruction base; |
| 1559 | 1562 | ||
| 1560 | VariableTableEntry *var; | 1563 | IrInstruction *ptr; |
| 1561 | }; | 1564 | }; |
| 1562 | 1565 | ||
| 1563 | struct IrInstructionStoreVar { | 1566 | struct IrInstructionStorePtr { |
| 1564 | IrInstruction base; | 1567 | IrInstruction base; |
| 1565 | 1568 | ||
| 1569 | IrInstruction *ptr; | ||
| 1566 | IrInstruction *value; | 1570 | IrInstruction *value; |
| 1571 | }; | ||
| 1572 | |||
| 1573 | struct IrInstructionFieldPtr { | ||
| 1574 | IrInstruction base; | ||
| 1575 | |||
| 1576 | IrInstruction *struct_ptr; | ||
| 1577 | Buf field_name; | ||
| 1578 | }; | ||
| 1579 | |||
| 1580 | struct IrInstructionElemPtr { | ||
| 1581 | IrInstruction base; | ||
| 1582 | |||
| 1583 | IrInstruction *array_ptr; | ||
| 1584 | IrInstruction *elem_index; | ||
| 1585 | }; | ||
| 1586 | |||
| 1587 | struct IrInstructionVarPtr { | ||
| 1588 | IrInstruction base; | ||
| 1589 | |||
| 1567 | VariableTableEntry *var; | 1590 | VariableTableEntry *var; |
| 1568 | }; | 1591 | }; |
| 1569 | 1592 |
src/analyze.cpp+3| ... | @@ -3615,6 +3615,9 @@ static VariableTableEntry *add_local_var_shadowable(CodeGen *g, AstNode *source_ | ... | @@ -3615,6 +3615,9 @@ static VariableTableEntry *add_local_var_shadowable(CodeGen *g, AstNode *source_ |
| 3615 | // TODO replace _anon with @anon and make sure all tests still pass | 3615 | // TODO replace _anon with @anon and make sure all tests still pass |
| 3616 | buf_init_from_str(&variable_entry->name, "_anon"); | 3616 | buf_init_from_str(&variable_entry->name, "_anon"); |
| 3617 | } | 3617 | } |
| 3618 | if (context->fn_entry) { | ||
| 3619 | context->fn_entry->variable_list.append(variable_entry); | ||
| 3620 | } | ||
| 3618 | 3621 | ||
| 3619 | variable_entry->is_const = is_const; | 3622 | variable_entry->is_const = is_const; |
| 3620 | variable_entry->decl_node = source_node; | 3623 | variable_entry->decl_node = source_node; |
src/codegen.cpp+150-183| ... | @@ -2326,17 +2326,6 @@ static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrIns | ... | @@ -2326,17 +2326,6 @@ static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrIns |
| 2326 | return nullptr; | 2326 | return nullptr; |
| 2327 | } | 2327 | } |
| 2328 | 2328 | ||
| 2329 | static LLVMValueRef ir_render_load_var(CodeGen *g, IrExecutable *executable, | ||
| 2330 | IrInstructionLoadVar *load_var_instruction) | ||
| 2331 | { | ||
| 2332 | VariableTableEntry *var = load_var_instruction->var; | ||
| 2333 | if (!type_has_bits(var->type)) | ||
| 2334 | return nullptr; | ||
| 2335 | |||
| 2336 | assert(var->value_ref); | ||
| 2337 | return get_handle_value(g, var->value_ref, var->type); | ||
| 2338 | } | ||
| 2339 | |||
| 2340 | static LLVMValueRef ir_render_bin_op_bool(CodeGen *g, IrExecutable *executable, | 2329 | static LLVMValueRef ir_render_bin_op_bool(CodeGen *g, IrExecutable *executable, |
| 2341 | IrInstructionBinOp *bin_op_instruction) | 2330 | IrInstructionBinOp *bin_op_instruction) |
| 2342 | { | 2331 | { |
| ... | @@ -2864,6 +2853,14 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable, | ... | @@ -2864,6 +2853,14 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable, |
| 2864 | return nullptr; | 2853 | return nullptr; |
| 2865 | } | 2854 | } |
| 2866 | 2855 | ||
| 2856 | static LLVMValueRef ir_render_load_ptr(CodeGen *g, IrExecutable *executable, IrInstructionLoadPtr *instruction) { | ||
| 2857 | return LLVMBuildLoad(g->builder, ir_llvm_value(g, instruction->ptr), ""); | ||
| 2858 | } | ||
| 2859 | |||
| 2860 | static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutable *executable, IrInstructionVarPtr *instruction) { | ||
| 2861 | return instruction->var->value_ref; | ||
| 2862 | } | ||
| 2863 | |||
| 2867 | static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, IrInstruction *instruction) { | 2864 | static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, IrInstruction *instruction) { |
| 2868 | set_debug_source_node(g, instruction->source_node); | 2865 | set_debug_source_node(g, instruction->source_node); |
| 2869 | 2866 | ||
| ... | @@ -2875,8 +2872,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, | ... | @@ -2875,8 +2872,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, |
| 2875 | return ir_render_return(g, executable, (IrInstructionReturn *)instruction); | 2872 | return ir_render_return(g, executable, (IrInstructionReturn *)instruction); |
| 2876 | case IrInstructionIdDeclVar: | 2873 | case IrInstructionIdDeclVar: |
| 2877 | return ir_render_decl_var(g, executable, (IrInstructionDeclVar *)instruction); | 2874 | return ir_render_decl_var(g, executable, (IrInstructionDeclVar *)instruction); |
| 2878 | case IrInstructionIdLoadVar: | ||
| 2879 | return ir_render_load_var(g, executable, (IrInstructionLoadVar *)instruction); | ||
| 2880 | case IrInstructionIdBinOp: | 2875 | case IrInstructionIdBinOp: |
| 2881 | return ir_render_bin_op(g, executable, (IrInstructionBinOp *)instruction); | 2876 | return ir_render_bin_op(g, executable, (IrInstructionBinOp *)instruction); |
| 2882 | case IrInstructionIdCast: | 2877 | case IrInstructionIdCast: |
| ... | @@ -2889,13 +2884,19 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, | ... | @@ -2889,13 +2884,19 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, |
| 2889 | return ir_render_br(g, executable, (IrInstructionBr *)instruction); | 2884 | return ir_render_br(g, executable, (IrInstructionBr *)instruction); |
| 2890 | case IrInstructionIdUnOp: | 2885 | case IrInstructionIdUnOp: |
| 2891 | return ir_render_un_op(g, executable, (IrInstructionUnOp *)instruction); | 2886 | return ir_render_un_op(g, executable, (IrInstructionUnOp *)instruction); |
| 2887 | case IrInstructionIdLoadPtr: | ||
| 2888 | return ir_render_load_ptr(g, executable, (IrInstructionLoadPtr *)instruction); | ||
| 2889 | case IrInstructionIdVarPtr: | ||
| 2890 | return ir_render_var_ptr(g, executable, (IrInstructionVarPtr *)instruction); | ||
| 2892 | case IrInstructionIdSwitchBr: | 2891 | case IrInstructionIdSwitchBr: |
| 2893 | case IrInstructionIdPhi: | 2892 | case IrInstructionIdPhi: |
| 2894 | case IrInstructionIdStoreVar: | 2893 | case IrInstructionIdStorePtr: |
| 2895 | case IrInstructionIdCall: | 2894 | case IrInstructionIdCall: |
| 2896 | case IrInstructionIdBuiltinCall: | 2895 | case IrInstructionIdBuiltinCall: |
| 2897 | case IrInstructionIdContainerInitList: | 2896 | case IrInstructionIdContainerInitList: |
| 2898 | case IrInstructionIdContainerInitFields: | 2897 | case IrInstructionIdContainerInitFields: |
| 2898 | case IrInstructionIdFieldPtr: | ||
| 2899 | case IrInstructionIdElemPtr: | ||
| 2899 | zig_panic("TODO render more IR instructions to LLVM"); | 2900 | zig_panic("TODO render more IR instructions to LLVM"); |
| 2900 | } | 2901 | } |
| 2901 | zig_unreachable(); | 2902 | zig_unreachable(); |
| ... | @@ -3152,86 +3153,51 @@ static LLVMValueRef gen_while_expr(CodeGen *g, AstNode *node) { | ... | @@ -3152,86 +3153,51 @@ static LLVMValueRef gen_while_expr(CodeGen *g, AstNode *node) { |
| 3152 | assert(node->data.while_expr.condition); | 3153 | assert(node->data.while_expr.condition); |
| 3153 | assert(node->data.while_expr.body); | 3154 | assert(node->data.while_expr.body); |
| 3154 | 3155 | ||
| 3155 | AstNode *continue_expr_node = node->data.while_expr.continue_expr; | 3156 | //AstNode *continue_expr_node = node->data.while_expr.continue_expr; |
| 3156 | 3157 | ||
| 3157 | bool condition_always_true = node->data.while_expr.condition_always_true; | 3158 | bool condition_always_true = node->data.while_expr.condition_always_true; |
| 3158 | bool contains_break = node->data.while_expr.contains_break; | 3159 | //bool contains_break = node->data.while_expr.contains_break; |
| 3159 | if (condition_always_true) { | 3160 | if (condition_always_true) { |
| 3160 | // generate a forever loop | 3161 | // generate a forever loop |
| 3161 | 3162 | zig_panic("TODO IR"); | |
| 3162 | LLVMBasicBlockRef body_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "WhileBody"); | 3163 | |
| 3163 | LLVMBasicBlockRef continue_block = continue_expr_node ? | 3164 | //LLVMBasicBlockRef body_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "WhileBody"); |
| 3164 | LLVMAppendBasicBlock(g->cur_fn->fn_value, "WhileContinue") : body_block; | 3165 | //LLVMBasicBlockRef continue_block = continue_expr_node ? |
| 3165 | LLVMBasicBlockRef end_block = nullptr; | 3166 | // LLVMAppendBasicBlock(g->cur_fn->fn_value, "WhileContinue") : body_block; |
| 3166 | if (contains_break) { | 3167 | //LLVMBasicBlockRef end_block = nullptr; |
| 3167 | end_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "WhileEnd"); | 3168 | //if (contains_break) { |
| 3168 | } | 3169 | // end_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "WhileEnd"); |
| 3169 | 3170 | //} | |
| 3170 | set_debug_source_node(g, node); | 3171 | |
| 3171 | LLVMBuildBr(g->builder, body_block); | 3172 | //set_debug_source_node(g, node); |
| 3172 | 3173 | //LLVMBuildBr(g->builder, body_block); | |
| 3173 | if (continue_expr_node) { | 3174 | |
| 3174 | LLVMPositionBuilderAtEnd(g->builder, continue_block); | 3175 | //if (continue_expr_node) { |
| 3175 | 3176 | // LLVMPositionBuilderAtEnd(g->builder, continue_block); | |
| 3176 | gen_expr(g, continue_expr_node); | 3177 | |
| 3177 | 3178 | // gen_expr(g, continue_expr_node); | |
| 3178 | set_debug_source_node(g, node); | 3179 | |
| 3179 | LLVMBuildBr(g->builder, body_block); | 3180 | // set_debug_source_node(g, node); |
| 3180 | } | 3181 | // LLVMBuildBr(g->builder, body_block); |
| 3181 | 3182 | //} | |
| 3182 | LLVMPositionBuilderAtEnd(g->builder, body_block); | 3183 | |
| 3183 | g->break_block_stack.append(end_block); | 3184 | //LLVMPositionBuilderAtEnd(g->builder, body_block); |
| 3184 | g->continue_block_stack.append(continue_block); | 3185 | //g->break_block_stack.append(end_block); |
| 3185 | gen_expr(g, node->data.while_expr.body); | 3186 | //g->continue_block_stack.append(continue_block); |
| 3186 | g->break_block_stack.pop(); | 3187 | //gen_expr(g, node->data.while_expr.body); |
| 3187 | g->continue_block_stack.pop(); | 3188 | //g->break_block_stack.pop(); |
| 3188 | 3189 | //g->continue_block_stack.pop(); | |
| 3189 | if (get_expr_type(node->data.while_expr.body)->id != TypeTableEntryIdUnreachable) { | 3190 | |
| 3190 | set_debug_source_node(g, node); | 3191 | //if (get_expr_type(node->data.while_expr.body)->id != TypeTableEntryIdUnreachable) { |
| 3191 | LLVMBuildBr(g->builder, continue_block); | 3192 | // set_debug_source_node(g, node); |
| 3192 | } | 3193 | // LLVMBuildBr(g->builder, continue_block); |
| 3193 | 3194 | //} | |
| 3194 | if (contains_break) { | 3195 | |
| 3195 | LLVMPositionBuilderAtEnd(g->builder, end_block); | 3196 | //if (contains_break) { |
| 3196 | } | 3197 | // LLVMPositionBuilderAtEnd(g->builder, end_block); |
| 3198 | //} | ||
| 3197 | } else { | 3199 | } else { |
| 3198 | // generate a normal while loop | 3200 | zig_panic("moved to ir.cpp"); |
| 3199 | |||
| 3200 | LLVMBasicBlockRef cond_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "WhileCond"); | ||
| 3201 | LLVMBasicBlockRef body_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "WhileBody"); | ||
| 3202 | LLVMBasicBlockRef continue_block = continue_expr_node ? | ||
| 3203 | LLVMAppendBasicBlock(g->cur_fn->fn_value, "WhileContinue") : cond_block; | ||
| 3204 | LLVMBasicBlockRef end_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "WhileEnd"); | ||
| 3205 | |||
| 3206 | set_debug_source_node(g, node); | ||
| 3207 | LLVMBuildBr(g->builder, cond_block); | ||
| 3208 | |||
| 3209 | if (continue_expr_node) { | ||
| 3210 | LLVMPositionBuilderAtEnd(g->builder, continue_block); | ||
| 3211 | |||
| 3212 | gen_expr(g, continue_expr_node); | ||
| 3213 | |||
| 3214 | set_debug_source_node(g, node); | ||
| 3215 | LLVMBuildBr(g->builder, cond_block); | ||
| 3216 | } | ||
| 3217 | |||
| 3218 | LLVMPositionBuilderAtEnd(g->builder, cond_block); | ||
| 3219 | LLVMValueRef cond_val = gen_expr(g, node->data.while_expr.condition); | ||
| 3220 | set_debug_source_node(g, node->data.while_expr.condition); | ||
| 3221 | LLVMBuildCondBr(g->builder, cond_val, body_block, end_block); | ||
| 3222 | |||
| 3223 | LLVMPositionBuilderAtEnd(g->builder, body_block); | ||
| 3224 | g->break_block_stack.append(end_block); | ||
| 3225 | g->continue_block_stack.append(continue_block); | ||
| 3226 | gen_expr(g, node->data.while_expr.body); | ||
| 3227 | g->break_block_stack.pop(); | ||
| 3228 | g->continue_block_stack.pop(); | ||
| 3229 | if (get_expr_type(node->data.while_expr.body)->id != TypeTableEntryIdUnreachable) { | ||
| 3230 | set_debug_source_node(g, node); | ||
| 3231 | LLVMBuildBr(g->builder, continue_block); | ||
| 3232 | } | ||
| 3233 | |||
| 3234 | LLVMPositionBuilderAtEnd(g->builder, end_block); | ||
| 3235 | } | 3201 | } |
| 3236 | 3202 | ||
| 3237 | return nullptr; | 3203 | return nullptr; |
| ... | @@ -3242,98 +3208,99 @@ static LLVMValueRef gen_for_expr(CodeGen *g, AstNode *node) { | ... | @@ -3242,98 +3208,99 @@ static LLVMValueRef gen_for_expr(CodeGen *g, AstNode *node) { |
| 3242 | assert(node->data.for_expr.array_expr); | 3208 | assert(node->data.for_expr.array_expr); |
| 3243 | assert(node->data.for_expr.body); | 3209 | assert(node->data.for_expr.body); |
| 3244 | 3210 | ||
| 3245 | VariableTableEntry *elem_var = node->data.for_expr.elem_var; | 3211 | zig_panic("TODO IR for loop"); |
| 3246 | assert(elem_var); | 3212 | //VariableTableEntry *elem_var = node->data.for_expr.elem_var; |
| 3247 | 3213 | //assert(elem_var); | |
| 3248 | TypeTableEntry *array_type = get_expr_type(node->data.for_expr.array_expr); | 3214 | |
| 3249 | 3215 | //TypeTableEntry *array_type = get_expr_type(node->data.for_expr.array_expr); | |
| 3250 | VariableTableEntry *index_var = node->data.for_expr.index_var; | 3216 | |
| 3251 | assert(index_var); | 3217 | //VariableTableEntry *index_var = node->data.for_expr.index_var; |
| 3252 | LLVMValueRef index_ptr = index_var->value_ref; | 3218 | //assert(index_var); |
| 3253 | LLVMValueRef one_const = LLVMConstInt(g->builtin_types.entry_usize->type_ref, 1, false); | 3219 | //LLVMValueRef index_ptr = index_var->value_ref; |
| 3254 | 3220 | //LLVMValueRef one_const = LLVMConstInt(g->builtin_types.entry_usize->type_ref, 1, false); | |
| 3255 | LLVMBasicBlockRef cond_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "ForCond"); | 3221 | |
| 3256 | LLVMBasicBlockRef body_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "ForBody"); | 3222 | //LLVMBasicBlockRef cond_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "ForCond"); |
| 3257 | LLVMBasicBlockRef end_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "ForEnd"); | 3223 | //LLVMBasicBlockRef body_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "ForBody"); |
| 3258 | LLVMBasicBlockRef continue_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "ForContinue"); | 3224 | //LLVMBasicBlockRef end_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "ForEnd"); |
| 3259 | 3225 | //LLVMBasicBlockRef continue_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "ForContinue"); | |
| 3260 | LLVMValueRef array_val = gen_array_base_ptr(g, node->data.for_expr.array_expr); | 3226 | |
| 3261 | set_debug_source_node(g, node); | 3227 | //LLVMValueRef array_val = gen_array_base_ptr(g, node->data.for_expr.array_expr); |
| 3262 | LLVMBuildStore(g->builder, LLVMConstNull(index_var->type->type_ref), index_ptr); | 3228 | //set_debug_source_node(g, node); |
| 3263 | 3229 | //LLVMBuildStore(g->builder, LLVMConstNull(index_var->type->type_ref), index_ptr); | |
| 3264 | gen_var_debug_decl(g, index_var); | 3230 | |
| 3265 | 3231 | //gen_var_debug_decl(g, index_var); | |
| 3266 | LLVMValueRef len_val; | 3232 | |
| 3267 | TypeTableEntry *child_type; | 3233 | //LLVMValueRef len_val; |
| 3268 | if (array_type->id == TypeTableEntryIdArray) { | 3234 | //TypeTableEntry *child_type; |
| 3269 | len_val = LLVMConstInt(g->builtin_types.entry_usize->type_ref, | 3235 | //if (array_type->id == TypeTableEntryIdArray) { |
| 3270 | array_type->data.array.len, false); | 3236 | // len_val = LLVMConstInt(g->builtin_types.entry_usize->type_ref, |
| 3271 | child_type = array_type->data.array.child_type; | 3237 | // array_type->data.array.len, false); |
| 3272 | } else if (array_type->id == TypeTableEntryIdStruct) { | 3238 | // child_type = array_type->data.array.child_type; |
| 3273 | assert(array_type->data.structure.is_slice); | 3239 | //} else if (array_type->id == TypeTableEntryIdStruct) { |
| 3274 | TypeTableEntry *child_ptr_type = array_type->data.structure.fields[0].type_entry; | 3240 | // assert(array_type->data.structure.is_slice); |
| 3275 | assert(child_ptr_type->id == TypeTableEntryIdPointer); | 3241 | // TypeTableEntry *child_ptr_type = array_type->data.structure.fields[0].type_entry; |
| 3276 | child_type = child_ptr_type->data.pointer.child_type; | 3242 | // assert(child_ptr_type->id == TypeTableEntryIdPointer); |
| 3277 | size_t len_index = array_type->data.structure.fields[1].gen_index; | 3243 | // child_type = child_ptr_type->data.pointer.child_type; |
| 3278 | assert(len_index != SIZE_MAX); | 3244 | // size_t len_index = array_type->data.structure.fields[1].gen_index; |
| 3279 | LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, array_val, len_index, ""); | 3245 | // assert(len_index != SIZE_MAX); |
| 3280 | len_val = LLVMBuildLoad(g->builder, len_field_ptr, ""); | 3246 | // LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, array_val, len_index, ""); |
| 3281 | } else { | 3247 | // len_val = LLVMBuildLoad(g->builder, len_field_ptr, ""); |
| 3282 | zig_unreachable(); | 3248 | //} else { |
| 3283 | } | 3249 | // zig_unreachable(); |
| 3284 | LLVMBuildBr(g->builder, cond_block); | 3250 | //} |
| 3285 | 3251 | //LLVMBuildBr(g->builder, cond_block); | |
| 3286 | LLVMPositionBuilderAtEnd(g->builder, cond_block); | 3252 | |
| 3287 | LLVMValueRef index_val = LLVMBuildLoad(g->builder, index_ptr, ""); | 3253 | //LLVMPositionBuilderAtEnd(g->builder, cond_block); |
| 3288 | LLVMValueRef cond = LLVMBuildICmp(g->builder, LLVMIntSLT, index_val, len_val, ""); | 3254 | //LLVMValueRef index_val = LLVMBuildLoad(g->builder, index_ptr, ""); |
| 3289 | LLVMBuildCondBr(g->builder, cond, body_block, end_block); | 3255 | //LLVMValueRef cond = LLVMBuildICmp(g->builder, LLVMIntSLT, index_val, len_val, ""); |
| 3290 | 3256 | //LLVMBuildCondBr(g->builder, cond, body_block, end_block); | |
| 3291 | LLVMPositionBuilderAtEnd(g->builder, body_block); | 3257 | |
| 3292 | LLVMValueRef elem_ptr = gen_array_elem_ptr(g, node, array_val, array_type, index_val); | 3258 | //LLVMPositionBuilderAtEnd(g->builder, body_block); |
| 3293 | 3259 | //LLVMValueRef elem_ptr = gen_array_elem_ptr(g, node, array_val, array_type, index_val); | |
| 3294 | LLVMValueRef elem_val; | 3260 | |
| 3295 | if (node->data.for_expr.elem_is_ptr) { | 3261 | //LLVMValueRef elem_val; |
| 3296 | elem_val = elem_ptr; | 3262 | //if (node->data.for_expr.elem_is_ptr) { |
| 3297 | } else { | 3263 | // elem_val = elem_ptr; |
| 3298 | elem_val = handle_is_ptr(child_type) ? elem_ptr : LLVMBuildLoad(g->builder, elem_ptr, ""); | 3264 | //} else { |
| 3299 | } | 3265 | // elem_val = handle_is_ptr(child_type) ? elem_ptr : LLVMBuildLoad(g->builder, elem_ptr, ""); |
| 3300 | gen_assign_raw(g, node, BinOpTypeAssign, elem_var->value_ref, elem_val, elem_var->type, child_type); | 3266 | //} |
| 3301 | gen_var_debug_decl(g, elem_var); | 3267 | //gen_assign_raw(g, node, BinOpTypeAssign, elem_var->value_ref, elem_val, elem_var->type, child_type); |
| 3302 | g->break_block_stack.append(end_block); | 3268 | //gen_var_debug_decl(g, elem_var); |
| 3303 | g->continue_block_stack.append(continue_block); | 3269 | //g->break_block_stack.append(end_block); |
| 3304 | gen_expr(g, node->data.for_expr.body); | 3270 | //g->continue_block_stack.append(continue_block); |
| 3305 | g->break_block_stack.pop(); | 3271 | //gen_expr(g, node->data.for_expr.body); |
| 3306 | g->continue_block_stack.pop(); | 3272 | //g->break_block_stack.pop(); |
| 3307 | if (get_expr_type(node->data.for_expr.body)->id != TypeTableEntryIdUnreachable) { | 3273 | //g->continue_block_stack.pop(); |
| 3308 | set_debug_source_node(g, node); | 3274 | //if (get_expr_type(node->data.for_expr.body)->id != TypeTableEntryIdUnreachable) { |
| 3309 | LLVMBuildBr(g->builder, continue_block); | 3275 | // set_debug_source_node(g, node); |
| 3310 | } | 3276 | // LLVMBuildBr(g->builder, continue_block); |
| 3311 | 3277 | //} | |
| 3312 | LLVMPositionBuilderAtEnd(g->builder, continue_block); | 3278 | |
| 3313 | set_debug_source_node(g, node); | 3279 | //LLVMPositionBuilderAtEnd(g->builder, continue_block); |
| 3314 | LLVMValueRef new_index_val = LLVMBuildNSWAdd(g->builder, index_val, one_const, ""); | 3280 | //set_debug_source_node(g, node); |
| 3315 | LLVMBuildStore(g->builder, new_index_val, index_ptr); | 3281 | //LLVMValueRef new_index_val = LLVMBuildNSWAdd(g->builder, index_val, one_const, ""); |
| 3316 | LLVMBuildBr(g->builder, cond_block); | 3282 | //LLVMBuildStore(g->builder, new_index_val, index_ptr); |
| 3317 | 3283 | //LLVMBuildBr(g->builder, cond_block); | |
| 3318 | LLVMPositionBuilderAtEnd(g->builder, end_block); | 3284 | |
| 3319 | return nullptr; | 3285 | //LLVMPositionBuilderAtEnd(g->builder, end_block); |
| 3320 | } | 3286 | //return nullptr; |
| 3321 | 3287 | } | |
| 3322 | static LLVMValueRef gen_break(CodeGen *g, AstNode *node) { | 3288 | |
| 3323 | assert(node->type == NodeTypeBreak); | 3289 | //static LLVMValueRef gen_break(CodeGen *g, AstNode *node) { |
| 3324 | LLVMBasicBlockRef dest_block = g->break_block_stack.last(); | 3290 | // assert(node->type == NodeTypeBreak); |
| 3325 | 3291 | // LLVMBasicBlockRef dest_block = g->break_block_stack.last(); | |
| 3326 | set_debug_source_node(g, node); | 3292 | // |
| 3327 | return LLVMBuildBr(g->builder, dest_block); | 3293 | // set_debug_source_node(g, node); |
| 3328 | } | 3294 | // return LLVMBuildBr(g->builder, dest_block); |
| 3329 | 3295 | //} | |
| 3330 | static LLVMValueRef gen_continue(CodeGen *g, AstNode *node) { | 3296 | |
| 3331 | assert(node->type == NodeTypeContinue); | 3297 | //static LLVMValueRef gen_continue(CodeGen *g, AstNode *node) { |
| 3332 | LLVMBasicBlockRef dest_block = g->continue_block_stack.last(); | 3298 | // assert(node->type == NodeTypeContinue); |
| 3333 | 3299 | // LLVMBasicBlockRef dest_block = g->continue_block_stack.last(); | |
| 3334 | set_debug_source_node(g, node); | 3300 | // |
| 3335 | return LLVMBuildBr(g->builder, dest_block); | 3301 | // set_debug_source_node(g, node); |
| 3336 | } | 3302 | // return LLVMBuildBr(g->builder, dest_block); |
| 3303 | //} | ||
| 3337 | 3304 | ||
| 3338 | static LLVMValueRef gen_var_decl_raw(CodeGen *g, AstNode *source_node, AstNodeVariableDeclaration *var_decl, | 3305 | static LLVMValueRef gen_var_decl_raw(CodeGen *g, AstNode *source_node, AstNodeVariableDeclaration *var_decl, |
| 3339 | bool unwrap_maybe, LLVMValueRef *init_value, TypeTableEntry **expr_type, bool var_is_ptr) | 3306 | bool unwrap_maybe, LLVMValueRef *init_value, TypeTableEntry **expr_type, bool var_is_ptr) |
| ... | @@ -3735,9 +3702,9 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) { | ... | @@ -3735,9 +3702,9 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) { |
| 3735 | case NodeTypeGoto: | 3702 | case NodeTypeGoto: |
| 3736 | return gen_goto(g, node); | 3703 | return gen_goto(g, node); |
| 3737 | case NodeTypeBreak: | 3704 | case NodeTypeBreak: |
| 3738 | return gen_break(g, node); | 3705 | zig_panic("TODO IR"); |
| 3739 | case NodeTypeContinue: | 3706 | case NodeTypeContinue: |
| 3740 | return gen_continue(g, node); | 3707 | zig_panic("TODO IR"); |
| 3741 | case NodeTypeLabel: | 3708 | case NodeTypeLabel: |
| 3742 | return gen_label(g, node); | 3709 | return gen_label(g, node); |
| 3743 | case NodeTypeContainerInitExpr: | 3710 | case NodeTypeContainerInitExpr: |
src/ir.cpp+293-69| ... | @@ -3,20 +3,17 @@ | ... | @@ -3,20 +3,17 @@ |
| 3 | #include "eval.hpp" | 3 | #include "eval.hpp" |
| 4 | #include "ir.hpp" | 4 | #include "ir.hpp" |
| 5 | 5 | ||
| 6 | struct IrVarSlot { | ||
| 7 | ConstExprValue value; | ||
| 8 | bool runtime; | ||
| 9 | }; | ||
| 10 | |||
| 11 | struct IrExecContext { | 6 | struct IrExecContext { |
| 12 | IrVarSlot *var_slot_list; | 7 | ConstExprValue *mem_slot_list; |
| 13 | size_t var_slot_count; | 8 | size_t mem_slot_count; |
| 14 | }; | 9 | }; |
| 15 | 10 | ||
| 16 | struct IrBuilder { | 11 | struct IrBuilder { |
| 17 | CodeGen *codegen; | 12 | CodeGen *codegen; |
| 18 | IrExecutable *exec; | 13 | IrExecutable *exec; |
| 19 | IrBasicBlock *current_basic_block; | 14 | IrBasicBlock *current_basic_block; |
| 15 | ZigList<IrBasicBlock *> break_block_stack; | ||
| 16 | ZigList<IrBasicBlock *> continue_block_stack; | ||
| 20 | }; | 17 | }; |
| 21 | 18 | ||
| 22 | struct IrAnalyze { | 19 | struct IrAnalyze { |
| ... | @@ -27,6 +24,7 @@ struct IrAnalyze { | ... | @@ -27,6 +24,7 @@ struct IrAnalyze { |
| 27 | }; | 24 | }; |
| 28 | 25 | ||
| 29 | static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, BlockContext *scope); | 26 | static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, BlockContext *scope); |
| 27 | static IrInstruction *ir_gen_lvalue(IrBuilder *irb, AstNode *node, BlockContext *scope); | ||
| 30 | 28 | ||
| 31 | static void ir_instruction_append(IrBasicBlock *basic_block, IrInstruction *instruction) { | 29 | static void ir_instruction_append(IrBasicBlock *basic_block, IrInstruction *instruction) { |
| 32 | assert(basic_block); | 30 | assert(basic_block); |
| ... | @@ -40,9 +38,9 @@ static size_t exec_next_debug_id(IrExecutable *exec) { | ... | @@ -40,9 +38,9 @@ static size_t exec_next_debug_id(IrExecutable *exec) { |
| 40 | return result; | 38 | return result; |
| 41 | } | 39 | } |
| 42 | 40 | ||
| 43 | static size_t exec_next_var_slot(IrExecutable *exec) { | 41 | static size_t exec_next_mem_slot(IrExecutable *exec) { |
| 44 | size_t result = exec->var_slot_count; | 42 | size_t result = exec->mem_slot_count; |
| 45 | exec->var_slot_count += 1; | 43 | exec->mem_slot_count += 1; |
| 46 | return result; | 44 | return result; |
| 47 | } | 45 | } |
| 48 | 46 | ||
| ... | @@ -115,12 +113,24 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionDeclVar *) { | ... | @@ -115,12 +113,24 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionDeclVar *) { |
| 115 | return IrInstructionIdDeclVar; | 113 | return IrInstructionIdDeclVar; |
| 116 | } | 114 | } |
| 117 | 115 | ||
| 118 | static constexpr IrInstructionId ir_instruction_id(IrInstructionLoadVar *) { | 116 | static constexpr IrInstructionId ir_instruction_id(IrInstructionLoadPtr *) { |
| 119 | return IrInstructionIdLoadVar; | 117 | return IrInstructionIdLoadPtr; |
| 120 | } | 118 | } |
| 121 | 119 | ||
| 122 | static constexpr IrInstructionId ir_instruction_id(IrInstructionStoreVar *) { | 120 | static constexpr IrInstructionId ir_instruction_id(IrInstructionStorePtr *) { |
| 123 | return IrInstructionIdStoreVar; | 121 | return IrInstructionIdStorePtr; |
| 122 | } | ||
| 123 | |||
| 124 | static constexpr IrInstructionId ir_instruction_id(IrInstructionFieldPtr *) { | ||
| 125 | return IrInstructionIdFieldPtr; | ||
| 126 | } | ||
| 127 | |||
| 128 | static constexpr IrInstructionId ir_instruction_id(IrInstructionElemPtr *) { | ||
| 129 | return IrInstructionIdElemPtr; | ||
| 130 | } | ||
| 131 | |||
| 132 | static constexpr IrInstructionId ir_instruction_id(IrInstructionVarPtr *) { | ||
| 133 | return IrInstructionIdVarPtr; | ||
| 124 | } | 134 | } |
| 125 | 135 | ||
| 126 | static constexpr IrInstructionId ir_instruction_id(IrInstructionCall *) { | 136 | static constexpr IrInstructionId ir_instruction_id(IrInstructionCall *) { |
| ... | @@ -283,6 +293,37 @@ static IrInstruction *ir_build_const_generic_fn(IrBuilder *irb, AstNode *source_ | ... | @@ -283,6 +293,37 @@ static IrInstruction *ir_build_const_generic_fn(IrBuilder *irb, AstNode *source_ |
| 283 | return &const_instruction->base; | 293 | return &const_instruction->base; |
| 284 | } | 294 | } |
| 285 | 295 | ||
| 296 | static IrInstruction *ir_build_const_ptr(IrBuilder *irb, AstNode *source_node, ConstExprValue *pointee) { | ||
| 297 | IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node); | ||
| 298 | const_instruction->base.static_value.ok = true; | ||
| 299 | const_instruction->base.static_value.data.x_ptr.len = 1; | ||
| 300 | const_instruction->base.static_value.data.x_ptr.is_c_str = false; | ||
| 301 | const_instruction->base.static_value.data.x_ptr.ptr = allocate<ConstExprValue *>(1); | ||
| 302 | const_instruction->base.static_value.data.x_ptr.ptr[0] = pointee; | ||
| 303 | return &const_instruction->base; | ||
| 304 | } | ||
| 305 | |||
| 306 | static IrInstruction *ir_build_const_ptr_from(IrBuilder *irb, IrInstruction *old_instruction, | ||
| 307 | ConstExprValue *pointee) | ||
| 308 | { | ||
| 309 | IrInstruction *new_instruction = ir_build_const_ptr(irb, old_instruction->source_node, pointee); | ||
| 310 | ir_link_new_instruction(new_instruction, old_instruction); | ||
| 311 | return new_instruction; | ||
| 312 | } | ||
| 313 | |||
| 314 | static IrInstruction *ir_build_const(IrBuilder *irb, AstNode *source_node, ConstExprValue *value) { | ||
| 315 | IrInstructionConst *instruction = ir_build_instruction<IrInstructionConst>(irb, source_node); | ||
| 316 | instruction->base.static_value = *value; | ||
| 317 | instruction->base.static_value.ok = true; | ||
| 318 | return &instruction->base; | ||
| 319 | } | ||
| 320 | |||
| 321 | static IrInstruction *ir_build_const_from(IrBuilder *irb, IrInstruction *old_instruction, ConstExprValue *value) { | ||
| 322 | IrInstruction *new_instruction = ir_build_const(irb, old_instruction->source_node, value); | ||
| 323 | ir_link_new_instruction(new_instruction, old_instruction); | ||
| 324 | return new_instruction; | ||
| 325 | } | ||
| 326 | |||
| 286 | static IrInstruction *ir_build_bin_op(IrBuilder *irb, AstNode *source_node, IrBinOp op_id, | 327 | static IrInstruction *ir_build_bin_op(IrBuilder *irb, AstNode *source_node, IrBinOp op_id, |
| 287 | IrInstruction *op1, IrInstruction *op2) | 328 | IrInstruction *op1, IrInstruction *op2) |
| 288 | { | 329 | { |
| ... | @@ -305,20 +346,19 @@ static IrInstruction *ir_build_bin_op_from(IrBuilder *irb, IrInstruction *old_in | ... | @@ -305,20 +346,19 @@ static IrInstruction *ir_build_bin_op_from(IrBuilder *irb, IrInstruction *old_in |
| 305 | return new_instruction; | 346 | return new_instruction; |
| 306 | } | 347 | } |
| 307 | 348 | ||
| 308 | static IrInstruction *ir_build_load_var(IrBuilder *irb, AstNode *source_node, VariableTableEntry *var) { | 349 | static IrInstruction *ir_build_var_ptr(IrBuilder *irb, AstNode *source_node, VariableTableEntry *var) { |
| 309 | IrInstructionLoadVar *load_var_instruction = ir_build_instruction<IrInstructionLoadVar>(irb, source_node); | 350 | IrInstructionVarPtr *instruction = ir_build_instruction<IrInstructionVarPtr>(irb, source_node); |
| 310 | load_var_instruction->base.type_entry = var->type; | 351 | instruction->var = var; |
| 311 | load_var_instruction->var = var; | ||
| 312 | 352 | ||
| 313 | ir_ref_var(var); | 353 | ir_ref_var(var); |
| 314 | 354 | ||
| 315 | return &load_var_instruction->base; | 355 | return &instruction->base; |
| 316 | } | 356 | } |
| 317 | 357 | ||
| 318 | static IrInstruction *ir_build_load_var_from(IrBuilder *irb, IrInstruction *old_instruction, | 358 | static IrInstruction *ir_build_var_ptr_from(IrBuilder *irb, IrInstruction *old_instruction, |
| 319 | VariableTableEntry *var) | 359 | VariableTableEntry *var) |
| 320 | { | 360 | { |
| 321 | IrInstruction *new_instruction = ir_build_load_var(irb, old_instruction->source_node, var); | 361 | IrInstruction *new_instruction = ir_build_var_ptr(irb, old_instruction->source_node, var); |
| 322 | ir_link_new_instruction(new_instruction, old_instruction); | 362 | ir_link_new_instruction(new_instruction, old_instruction); |
| 323 | return new_instruction; | 363 | return new_instruction; |
| 324 | 364 | ||
| ... | @@ -460,16 +500,20 @@ static IrInstruction *ir_build_unreachable_from(IrBuilder *irb, IrInstruction *o | ... | @@ -460,16 +500,20 @@ static IrInstruction *ir_build_unreachable_from(IrBuilder *irb, IrInstruction *o |
| 460 | return new_instruction; | 500 | return new_instruction; |
| 461 | } | 501 | } |
| 462 | 502 | ||
| 463 | //static IrInstruction *ir_build_store(IrBuilder *irb, AstNode *source_node, | 503 | static IrInstruction *ir_build_store_ptr(IrBuilder *irb, AstNode *source_node, |
| 464 | // VariableTableEntry *var, IrInstruction *value) | 504 | IrInstruction *ptr, IrInstruction *value) |
| 465 | //{ | 505 | { |
| 466 | // IrInstructionStoreVar *store_instruction = ir_build_instruction<IrInstructionStoreVar>(irb, source_node); | 506 | IrInstructionStorePtr *instruction = ir_build_instruction<IrInstructionStorePtr>(irb, source_node); |
| 467 | // store_instruction->base.static_value.ok = true; | 507 | instruction->base.static_value.ok = true; |
| 468 | // store_instruction->base.type_entry = irb->codegen->builtin_types.entry_void; | 508 | instruction->base.type_entry = irb->codegen->builtin_types.entry_void; |
| 469 | // store_instruction->var = var; | 509 | instruction->ptr = ptr; |
| 470 | // store_instruction->value = value; | 510 | instruction->value = value; |
| 471 | // return &store_instruction->base; | 511 | |
| 472 | //} | 512 | ir_ref_instruction(ptr); |
| 513 | ir_ref_instruction(value); | ||
| 514 | |||
| 515 | return &instruction->base; | ||
| 516 | } | ||
| 473 | 517 | ||
| 474 | static IrInstruction *ir_build_var_decl(IrBuilder *irb, AstNode *source_node, | 518 | static IrInstruction *ir_build_var_decl(IrBuilder *irb, AstNode *source_node, |
| 475 | VariableTableEntry *var, IrInstruction *var_type, IrInstruction *init_value) | 519 | VariableTableEntry *var, IrInstruction *var_type, IrInstruction *init_value) |
| ... | @@ -480,6 +524,10 @@ static IrInstruction *ir_build_var_decl(IrBuilder *irb, AstNode *source_node, | ... | @@ -480,6 +524,10 @@ static IrInstruction *ir_build_var_decl(IrBuilder *irb, AstNode *source_node, |
| 480 | decl_var_instruction->var = var; | 524 | decl_var_instruction->var = var; |
| 481 | decl_var_instruction->var_type = var_type; | 525 | decl_var_instruction->var_type = var_type; |
| 482 | decl_var_instruction->init_value = init_value; | 526 | decl_var_instruction->init_value = init_value; |
| 527 | |||
| 528 | ir_ref_instruction(var_type); | ||
| 529 | ir_ref_instruction(init_value); | ||
| 530 | |||
| 483 | return &decl_var_instruction->base; | 531 | return &decl_var_instruction->base; |
| 484 | } | 532 | } |
| 485 | 533 | ||
| ... | @@ -491,6 +539,21 @@ static IrInstruction *ir_build_var_decl_from(IrBuilder *irb, IrInstruction *old_ | ... | @@ -491,6 +539,21 @@ static IrInstruction *ir_build_var_decl_from(IrBuilder *irb, IrInstruction *old_ |
| 491 | return new_instruction; | 539 | return new_instruction; |
| 492 | } | 540 | } |
| 493 | 541 | ||
| 542 | static IrInstruction *ir_build_load_ptr(IrBuilder *irb, AstNode *source_node, IrInstruction *ptr) { | ||
| 543 | IrInstructionLoadPtr *instruction = ir_build_instruction<IrInstructionLoadPtr>(irb, source_node); | ||
| 544 | instruction->ptr = ptr; | ||
| 545 | |||
| 546 | ir_ref_instruction(ptr); | ||
| 547 | |||
| 548 | return &instruction->base; | ||
| 549 | } | ||
| 550 | |||
| 551 | static IrInstruction *ir_build_load_ptr_from(IrBuilder *irb, IrInstruction *old_instruction, IrInstruction *ptr) { | ||
| 552 | IrInstruction *new_instruction = ir_build_load_ptr(irb, old_instruction->source_node, ptr); | ||
| 553 | ir_link_new_instruction(new_instruction, old_instruction); | ||
| 554 | return new_instruction; | ||
| 555 | } | ||
| 556 | |||
| 494 | //static size_t get_conditional_defer_count(BlockContext *inner_block, BlockContext *outer_block) { | 557 | //static size_t get_conditional_defer_count(BlockContext *inner_block, BlockContext *outer_block) { |
| 495 | // size_t result = 0; | 558 | // size_t result = 0; |
| 496 | // while (inner_block != outer_block) { | 559 | // while (inner_block != outer_block) { |
| ... | @@ -552,7 +615,7 @@ static VariableTableEntry *ir_add_local_var(IrBuilder *irb, AstNode *node, Buf * | ... | @@ -552,7 +615,7 @@ static VariableTableEntry *ir_add_local_var(IrBuilder *irb, AstNode *node, Buf * |
| 552 | variable_entry->block_context = node->block_context; | 615 | variable_entry->block_context = node->block_context; |
| 553 | variable_entry->import = node->owner; | 616 | variable_entry->import = node->owner; |
| 554 | variable_entry->shadowable = is_shadowable; | 617 | variable_entry->shadowable = is_shadowable; |
| 555 | variable_entry->slot_index = exec_next_var_slot(irb->exec); | 618 | variable_entry->mem_slot_index = exec_next_mem_slot(irb->exec); |
| 556 | 619 | ||
| 557 | if (name) { | 620 | if (name) { |
| 558 | buf_init_from_buf(&variable_entry->name, name); | 621 | buf_init_from_buf(&variable_entry->name, name); |
| ... | @@ -625,6 +688,19 @@ static IrInstruction *ir_gen_bin_op_id(IrBuilder *irb, AstNode *node, IrBinOp op | ... | @@ -625,6 +688,19 @@ static IrInstruction *ir_gen_bin_op_id(IrBuilder *irb, AstNode *node, IrBinOp op |
| 625 | return ir_build_bin_op(irb, node, op_id, op1, op2); | 688 | return ir_build_bin_op(irb, node, op_id, op1, op2); |
| 626 | } | 689 | } |
| 627 | 690 | ||
| 691 | static IrInstruction *ir_gen_assign_op(IrBuilder *irb, AstNode *node, IrBinOp op_id) { | ||
| 692 | IrInstruction *lvalue = ir_gen_lvalue(irb, node->data.bin_op_expr.op1, node->block_context); | ||
| 693 | if (lvalue == irb->codegen->invalid_instruction) | ||
| 694 | return lvalue; | ||
| 695 | IrInstruction *op1 = ir_build_load_ptr(irb, node->data.bin_op_expr.op1, lvalue); | ||
| 696 | IrInstruction *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, node->block_context); | ||
| 697 | if (op2 == irb->codegen->invalid_instruction) | ||
| 698 | return op2; | ||
| 699 | IrInstruction *result = ir_build_bin_op(irb, node, op_id, op1, op2); | ||
| 700 | ir_build_store_ptr(irb, node, lvalue, result); | ||
| 701 | return ir_build_const_void(irb, node); | ||
| 702 | } | ||
| 703 | |||
| 628 | static IrInstruction *ir_gen_bin_op(IrBuilder *irb, AstNode *node) { | 704 | static IrInstruction *ir_gen_bin_op(IrBuilder *irb, AstNode *node) { |
| 629 | assert(node->type == NodeTypeBinOpExpr); | 705 | assert(node->type == NodeTypeBinOpExpr); |
| 630 | 706 | ||
| ... | @@ -633,23 +709,39 @@ static IrInstruction *ir_gen_bin_op(IrBuilder *irb, AstNode *node) { | ... | @@ -633,23 +709,39 @@ static IrInstruction *ir_gen_bin_op(IrBuilder *irb, AstNode *node) { |
| 633 | case BinOpTypeInvalid: | 709 | case BinOpTypeInvalid: |
| 634 | zig_unreachable(); | 710 | zig_unreachable(); |
| 635 | case BinOpTypeAssign: | 711 | case BinOpTypeAssign: |
| 712 | zig_panic("TODO gen IR for assignment"); | ||
| 636 | case BinOpTypeAssignTimes: | 713 | case BinOpTypeAssignTimes: |
| 714 | return ir_gen_assign_op(irb, node, IrBinOpMult); | ||
| 637 | case BinOpTypeAssignTimesWrap: | 715 | case BinOpTypeAssignTimesWrap: |
| 716 | return ir_gen_assign_op(irb, node, IrBinOpMultWrap); | ||
| 638 | case BinOpTypeAssignDiv: | 717 | case BinOpTypeAssignDiv: |
| 718 | return ir_gen_assign_op(irb, node, IrBinOpDiv); | ||
| 639 | case BinOpTypeAssignMod: | 719 | case BinOpTypeAssignMod: |
| 720 | return ir_gen_assign_op(irb, node, IrBinOpMod); | ||
| 640 | case BinOpTypeAssignPlus: | 721 | case BinOpTypeAssignPlus: |
| 722 | return ir_gen_assign_op(irb, node, IrBinOpAdd); | ||
| 641 | case BinOpTypeAssignPlusWrap: | 723 | case BinOpTypeAssignPlusWrap: |
| 724 | return ir_gen_assign_op(irb, node, IrBinOpAddWrap); | ||
| 642 | case BinOpTypeAssignMinus: | 725 | case BinOpTypeAssignMinus: |
| 726 | return ir_gen_assign_op(irb, node, IrBinOpSub); | ||
| 643 | case BinOpTypeAssignMinusWrap: | 727 | case BinOpTypeAssignMinusWrap: |
| 728 | return ir_gen_assign_op(irb, node, IrBinOpSubWrap); | ||
| 644 | case BinOpTypeAssignBitShiftLeft: | 729 | case BinOpTypeAssignBitShiftLeft: |
| 730 | return ir_gen_assign_op(irb, node, IrBinOpBitShiftLeft); | ||
| 645 | case BinOpTypeAssignBitShiftLeftWrap: | 731 | case BinOpTypeAssignBitShiftLeftWrap: |
| 732 | return ir_gen_assign_op(irb, node, IrBinOpBitShiftLeftWrap); | ||
| 646 | case BinOpTypeAssignBitShiftRight: | 733 | case BinOpTypeAssignBitShiftRight: |
| 734 | return ir_gen_assign_op(irb, node, IrBinOpBitShiftRight); | ||
| 647 | case BinOpTypeAssignBitAnd: | 735 | case BinOpTypeAssignBitAnd: |
| 736 | return ir_gen_assign_op(irb, node, IrBinOpBinAnd); | ||
| 648 | case BinOpTypeAssignBitXor: | 737 | case BinOpTypeAssignBitXor: |
| 738 | return ir_gen_assign_op(irb, node, IrBinOpBinXor); | ||
| 649 | case BinOpTypeAssignBitOr: | 739 | case BinOpTypeAssignBitOr: |
| 740 | return ir_gen_assign_op(irb, node, IrBinOpBinOr); | ||
| 650 | case BinOpTypeAssignBoolAnd: | 741 | case BinOpTypeAssignBoolAnd: |
| 742 | return ir_gen_assign_op(irb, node, IrBinOpBoolAnd); | ||
| 651 | case BinOpTypeAssignBoolOr: | 743 | case BinOpTypeAssignBoolOr: |
| 652 | zig_panic("TODO gen IR for assignment"); | 744 | return ir_gen_assign_op(irb, node, IrBinOpBoolOr); |
| 653 | case BinOpTypeBoolOr: | 745 | case BinOpTypeBoolOr: |
| 654 | case BinOpTypeBoolAnd: | 746 | case BinOpTypeBoolAnd: |
| 655 | // note: this is not a direct mapping to IrBinOpBoolOr/And | 747 | // note: this is not a direct mapping to IrBinOpBoolOr/And |
| ... | @@ -726,7 +818,8 @@ static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, AstN | ... | @@ -726,7 +818,8 @@ static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, AstN |
| 726 | 818 | ||
| 727 | if (decl_node->type == NodeTypeVariableDeclaration) { | 819 | if (decl_node->type == NodeTypeVariableDeclaration) { |
| 728 | VariableTableEntry *var = decl_node->data.variable_declaration.variable; | 820 | VariableTableEntry *var = decl_node->data.variable_declaration.variable; |
| 729 | return ir_build_load_var(irb, source_node, var); | 821 | IrInstruction *var_ptr = ir_build_var_ptr(irb, source_node, var); |
| 822 | return ir_build_load_ptr(irb, source_node, var_ptr); | ||
| 730 | } else if (decl_node->type == NodeTypeFnProto) { | 823 | } else if (decl_node->type == NodeTypeFnProto) { |
| 731 | FnTableEntry *fn_entry = decl_node->data.fn_proto.fn_table_entry; | 824 | FnTableEntry *fn_entry = decl_node->data.fn_proto.fn_table_entry; |
| 732 | assert(fn_entry->type_entry); | 825 | assert(fn_entry->type_entry); |
| ... | @@ -763,8 +856,10 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, AstNode *node, bool pointer_ | ... | @@ -763,8 +856,10 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, AstNode *node, bool pointer_ |
| 763 | return ir_build_const_type(irb, node, primitive_table_entry->value); | 856 | return ir_build_const_type(irb, node, primitive_table_entry->value); |
| 764 | 857 | ||
| 765 | VariableTableEntry *var = find_variable(irb->codegen, node->block_context, variable_name); | 858 | VariableTableEntry *var = find_variable(irb->codegen, node->block_context, variable_name); |
| 766 | if (var) | 859 | if (var) { |
| 767 | return ir_build_load_var(irb, node, var); | 860 | IrInstruction *var_ptr = ir_build_var_ptr(irb, node, var); |
| 861 | return ir_build_load_ptr(irb, node, var_ptr); | ||
| 862 | } | ||
| 768 | 863 | ||
| 769 | AstNode *decl_node = find_decl(node->block_context, variable_name); | 864 | AstNode *decl_node = find_decl(node->block_context, variable_name); |
| 770 | if (decl_node) | 865 | if (decl_node) |
| ... | @@ -1011,6 +1106,44 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, AstNode *node) { | ... | @@ -1011,6 +1106,44 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, AstNode *node) { |
| 1011 | return ir_build_var_decl(irb, node, var, type_instruction, init_value); | 1106 | return ir_build_var_decl(irb, node, var, type_instruction, init_value); |
| 1012 | } | 1107 | } |
| 1013 | 1108 | ||
| 1109 | static IrInstruction *ir_gen_while_expr(IrBuilder *irb, AstNode *node) { | ||
| 1110 | assert(node->type == NodeTypeWhileExpr); | ||
| 1111 | |||
| 1112 | AstNode *continue_expr_node = node->data.while_expr.continue_expr; | ||
| 1113 | |||
| 1114 | IrBasicBlock *cond_block = ir_build_basic_block(irb, "WhileCond"); | ||
| 1115 | IrBasicBlock *body_block = ir_build_basic_block(irb, "WhileBody"); | ||
| 1116 | IrBasicBlock *continue_block = continue_expr_node ? | ||
| 1117 | ir_build_basic_block(irb, "WhileContinue") : cond_block; | ||
| 1118 | IrBasicBlock *end_block = ir_build_basic_block(irb, "WhileEnd"); | ||
| 1119 | |||
| 1120 | ir_build_br(irb, node, cond_block); | ||
| 1121 | |||
| 1122 | if (continue_expr_node) { | ||
| 1123 | ir_set_cursor_at_end(irb, continue_block); | ||
| 1124 | ir_gen_node(irb, continue_expr_node, node->block_context); | ||
| 1125 | ir_build_br(irb, node, cond_block); | ||
| 1126 | |||
| 1127 | } | ||
| 1128 | |||
| 1129 | ir_set_cursor_at_end(irb, cond_block); | ||
| 1130 | IrInstruction *cond_val = ir_gen_node(irb, node->data.while_expr.condition, node->block_context); | ||
| 1131 | ir_build_cond_br(irb, node->data.while_expr.condition, cond_val, body_block, end_block); | ||
| 1132 | |||
| 1133 | ir_set_cursor_at_end(irb, body_block); | ||
| 1134 | |||
| 1135 | irb->break_block_stack.append(end_block); | ||
| 1136 | irb->continue_block_stack.append(continue_block); | ||
| 1137 | ir_gen_node(irb, node->data.while_expr.body, node->block_context); | ||
| 1138 | irb->break_block_stack.pop(); | ||
| 1139 | irb->continue_block_stack.pop(); | ||
| 1140 | |||
| 1141 | ir_build_br(irb, node, continue_block); | ||
| 1142 | ir_set_cursor_at_end(irb, end_block); | ||
| 1143 | |||
| 1144 | return ir_build_const_void(irb, node); | ||
| 1145 | } | ||
| 1146 | |||
| 1014 | static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockContext *block_context, | 1147 | static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockContext *block_context, |
| 1015 | bool pointer_only) | 1148 | bool pointer_only) |
| 1016 | { | 1149 | { |
| ... | @@ -1036,6 +1169,8 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockCont | ... | @@ -1036,6 +1169,8 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockCont |
| 1036 | return ir_gen_container_init_expr(irb, node); | 1169 | return ir_gen_container_init_expr(irb, node); |
| 1037 | case NodeTypeVariableDeclaration: | 1170 | case NodeTypeVariableDeclaration: |
| 1038 | return ir_gen_var_decl(irb, node); | 1171 | return ir_gen_var_decl(irb, node); |
| 1172 | case NodeTypeWhileExpr: | ||
| 1173 | return ir_gen_while_expr(irb, node); | ||
| 1039 | case NodeTypeUnwrapErrorExpr: | 1174 | case NodeTypeUnwrapErrorExpr: |
| 1040 | case NodeTypeReturnExpr: | 1175 | case NodeTypeReturnExpr: |
| 1041 | case NodeTypeDefer: | 1176 | case NodeTypeDefer: |
| ... | @@ -1043,7 +1178,6 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockCont | ... | @@ -1043,7 +1178,6 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockCont |
| 1043 | case NodeTypeSliceExpr: | 1178 | case NodeTypeSliceExpr: |
| 1044 | case NodeTypeFieldAccessExpr: | 1179 | case NodeTypeFieldAccessExpr: |
| 1045 | case NodeTypeIfVarExpr: | 1180 | case NodeTypeIfVarExpr: |
| 1046 | case NodeTypeWhileExpr: | ||
| 1047 | case NodeTypeForExpr: | 1181 | case NodeTypeForExpr: |
| 1048 | case NodeTypeAsmExpr: | 1182 | case NodeTypeAsmExpr: |
| 1049 | case NodeTypeGoto: | 1183 | case NodeTypeGoto: |
| ... | @@ -1085,6 +1219,67 @@ static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, BlockContext *s | ... | @@ -1085,6 +1219,67 @@ static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, BlockContext *s |
| 1085 | return ir_gen_node_extra(irb, node, scope, pointer_only_no); | 1219 | return ir_gen_node_extra(irb, node, scope, pointer_only_no); |
| 1086 | } | 1220 | } |
| 1087 | 1221 | ||
| 1222 | static IrInstruction *ir_gen_lvalue(IrBuilder *irb, AstNode *node, BlockContext *scope) { | ||
| 1223 | assert(scope); | ||
| 1224 | node->block_context = scope; | ||
| 1225 | switch (node->type) { | ||
| 1226 | case NodeTypeSymbol: | ||
| 1227 | zig_panic("TODO symbol lvalue"); | ||
| 1228 | case NodeTypeArrayAccessExpr: | ||
| 1229 | zig_panic("TODO array access lvalue"); | ||
| 1230 | case NodeTypeFieldAccessExpr: | ||
| 1231 | zig_panic("TODO field access lvalue"); | ||
| 1232 | case NodeTypePrefixOpExpr: | ||
| 1233 | zig_panic("TODO prefix op lvalue"); | ||
| 1234 | case NodeTypeBlock: | ||
| 1235 | case NodeTypeBinOpExpr: | ||
| 1236 | case NodeTypeNumberLiteral: | ||
| 1237 | case NodeTypeFnCallExpr: | ||
| 1238 | case NodeTypeIfBoolExpr: | ||
| 1239 | case NodeTypeContainerInitExpr: | ||
| 1240 | case NodeTypeVariableDeclaration: | ||
| 1241 | case NodeTypeWhileExpr: | ||
| 1242 | case NodeTypeUnwrapErrorExpr: | ||
| 1243 | case NodeTypeReturnExpr: | ||
| 1244 | case NodeTypeDefer: | ||
| 1245 | case NodeTypeSliceExpr: | ||
| 1246 | case NodeTypeIfVarExpr: | ||
| 1247 | case NodeTypeForExpr: | ||
| 1248 | case NodeTypeAsmExpr: | ||
| 1249 | case NodeTypeGoto: | ||
| 1250 | case NodeTypeBreak: | ||
| 1251 | case NodeTypeContinue: | ||
| 1252 | case NodeTypeLabel: | ||
| 1253 | case NodeTypeSwitchExpr: | ||
| 1254 | case NodeTypeBoolLiteral: | ||
| 1255 | case NodeTypeStringLiteral: | ||
| 1256 | case NodeTypeCharLiteral: | ||
| 1257 | case NodeTypeNullLiteral: | ||
| 1258 | case NodeTypeUndefinedLiteral: | ||
| 1259 | case NodeTypeZeroesLiteral: | ||
| 1260 | case NodeTypeThisLiteral: | ||
| 1261 | case NodeTypeErrorType: | ||
| 1262 | case NodeTypeTypeLiteral: | ||
| 1263 | case NodeTypeArrayType: | ||
| 1264 | case NodeTypeVarLiteral: | ||
| 1265 | case NodeTypeRoot: | ||
| 1266 | case NodeTypeFnProto: | ||
| 1267 | case NodeTypeFnDef: | ||
| 1268 | case NodeTypeFnDecl: | ||
| 1269 | case NodeTypeParamDecl: | ||
| 1270 | case NodeTypeUse: | ||
| 1271 | case NodeTypeContainerDecl: | ||
| 1272 | case NodeTypeStructField: | ||
| 1273 | case NodeTypeStructValueField: | ||
| 1274 | case NodeTypeSwitchProng: | ||
| 1275 | case NodeTypeSwitchRange: | ||
| 1276 | case NodeTypeErrorValueDecl: | ||
| 1277 | case NodeTypeTypeDecl: | ||
| 1278 | zig_unreachable(); | ||
| 1279 | } | ||
| 1280 | zig_unreachable(); | ||
| 1281 | } | ||
| 1282 | |||
| 1088 | static IrInstruction *ir_gen_add_return(CodeGen *g, AstNode *node, BlockContext *scope, | 1283 | static IrInstruction *ir_gen_add_return(CodeGen *g, AstNode *node, BlockContext *scope, |
| 1089 | IrExecutable *ir_executable, bool add_return, bool pointer_only) | 1284 | IrExecutable *ir_executable, bool add_return, bool pointer_only) |
| 1090 | { | 1285 | { |
| ... | @@ -1965,8 +2160,8 @@ static int ir_eval_math_op(ConstExprValue *op1_val, TypeTableEntry *op1_type, | ... | @@ -1965,8 +2160,8 @@ static int ir_eval_math_op(ConstExprValue *op1_val, TypeTableEntry *op1_type, |
| 1965 | } | 2160 | } |
| 1966 | 2161 | ||
| 1967 | static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) { | 2162 | static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) { |
| 1968 | IrInstruction *op1 = bin_op_instruction->op1; | 2163 | IrInstruction *op1 = bin_op_instruction->op1->other; |
| 1969 | IrInstruction *op2 = bin_op_instruction->op2; | 2164 | IrInstruction *op2 = bin_op_instruction->op2->other; |
| 1970 | IrInstruction *instructions[] = {op1, op2}; | 2165 | IrInstruction *instructions[] = {op1, op2}; |
| 1971 | TypeTableEntry *resolved_type = ir_resolve_peer_types(ira, &bin_op_instruction->base, instructions, 2); | 2166 | TypeTableEntry *resolved_type = ir_resolve_peer_types(ira, &bin_op_instruction->base, instructions, 2); |
| 1972 | if (resolved_type->id == TypeTableEntryIdInvalid) | 2167 | if (resolved_type->id == TypeTableEntryIdInvalid) |
| ... | @@ -2021,7 +2216,7 @@ static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp | ... | @@ -2021,7 +2216,7 @@ static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp |
| 2021 | 2216 | ||
| 2022 | } | 2217 | } |
| 2023 | 2218 | ||
| 2024 | ir_build_bin_op_from(&ira->new_irb, &bin_op_instruction->base, op_id, op1->other, op2->other); | 2219 | ir_build_bin_op_from(&ira->new_irb, &bin_op_instruction->base, op_id, op1, op2); |
| 2025 | 2220 | ||
| 2026 | return resolved_type; | 2221 | return resolved_type; |
| 2027 | } | 2222 | } |
| ... | @@ -2169,9 +2364,9 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc | ... | @@ -2169,9 +2364,9 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc |
| 2169 | var->type = result_type; | 2364 | var->type = result_type; |
| 2170 | assert(var->type != nullptr); // should have been caught by the parser | 2365 | assert(var->type != nullptr); // should have been caught by the parser |
| 2171 | 2366 | ||
| 2172 | if (casted_init_value->static_value.ok) { | 2367 | ConstExprValue *mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index]; |
| 2173 | // TODO set the variable in the IrVarSlot | 2368 | *mem_slot = casted_init_value->static_value; |
| 2174 | } | 2369 | |
| 2175 | ir_build_var_decl_from(&ira->new_irb, &decl_var_instruction->base, var, var_type, casted_init_value); | 2370 | ir_build_var_decl_from(&ira->new_irb, &decl_var_instruction->base, var, var_type, casted_init_value); |
| 2176 | 2371 | ||
| 2177 | BlockContext *scope = decl_var_instruction->base.source_node->block_context; | 2372 | BlockContext *scope = decl_var_instruction->base.source_node->block_context; |
| ... | @@ -2181,11 +2376,6 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc | ... | @@ -2181,11 +2376,6 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc |
| 2181 | return ira->codegen->builtin_types.entry_void; | 2376 | return ira->codegen->builtin_types.entry_void; |
| 2182 | } | 2377 | } |
| 2183 | 2378 | ||
| 2184 | static TypeTableEntry *ir_analyze_instruction_load_var(IrAnalyze *ira, IrInstructionLoadVar *load_var_instruction) { | ||
| 2185 | ir_build_load_var_from(&ira->new_irb, &load_var_instruction->base, load_var_instruction->var); | ||
| 2186 | return load_var_instruction->var->type; | ||
| 2187 | } | ||
| 2188 | |||
| 2189 | static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionCall *call_instruction) { | 2379 | static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionCall *call_instruction) { |
| 2190 | IrInstruction *fn_ref = call_instruction->fn->other; | 2380 | IrInstruction *fn_ref = call_instruction->fn->other; |
| 2191 | if (fn_ref->type_entry->id == TypeTableEntryIdInvalid) | 2381 | if (fn_ref->type_entry->id == TypeTableEntryIdInvalid) |
| ... | @@ -2345,20 +2535,7 @@ static TypeTableEntry *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstructio | ... | @@ -2345,20 +2535,7 @@ static TypeTableEntry *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstructio |
| 2345 | // } | 2535 | // } |
| 2346 | //} | 2536 | //} |
| 2347 | case IrUnOpDereference: | 2537 | case IrUnOpDereference: |
| 2348 | zig_panic("TODO analyze PrefixOpDereference"); | 2538 | zig_panic("TODO remove this IrUnOp item"); |
| 2349 | //{ | ||
| 2350 | // TypeTableEntry *type_entry = analyze_expression(g, import, context, nullptr, *expr_node); | ||
| 2351 | // if (type_entry->id == TypeTableEntryIdInvalid) { | ||
| 2352 | // return type_entry; | ||
| 2353 | // } else if (type_entry->id == TypeTableEntryIdPointer) { | ||
| 2354 | // return type_entry->data.pointer.child_type; | ||
| 2355 | // } else { | ||
| 2356 | // add_node_error(g, *expr_node, | ||
| 2357 | // buf_sprintf("indirection requires pointer operand ('%s' invalid)", | ||
| 2358 | // buf_ptr(&type_entry->name))); | ||
| 2359 | // return g->builtin_types.entry_invalid; | ||
| 2360 | // } | ||
| 2361 | //} | ||
| 2362 | case IrUnOpMaybe: | 2539 | case IrUnOpMaybe: |
| 2363 | zig_panic("TODO analyze PrefixOpMaybe"); | 2540 | zig_panic("TODO analyze PrefixOpMaybe"); |
| 2364 | //{ | 2541 | //{ |
| ... | @@ -3727,6 +3904,43 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP | ... | @@ -3727,6 +3904,43 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP |
| 3727 | return resolved_type; | 3904 | return resolved_type; |
| 3728 | } | 3905 | } |
| 3729 | 3906 | ||
| 3907 | static TypeTableEntry *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstructionVarPtr *var_ptr_instruction) { | ||
| 3908 | VariableTableEntry *var = var_ptr_instruction->var; | ||
| 3909 | ConstExprValue *mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index]; | ||
| 3910 | TypeTableEntry *ptr_type = get_pointer_to_type(ira->codegen, var_ptr_instruction->var->type, false); | ||
| 3911 | if (mem_slot->ok) { | ||
| 3912 | ir_build_const_ptr_from(&ira->new_irb, &var_ptr_instruction->base, mem_slot); | ||
| 3913 | return ptr_type; | ||
| 3914 | } | ||
| 3915 | |||
| 3916 | ir_build_var_ptr_from(&ira->new_irb, &var_ptr_instruction->base, var); | ||
| 3917 | return ptr_type; | ||
| 3918 | } | ||
| 3919 | |||
| 3920 | static TypeTableEntry *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstructionLoadPtr *load_ptr_instruction) { | ||
| 3921 | IrInstruction *ptr = load_ptr_instruction->ptr->other; | ||
| 3922 | TypeTableEntry *type_entry = ptr->type_entry; | ||
| 3923 | if (type_entry->id == TypeTableEntryIdInvalid) { | ||
| 3924 | return type_entry; | ||
| 3925 | } else if (type_entry->id == TypeTableEntryIdPointer) { | ||
| 3926 | TypeTableEntry *child_type = type_entry->data.pointer.child_type; | ||
| 3927 | if (ptr->static_value.ok) { | ||
| 3928 | ConstExprValue *pointee = ptr->static_value.data.x_ptr.ptr[0]; | ||
| 3929 | if (pointee->ok) { | ||
| 3930 | ir_build_const_from(&ira->new_irb, &load_ptr_instruction->base, pointee); | ||
| 3931 | return child_type; | ||
| 3932 | } | ||
| 3933 | } | ||
| 3934 | ir_build_load_ptr_from(&ira->new_irb, &load_ptr_instruction->base, ptr); | ||
| 3935 | return child_type; | ||
| 3936 | } else { | ||
| 3937 | add_node_error(ira->codegen, load_ptr_instruction->base.source_node, | ||
| 3938 | buf_sprintf("indirection requires pointer operand ('%s' invalid)", | ||
| 3939 | buf_ptr(&type_entry->name))); | ||
| 3940 | return ira->codegen->builtin_types.entry_invalid; | ||
| 3941 | } | ||
| 3942 | } | ||
| 3943 | |||
| 3730 | static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) { | 3944 | static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) { |
| 3731 | switch (instruction->id) { | 3945 | switch (instruction->id) { |
| 3732 | case IrInstructionIdInvalid: | 3946 | case IrInstructionIdInvalid: |
| ... | @@ -3741,8 +3955,16 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi | ... | @@ -3741,8 +3955,16 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi |
| 3741 | return ir_analyze_instruction_bin_op(ira, (IrInstructionBinOp *)instruction); | 3955 | return ir_analyze_instruction_bin_op(ira, (IrInstructionBinOp *)instruction); |
| 3742 | case IrInstructionIdDeclVar: | 3956 | case IrInstructionIdDeclVar: |
| 3743 | return ir_analyze_instruction_decl_var(ira, (IrInstructionDeclVar *)instruction); | 3957 | return ir_analyze_instruction_decl_var(ira, (IrInstructionDeclVar *)instruction); |
| 3744 | case IrInstructionIdLoadVar: | 3958 | case IrInstructionIdLoadPtr: |
| 3745 | return ir_analyze_instruction_load_var(ira, (IrInstructionLoadVar *)instruction); | 3959 | return ir_analyze_instruction_load_ptr(ira, (IrInstructionLoadPtr *)instruction); |
| 3960 | case IrInstructionIdStorePtr: | ||
| 3961 | zig_panic("TODO store ptr"); | ||
| 3962 | case IrInstructionIdFieldPtr: | ||
| 3963 | zig_panic("TODO field ptr"); | ||
| 3964 | case IrInstructionIdElemPtr: | ||
| 3965 | zig_panic("TODO elem ptr"); | ||
| 3966 | case IrInstructionIdVarPtr: | ||
| 3967 | return ir_analyze_instruction_var_ptr(ira, (IrInstructionVarPtr *)instruction); | ||
| 3746 | case IrInstructionIdCall: | 3968 | case IrInstructionIdCall: |
| 3747 | return ir_analyze_instruction_call(ira, (IrInstructionCall *)instruction); | 3969 | return ir_analyze_instruction_call(ira, (IrInstructionCall *)instruction); |
| 3748 | case IrInstructionIdBr: | 3970 | case IrInstructionIdBr: |
| ... | @@ -3756,7 +3978,6 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi | ... | @@ -3756,7 +3978,6 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi |
| 3756 | case IrInstructionIdPhi: | 3978 | case IrInstructionIdPhi: |
| 3757 | return ir_analyze_instruction_phi(ira, (IrInstructionPhi *)instruction); | 3979 | return ir_analyze_instruction_phi(ira, (IrInstructionPhi *)instruction); |
| 3758 | case IrInstructionIdSwitchBr: | 3980 | case IrInstructionIdSwitchBr: |
| 3759 | case IrInstructionIdStoreVar: | ||
| 3760 | case IrInstructionIdCast: | 3981 | case IrInstructionIdCast: |
| 3761 | case IrInstructionIdContainerInitList: | 3982 | case IrInstructionIdContainerInitList: |
| 3762 | case IrInstructionIdContainerInitFields: | 3983 | case IrInstructionIdContainerInitFields: |
| ... | @@ -3792,8 +4013,8 @@ TypeTableEntry *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutabl | ... | @@ -3792,8 +4013,8 @@ TypeTableEntry *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutabl |
| 3792 | ira->new_irb.codegen = codegen; | 4013 | ira->new_irb.codegen = codegen; |
| 3793 | ira->new_irb.exec = new_exec; | 4014 | ira->new_irb.exec = new_exec; |
| 3794 | 4015 | ||
| 3795 | ira->exec_context.var_slot_count = ira->old_irb.exec->var_slot_count; | 4016 | ira->exec_context.mem_slot_count = ira->old_irb.exec->mem_slot_count; |
| 3796 | ira->exec_context.var_slot_list = allocate<IrVarSlot>(ira->exec_context.var_slot_count); | 4017 | ira->exec_context.mem_slot_list = allocate<ConstExprValue>(ira->exec_context.mem_slot_count); |
| 3797 | 4018 | ||
| 3798 | TypeTableEntry *return_type = ira->codegen->builtin_types.entry_void; | 4019 | TypeTableEntry *return_type = ira->codegen->builtin_types.entry_void; |
| 3799 | for (size_t bb_i = 0; bb_i < ira->old_irb.exec->basic_block_list.length; bb_i += 1) { | 4020 | for (size_t bb_i = 0; bb_i < ira->old_irb.exec->basic_block_list.length; bb_i += 1) { |
| ... | @@ -3881,7 +4102,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -3881,7 +4102,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 3881 | case IrInstructionIdCondBr: | 4102 | case IrInstructionIdCondBr: |
| 3882 | case IrInstructionIdSwitchBr: | 4103 | case IrInstructionIdSwitchBr: |
| 3883 | case IrInstructionIdDeclVar: | 4104 | case IrInstructionIdDeclVar: |
| 3884 | case IrInstructionIdStoreVar: | 4105 | case IrInstructionIdStorePtr: |
| 3885 | case IrInstructionIdCall: | 4106 | case IrInstructionIdCall: |
| 3886 | case IrInstructionIdReturn: | 4107 | case IrInstructionIdReturn: |
| 3887 | case IrInstructionIdUnreachable: | 4108 | case IrInstructionIdUnreachable: |
| ... | @@ -3889,11 +4110,14 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -3889,11 +4110,14 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 3889 | case IrInstructionIdPhi: | 4110 | case IrInstructionIdPhi: |
| 3890 | case IrInstructionIdUnOp: | 4111 | case IrInstructionIdUnOp: |
| 3891 | case IrInstructionIdBinOp: | 4112 | case IrInstructionIdBinOp: |
| 3892 | case IrInstructionIdLoadVar: | 4113 | case IrInstructionIdLoadPtr: |
| 3893 | case IrInstructionIdConst: | 4114 | case IrInstructionIdConst: |
| 3894 | case IrInstructionIdCast: | 4115 | case IrInstructionIdCast: |
| 3895 | case IrInstructionIdContainerInitList: | 4116 | case IrInstructionIdContainerInitList: |
| 3896 | case IrInstructionIdContainerInitFields: | 4117 | case IrInstructionIdContainerInitFields: |
| 4118 | case IrInstructionIdFieldPtr: | ||
| 4119 | case IrInstructionIdElemPtr: | ||
| 4120 | case IrInstructionIdVarPtr: | ||
| 3897 | return false; | 4121 | return false; |
| 3898 | case IrInstructionIdBuiltinCall: | 4122 | case IrInstructionIdBuiltinCall: |
| 3899 | return ir_builtin_call_has_side_effects((IrInstructionBuiltinCall *)instruction); | 4123 | return ir_builtin_call_has_side_effects((IrInstructionBuiltinCall *)instruction); |
src/ir_print.cpp+45-20| ... | @@ -21,8 +21,7 @@ static void ir_print_prefix(IrPrint *irp, IrInstruction *instruction) { | ... | @@ -21,8 +21,7 @@ static void ir_print_prefix(IrPrint *irp, IrInstruction *instruction) { |
| 21 | fprintf(irp->f, "#%-3zu| %-12s| %-2s| ", instruction->debug_id, type_name, ref_count); | 21 | fprintf(irp->f, "#%-3zu| %-12s| %-2s| ", instruction->debug_id, type_name, ref_count); |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | static void ir_print_const_instruction(IrPrint *irp, IrInstruction *instruction) { | 24 | static void ir_print_const_value(IrPrint *irp, TypeTableEntry *type_entry, ConstExprValue *const_val) { |
| 25 | TypeTableEntry *type_entry = instruction->type_entry; | ||
| 26 | switch (type_entry->id) { | 25 | switch (type_entry->id) { |
| 27 | case TypeTableEntryIdInvalid: | 26 | case TypeTableEntryIdInvalid: |
| 28 | zig_unreachable(); | 27 | zig_unreachable(); |
| ... | @@ -30,21 +29,21 @@ static void ir_print_const_instruction(IrPrint *irp, IrInstruction *instruction) | ... | @@ -30,21 +29,21 @@ static void ir_print_const_instruction(IrPrint *irp, IrInstruction *instruction) |
| 30 | fprintf(irp->f, "{}"); | 29 | fprintf(irp->f, "{}"); |
| 31 | break; | 30 | break; |
| 32 | case TypeTableEntryIdNumLitFloat: | 31 | case TypeTableEntryIdNumLitFloat: |
| 33 | fprintf(irp->f, "%f", instruction->static_value.data.x_bignum.data.x_float); | 32 | fprintf(irp->f, "%f", const_val->data.x_bignum.data.x_float); |
| 34 | break; | 33 | break; |
| 35 | case TypeTableEntryIdNumLitInt: | 34 | case TypeTableEntryIdNumLitInt: |
| 36 | { | 35 | { |
| 37 | BigNum *bignum = &instruction->static_value.data.x_bignum; | 36 | BigNum *bignum = &const_val->data.x_bignum; |
| 38 | const char *negative_str = bignum->is_negative ? "-" : ""; | 37 | const char *negative_str = bignum->is_negative ? "-" : ""; |
| 39 | fprintf(irp->f, "%s%llu", negative_str, bignum->data.x_uint); | 38 | fprintf(irp->f, "%s%llu", negative_str, bignum->data.x_uint); |
| 40 | break; | 39 | break; |
| 41 | } | 40 | } |
| 42 | case TypeTableEntryIdMetaType: | 41 | case TypeTableEntryIdMetaType: |
| 43 | fprintf(irp->f, "%s", buf_ptr(&instruction->static_value.data.x_type->name)); | 42 | fprintf(irp->f, "%s", buf_ptr(&const_val->data.x_type->name)); |
| 44 | break; | 43 | break; |
| 45 | case TypeTableEntryIdInt: | 44 | case TypeTableEntryIdInt: |
| 46 | { | 45 | { |
| 47 | BigNum *bignum = &instruction->static_value.data.x_bignum; | 46 | BigNum *bignum = &const_val->data.x_bignum; |
| 48 | assert(bignum->kind == BigNumKindInt); | 47 | assert(bignum->kind == BigNumKindInt); |
| 49 | const char *negative_str = bignum->is_negative ? "-" : ""; | 48 | const char *negative_str = bignum->is_negative ? "-" : ""; |
| 50 | fprintf(irp->f, "%s%llu", negative_str, bignum->data.x_uint); | 49 | fprintf(irp->f, "%s%llu", negative_str, bignum->data.x_uint); |
| ... | @@ -53,10 +52,18 @@ static void ir_print_const_instruction(IrPrint *irp, IrInstruction *instruction) | ... | @@ -53,10 +52,18 @@ static void ir_print_const_instruction(IrPrint *irp, IrInstruction *instruction) |
| 53 | case TypeTableEntryIdUnreachable: | 52 | case TypeTableEntryIdUnreachable: |
| 54 | fprintf(irp->f, "@unreachable()"); | 53 | fprintf(irp->f, "@unreachable()"); |
| 55 | break; | 54 | break; |
| 56 | case TypeTableEntryIdVar: | ||
| 57 | case TypeTableEntryIdBool: | 55 | case TypeTableEntryIdBool: |
| 58 | case TypeTableEntryIdFloat: | 56 | { |
| 57 | const char *value = const_val->data.x_bool ? "true" : "false"; | ||
| 58 | fprintf(irp->f, "%s", value); | ||
| 59 | break; | ||
| 60 | } | ||
| 59 | case TypeTableEntryIdPointer: | 61 | case TypeTableEntryIdPointer: |
| 62 | fprintf(irp->f, "&"); | ||
| 63 | ir_print_const_value(irp, type_entry->data.pointer.child_type, const_val->data.x_ptr.ptr[0]); | ||
| 64 | break; | ||
| 65 | case TypeTableEntryIdVar: | ||
| 66 | case TypeTableEntryIdFloat: | ||
| 60 | case TypeTableEntryIdArray: | 67 | case TypeTableEntryIdArray: |
| 61 | case TypeTableEntryIdStruct: | 68 | case TypeTableEntryIdStruct: |
| 62 | case TypeTableEntryIdUndefLit: | 69 | case TypeTableEntryIdUndefLit: |
| ... | @@ -75,6 +82,12 @@ static void ir_print_const_instruction(IrPrint *irp, IrInstruction *instruction) | ... | @@ -75,6 +82,12 @@ static void ir_print_const_instruction(IrPrint *irp, IrInstruction *instruction) |
| 75 | } | 82 | } |
| 76 | } | 83 | } |
| 77 | 84 | ||
| 85 | static void ir_print_const_instruction(IrPrint *irp, IrInstruction *instruction) { | ||
| 86 | TypeTableEntry *type_entry = instruction->type_entry; | ||
| 87 | ConstExprValue *const_val = &instruction->static_value; | ||
| 88 | ir_print_const_value(irp, type_entry, const_val); | ||
| 89 | } | ||
| 90 | |||
| 78 | static void ir_print_other_instruction(IrPrint *irp, IrInstruction *instruction) { | 91 | static void ir_print_other_instruction(IrPrint *irp, IrInstruction *instruction) { |
| 79 | if (instruction->static_value.ok) { | 92 | if (instruction->static_value.ok) { |
| 80 | ir_print_const_instruction(irp, instruction); | 93 | ir_print_const_instruction(irp, instruction); |
| ... | @@ -211,10 +224,6 @@ static void ir_print_decl_var(IrPrint *irp, IrInstructionDeclVar *decl_var_instr | ... | @@ -211,10 +224,6 @@ static void ir_print_decl_var(IrPrint *irp, IrInstructionDeclVar *decl_var_instr |
| 211 | ir_print_other_instruction(irp, decl_var_instruction->init_value); | 224 | ir_print_other_instruction(irp, decl_var_instruction->init_value); |
| 212 | } | 225 | } |
| 213 | 226 | ||
| 214 | static void ir_print_load_var(IrPrint *irp, IrInstructionLoadVar *load_var_instruction) { | ||
| 215 | fprintf(irp->f, "%s", buf_ptr(&load_var_instruction->var->name)); | ||
| 216 | } | ||
| 217 | |||
| 218 | static void ir_print_cast(IrPrint *irp, IrInstructionCast *cast_instruction) { | 227 | static void ir_print_cast(IrPrint *irp, IrInstructionCast *cast_instruction) { |
| 219 | fprintf(irp->f, "cast "); | 228 | fprintf(irp->f, "cast "); |
| 220 | ir_print_other_instruction(irp, cast_instruction->value); | 229 | ir_print_other_instruction(irp, cast_instruction->value); |
| ... | @@ -301,9 +310,20 @@ static void ir_print_unreachable(IrPrint *irp, IrInstructionUnreachable *instruc | ... | @@ -301,9 +310,20 @@ static void ir_print_unreachable(IrPrint *irp, IrInstructionUnreachable *instruc |
| 301 | fprintf(irp->f, "unreachable"); | 310 | fprintf(irp->f, "unreachable"); |
| 302 | } | 311 | } |
| 303 | 312 | ||
| 304 | static void ir_print_store(IrPrint *irp, IrInstructionStoreVar *store_instruction) { | 313 | static void ir_print_elem_ptr(IrPrint *irp, IrInstructionElemPtr *instruction) { |
| 305 | fprintf(irp->f, "%s = ", buf_ptr(&store_instruction->var->name)); | 314 | ir_print_other_instruction(irp, instruction->array_ptr); |
| 306 | ir_print_other_instruction(irp, store_instruction->value); | 315 | fprintf(irp->f, "["); |
| 316 | ir_print_other_instruction(irp, instruction->elem_index); | ||
| 317 | fprintf(irp->f, "]"); | ||
| 318 | } | ||
| 319 | |||
| 320 | static void ir_print_var_ptr(IrPrint *irp, IrInstructionVarPtr *instruction) { | ||
| 321 | fprintf(irp->f, "&%s", buf_ptr(&instruction->var->name)); | ||
| 322 | } | ||
| 323 | |||
| 324 | static void ir_print_load_ptr(IrPrint *irp, IrInstructionLoadPtr *instruction) { | ||
| 325 | fprintf(irp->f, "*"); | ||
| 326 | ir_print_other_instruction(irp, instruction->ptr); | ||
| 307 | } | 327 | } |
| 308 | 328 | ||
| 309 | static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { | 329 | static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { |
| ... | @@ -323,9 +343,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { | ... | @@ -323,9 +343,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { |
| 323 | case IrInstructionIdDeclVar: | 343 | case IrInstructionIdDeclVar: |
| 324 | ir_print_decl_var(irp, (IrInstructionDeclVar *)instruction); | 344 | ir_print_decl_var(irp, (IrInstructionDeclVar *)instruction); |
| 325 | break; | 345 | break; |
| 326 | case IrInstructionIdLoadVar: | ||
| 327 | ir_print_load_var(irp, (IrInstructionLoadVar *)instruction); | ||
| 328 | break; | ||
| 329 | case IrInstructionIdCast: | 346 | case IrInstructionIdCast: |
| 330 | ir_print_cast(irp, (IrInstructionCast *)instruction); | 347 | ir_print_cast(irp, (IrInstructionCast *)instruction); |
| 331 | break; | 348 | break; |
| ... | @@ -356,10 +373,18 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { | ... | @@ -356,10 +373,18 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { |
| 356 | case IrInstructionIdUnreachable: | 373 | case IrInstructionIdUnreachable: |
| 357 | ir_print_unreachable(irp, (IrInstructionUnreachable *)instruction); | 374 | ir_print_unreachable(irp, (IrInstructionUnreachable *)instruction); |
| 358 | break; | 375 | break; |
| 359 | case IrInstructionIdStoreVar: | 376 | case IrInstructionIdElemPtr: |
| 360 | ir_print_store(irp, (IrInstructionStoreVar *)instruction); | 377 | ir_print_elem_ptr(irp, (IrInstructionElemPtr *)instruction); |
| 378 | break; | ||
| 379 | case IrInstructionIdVarPtr: | ||
| 380 | ir_print_var_ptr(irp, (IrInstructionVarPtr *)instruction); | ||
| 381 | break; | ||
| 382 | case IrInstructionIdLoadPtr: | ||
| 383 | ir_print_load_ptr(irp, (IrInstructionLoadPtr *)instruction); | ||
| 361 | break; | 384 | break; |
| 362 | case IrInstructionIdSwitchBr: | 385 | case IrInstructionIdSwitchBr: |
| 386 | case IrInstructionIdStorePtr: | ||
| 387 | case IrInstructionIdFieldPtr: | ||
| 363 | zig_panic("TODO print more IR instructions"); | 388 | zig_panic("TODO print more IR instructions"); |
| 364 | } | 389 | } |
| 365 | fprintf(irp->f, "\n"); | 390 | fprintf(irp->f, "\n"); |