authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-10-23 00:21:29-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-10-23 00:21:29-04:00
logd7a2b05a813a7badf0606726c9a4b1423befd437
treeb4f1f0caa664d10b26a0ca4be31d1aeb125c802b
parenta9a6f77a1f0a6e173d85fee42aec0a8d5e22a64d

IR: introduce concept of lvalues


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)
3939
40set(ZIG_SOURCES40set(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;
3434
35struct IrExecutable {35struct 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};
4040
...@@ -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};
13551355
...@@ -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};
15561559
1557struct IrInstructionLoadVar {1560struct IrInstructionLoadPtr {
1558 IrInstruction base;1561 IrInstruction base;
15591562
1560 VariableTableEntry *var;1563 IrInstruction *ptr;
1561};1564};
15621565
1563struct IrInstructionStoreVar {1566struct IrInstructionStorePtr {
1564 IrInstruction base;1567 IrInstruction base;
15651568
1569 IrInstruction *ptr;
1566 IrInstruction *value;1570 IrInstruction *value;
1571};
1572
1573struct IrInstructionFieldPtr {
1574 IrInstruction base;
1575
1576 IrInstruction *struct_ptr;
1577 Buf field_name;
1578};
1579
1580struct IrInstructionElemPtr {
1581 IrInstruction base;
1582
1583 IrInstruction *array_ptr;
1584 IrInstruction *elem_index;
1585};
1586
1587struct IrInstructionVarPtr {
1588 IrInstruction base;
1589
1567 VariableTableEntry *var;1590 VariableTableEntry *var;
1568};1591};
15691592
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 pass3615 // 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 }
36183621
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}
23282328
2329static 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
2340static LLVMValueRef ir_render_bin_op_bool(CodeGen *g, IrExecutable *executable,2329static 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}
28662855
2856static LLVMValueRef ir_render_load_ptr(CodeGen *g, IrExecutable *executable, IrInstructionLoadPtr *instruction) {
2857 return LLVMBuildLoad(g->builder, ir_llvm_value(g, instruction->ptr), "");
2858}
2859
2860static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutable *executable, IrInstructionVarPtr *instruction) {
2861 return instruction->var->value_ref;
2862}
2863
2867static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, IrInstruction *instruction) {2864static 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);
28692866
...@@ -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);
31543155
3155 AstNode *continue_expr_node = node->data.while_expr.continue_expr;3156 //AstNode *continue_expr_node = node->data.while_expr.continue_expr;
31563157
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 loop3161 // generate a forever loop
31613162 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");
31693170 //}
3170 set_debug_source_node(g, node);3171
3171 LLVMBuildBr(g->builder, body_block);3172 //set_debug_source_node(g, node);
31723173 //LLVMBuildBr(g->builder, body_block);
3173 if (continue_expr_node) {3174
3174 LLVMPositionBuilderAtEnd(g->builder, continue_block);3175 //if (continue_expr_node) {
31753176 // LLVMPositionBuilderAtEnd(g->builder, continue_block);
3176 gen_expr(g, continue_expr_node);3177
31773178 // 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);
31813182 //}
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();
31883189 //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);
31933194 //}
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 loop3200 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 }
32363202
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);
32443210
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;
32473213 //assert(elem_var);
3248 TypeTableEntry *array_type = get_expr_type(node->data.for_expr.array_expr);3214
32493215 //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;
32543220 //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");
32593225 //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);
32633229 //LLVMBuildStore(g->builder, LLVMConstNull(index_var->type->type_ref), index_ptr);
3264 gen_var_debug_decl(g, index_var);3230
32653231 //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 //}
32853251 //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, "");
32903256 //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);
32933259 //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);
33113277 //}
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);
33173283 //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;
33213287}
3322static 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);
33253291// 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);
33293295//}
3330static 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);
33333299// 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//}
33373304
3338static LLVMValueRef gen_var_decl_raw(CodeGen *g, AstNode *source_node, AstNodeVariableDeclaration *var_decl,3305static 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"
55
6struct IrVarSlot {
7 ConstExprValue value;
8 bool runtime;
9};
10
11struct IrExecContext {6struct 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};
1510
16struct IrBuilder {11struct 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};
2118
22struct IrAnalyze {19struct IrAnalyze {
...@@ -27,6 +24,7 @@ struct IrAnalyze {...@@ -27,6 +24,7 @@ struct IrAnalyze {
27};24};
2825
29static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, BlockContext *scope);26static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, BlockContext *scope);
27static IrInstruction *ir_gen_lvalue(IrBuilder *irb, AstNode *node, BlockContext *scope);
3028
31static void ir_instruction_append(IrBasicBlock *basic_block, IrInstruction *instruction) {29static 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}
4240
43static size_t exec_next_var_slot(IrExecutable *exec) {41static 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}
4846
...@@ -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}
117115
118static constexpr IrInstructionId ir_instruction_id(IrInstructionLoadVar *) {116static constexpr IrInstructionId ir_instruction_id(IrInstructionLoadPtr *) {
119 return IrInstructionIdLoadVar;117 return IrInstructionIdLoadPtr;
120}118}
121119
122static constexpr IrInstructionId ir_instruction_id(IrInstructionStoreVar *) {120static constexpr IrInstructionId ir_instruction_id(IrInstructionStorePtr *) {
123 return IrInstructionIdStoreVar;121 return IrInstructionIdStorePtr;
122}
123
124static constexpr IrInstructionId ir_instruction_id(IrInstructionFieldPtr *) {
125 return IrInstructionIdFieldPtr;
126}
127
128static constexpr IrInstructionId ir_instruction_id(IrInstructionElemPtr *) {
129 return IrInstructionIdElemPtr;
130}
131
132static constexpr IrInstructionId ir_instruction_id(IrInstructionVarPtr *) {
133 return IrInstructionIdVarPtr;
124}134}
125135
126static constexpr IrInstructionId ir_instruction_id(IrInstructionCall *) {136static 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}
285295
296static 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
306static 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
314static 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
321static 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
286static IrInstruction *ir_build_bin_op(IrBuilder *irb, AstNode *source_node, IrBinOp op_id,327static 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}
307348
308static IrInstruction *ir_build_load_var(IrBuilder *irb, AstNode *source_node, VariableTableEntry *var) {349static 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;
312352
313 ir_ref_var(var);353 ir_ref_var(var);
314354
315 return &load_var_instruction->base;355 return &instruction->base;
316}356}
317357
318static IrInstruction *ir_build_load_var_from(IrBuilder *irb, IrInstruction *old_instruction,358static 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;
324364
...@@ -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}
462502
463//static IrInstruction *ir_build_store(IrBuilder *irb, AstNode *source_node,503static 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}
473517
474static IrInstruction *ir_build_var_decl(IrBuilder *irb, AstNode *source_node,518static 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}
485533
...@@ -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}
493541
542static 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
551static 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);
556619
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}
627690
691static 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
628static IrInstruction *ir_gen_bin_op(IrBuilder *irb, AstNode *node) {704static IrInstruction *ir_gen_bin_op(IrBuilder *irb, AstNode *node) {
629 assert(node->type == NodeTypeBinOpExpr);705 assert(node->type == NodeTypeBinOpExpr);
630706
...@@ -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/And747 // 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
726818
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);
764857
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 }
768863
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}
10131108
1109static 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
1014static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockContext *block_context,1147static 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}
10871221
1222static 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
1088static IrInstruction *ir_gen_add_return(CodeGen *g, AstNode *node, BlockContext *scope,1283static 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}
19662161
1967static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) {2162static 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
20212216
2022 }2217 }
20232218
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);
20252220
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 parser2365 assert(var->type != nullptr); // should have been caught by the parser
21712366
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 IrVarSlot2368 *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);
21762371
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}
21832378
2184static 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
2189static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionCall *call_instruction) {2379static 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}
37293906
3907static 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
3920static 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
3730static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {3944static 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;
37944015
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);
37974018
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}
2323
24static void ir_print_const_instruction(IrPrint *irp, IrInstruction *instruction) {24static 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}
7784
85static 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
78static void ir_print_other_instruction(IrPrint *irp, IrInstruction *instruction) {91static 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}
213226
214static 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
218static void ir_print_cast(IrPrint *irp, IrInstructionCast *cast_instruction) {227static 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}
303312
304static void ir_print_store(IrPrint *irp, IrInstructionStoreVar *store_instruction) {313static 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
320static void ir_print_var_ptr(IrPrint *irp, IrInstructionVarPtr *instruction) {
321 fprintf(irp->f, "&%s", buf_ptr(&instruction->var->name));
322}
323
324static void ir_print_load_ptr(IrPrint *irp, IrInstructionLoadPtr *instruction) {
325 fprintf(irp->f, "*");
326 ir_print_other_instruction(irp, instruction->ptr);
307}327}
308328
309static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {329static 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");