authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-02-03 15:14:18-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-02-03 15:14:18-05:00
log5a86c0499694d4dafa3af97c6b26860714bc8983
tree36c7b589fa136e75ae8f104009f360fc2ee25431
parent8c9016b6d1a62da847faf95b6124515cdcd9fe0b

add volatileStore() builtin function

See #238 We can revisit how volatile will work later - for now here's a builtin function to do it.

4 files changed, 35 insertions(+), 10 deletions(-)

src/all_types.hpp+2
...@@ -1109,6 +1109,7 @@ enum BuiltinFnId {...@@ -1109,6 +1109,7 @@ enum BuiltinFnId {
1109 BuiltinFnIdCanImplicitCast,1109 BuiltinFnIdCanImplicitCast,
1110 BuiltinFnIdSetGlobalAlign,1110 BuiltinFnIdSetGlobalAlign,
1111 BuiltinFnIdSetGlobalSection,1111 BuiltinFnIdSetGlobalSection,
1112 BuiltinFnIdVolatileStore,
1112};1113};
11131114
1114struct BuiltinFnEntry {1115struct BuiltinFnEntry {
...@@ -1691,6 +1692,7 @@ struct IrInstructionStorePtr {...@@ -1691,6 +1692,7 @@ struct IrInstructionStorePtr {
16911692
1692 IrInstruction *ptr;1693 IrInstruction *ptr;
1693 IrInstruction *value;1694 IrInstruction *value;
1695 bool is_volatile;
1694};1696};
16951697
1696struct IrInstructionFieldPtr {1698struct IrInstructionFieldPtr {
src/codegen.cpp+5-1
...@@ -1303,7 +1303,10 @@ static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, Ir...@@ -1303,7 +1303,10 @@ static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, Ir
1303 return gen_struct_memcpy(g, value, ptr, op1_type);1303 return gen_struct_memcpy(g, value, ptr, op1_type);
1304 }1304 }
13051305
1306 LLVMBuildStore(g->builder, value, ptr);1306 LLVMValueRef llvm_instruction = LLVMBuildStore(g->builder, value, ptr);
1307
1308 LLVMSetVolatile(llvm_instruction, instruction->is_volatile);
1309
1307 return nullptr;1310 return nullptr;
1308}1311}
13091312
...@@ -3686,6 +3689,7 @@ static void define_builtin_fns(CodeGen *g) {...@@ -3686,6 +3689,7 @@ static void define_builtin_fns(CodeGen *g) {
3686 create_builtin_fn(g, BuiltinFnIdAlloca, "alloca", 2);3689 create_builtin_fn(g, BuiltinFnIdAlloca, "alloca", 2);
3687 create_builtin_fn(g, BuiltinFnIdSetGlobalAlign, "setGlobalAlign", 2);3690 create_builtin_fn(g, BuiltinFnIdSetGlobalAlign, "setGlobalAlign", 2);
3688 create_builtin_fn(g, BuiltinFnIdSetGlobalSection, "setGlobalSection", 2);3691 create_builtin_fn(g, BuiltinFnIdSetGlobalSection, "setGlobalSection", 2);
3692 create_builtin_fn(g, BuiltinFnIdVolatileStore, "volatileStore", 2);
3689}3693}
36903694
3691static void init(CodeGen *g, Buf *source_path) {3695static void init(CodeGen *g, Buf *source_path) {
src/ir.cpp+25-9
...@@ -1042,13 +1042,14 @@ static IrInstruction *ir_build_unreachable_from(IrBuilder *irb, IrInstruction *o...@@ -1042,13 +1042,14 @@ static IrInstruction *ir_build_unreachable_from(IrBuilder *irb, IrInstruction *o
1042}1042}
10431043
1044static IrInstruction *ir_build_store_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,1044static IrInstruction *ir_build_store_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,
1045 IrInstruction *ptr, IrInstruction *value)1045 IrInstruction *ptr, IrInstruction *value, bool is_volatile)
1046{1046{
1047 IrInstructionStorePtr *instruction = ir_build_instruction<IrInstructionStorePtr>(irb, scope, source_node);1047 IrInstructionStorePtr *instruction = ir_build_instruction<IrInstructionStorePtr>(irb, scope, source_node);
1048 instruction->base.value.special = ConstValSpecialStatic;1048 instruction->base.value.special = ConstValSpecialStatic;
1049 instruction->base.value.type = irb->codegen->builtin_types.entry_void;1049 instruction->base.value.type = irb->codegen->builtin_types.entry_void;
1050 instruction->ptr = ptr;1050 instruction->ptr = ptr;
1051 instruction->value = value;1051 instruction->value = value;
1052 instruction->is_volatile = is_volatile;
10521053
1053 ir_ref_instruction(ptr, irb->current_basic_block);1054 ir_ref_instruction(ptr, irb->current_basic_block);
1054 ir_ref_instruction(value, irb->current_basic_block);1055 ir_ref_instruction(value, irb->current_basic_block);
...@@ -1057,10 +1058,10 @@ static IrInstruction *ir_build_store_ptr(IrBuilder *irb, Scope *scope, AstNode *...@@ -1057,10 +1058,10 @@ static IrInstruction *ir_build_store_ptr(IrBuilder *irb, Scope *scope, AstNode *
1057}1058}
10581059
1059static IrInstruction *ir_build_store_ptr_from(IrBuilder *irb, IrInstruction *old_instruction,1060static IrInstruction *ir_build_store_ptr_from(IrBuilder *irb, IrInstruction *old_instruction,
1060 IrInstruction *ptr, IrInstruction *value)1061 IrInstruction *ptr, IrInstruction *value, bool is_volatile)
1061{1062{
1062 IrInstruction *new_instruction = ir_build_store_ptr(irb, old_instruction->scope,1063 IrInstruction *new_instruction = ir_build_store_ptr(irb, old_instruction->scope,
1063 old_instruction->source_node, ptr, value);1064 old_instruction->source_node, ptr, value, is_volatile);
1064 ir_link_new_instruction(new_instruction, old_instruction);1065 ir_link_new_instruction(new_instruction, old_instruction);
1065 return new_instruction;1066 return new_instruction;
1066}1067}
...@@ -3298,7 +3299,7 @@ static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node)...@@ -3298,7 +3299,7 @@ static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node)
3298 if (lvalue == irb->codegen->invalid_instruction || rvalue == irb->codegen->invalid_instruction)3299 if (lvalue == irb->codegen->invalid_instruction || rvalue == irb->codegen->invalid_instruction)
3299 return irb->codegen->invalid_instruction;3300 return irb->codegen->invalid_instruction;
33003301
3301 ir_build_store_ptr(irb, scope, node, lvalue, rvalue);3302 ir_build_store_ptr(irb, scope, node, lvalue, rvalue, false);
3302 return ir_build_const_void(irb, scope, node);3303 return ir_build_const_void(irb, scope, node);
3303}3304}
33043305
...@@ -3311,7 +3312,7 @@ static IrInstruction *ir_gen_assign_op(IrBuilder *irb, Scope *scope, AstNode *no...@@ -3311,7 +3312,7 @@ static IrInstruction *ir_gen_assign_op(IrBuilder *irb, Scope *scope, AstNode *no
3311 if (op2 == irb->codegen->invalid_instruction)3312 if (op2 == irb->codegen->invalid_instruction)
3312 return op2;3313 return op2;
3313 IrInstruction *result = ir_build_bin_op(irb, scope, node, op_id, op1, op2, true);3314 IrInstruction *result = ir_build_bin_op(irb, scope, node, op_id, op1, op2, true);
3314 ir_build_store_ptr(irb, scope, node, lvalue, result);3315 ir_build_store_ptr(irb, scope, node, lvalue, result, false);
3315 return ir_build_const_void(irb, scope, node);3316 return ir_build_const_void(irb, scope, node);
3316}3317}
33173318
...@@ -4199,6 +4200,20 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4199,6 +4200,20 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4199 return ir_build_set_global_section(irb, scope, node, var, arg1_value);4200 return ir_build_set_global_section(irb, scope, node, var, arg1_value);
4200 }4201 }
4201 }4202 }
4203 case BuiltinFnIdVolatileStore:
4204 {
4205 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4206 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
4207 if (arg0_value == irb->codegen->invalid_instruction)
4208 return arg0_value;
4209
4210 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4211 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope);
4212 if (arg1_value == irb->codegen->invalid_instruction)
4213 return arg1_value;
4214
4215 return ir_build_store_ptr(irb, scope, node, arg0_value, arg1_value, true);
4216 }
4202 }4217 }
4203 zig_unreachable();4218 zig_unreachable();
4204}4219}
...@@ -4613,7 +4628,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo...@@ -4613,7 +4628,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
4613 } else {4628 } else {
4614 elem_val = ir_build_load_ptr(irb, child_scope, node, elem_ptr);4629 elem_val = ir_build_load_ptr(irb, child_scope, node, elem_ptr);
4615 }4630 }
4616 ir_mark_gen(ir_build_store_ptr(irb, child_scope, node, elem_var_ptr, elem_val));4631 ir_mark_gen(ir_build_store_ptr(irb, child_scope, node, elem_var_ptr, elem_val, false));
46174632
4618 LoopStackItem *loop_stack_item = irb->loop_stack.add_one();4633 LoopStackItem *loop_stack_item = irb->loop_stack.add_one();
4619 loop_stack_item->break_block = end_block;4634 loop_stack_item->break_block = end_block;
...@@ -4627,7 +4642,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo...@@ -4627,7 +4642,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
46274642
4628 ir_set_cursor_at_end(irb, continue_block);4643 ir_set_cursor_at_end(irb, continue_block);
4629 IrInstruction *new_index_val = ir_build_bin_op(irb, child_scope, node, IrBinOpAdd, index_val, one, false);4644 IrInstruction *new_index_val = ir_build_bin_op(irb, child_scope, node, IrBinOpAdd, index_val, one, false);
4630 ir_mark_gen(ir_build_store_ptr(irb, child_scope, node, index_ptr, new_index_val));4645 ir_mark_gen(ir_build_store_ptr(irb, child_scope, node, index_ptr, new_index_val, false));
4631 ir_build_br(irb, child_scope, node, cond_block, is_comptime);4646 ir_build_br(irb, child_scope, node, cond_block, is_comptime);
46324647
4633 ir_set_cursor_at_end(irb, end_block);4648 ir_set_cursor_at_end(irb, end_block);
...@@ -9274,11 +9289,12 @@ static TypeTableEntry *ir_analyze_instruction_store_ptr(IrAnalyze *ira, IrInstru...@@ -9274,11 +9289,12 @@ static TypeTableEntry *ir_analyze_instruction_store_ptr(IrAnalyze *ira, IrInstru
9274 }9289 }
9275 new_ptr_inst->value.type = ptr->value.type;9290 new_ptr_inst->value.type = ptr->value.type;
9276 ir_build_store_ptr(&ira->new_irb, store_ptr_instruction->base.scope,9291 ir_build_store_ptr(&ira->new_irb, store_ptr_instruction->base.scope,
9277 store_ptr_instruction->base.source_node, new_ptr_inst, casted_value);9292 store_ptr_instruction->base.source_node, new_ptr_inst, casted_value, false);
9278 return ir_analyze_void(ira, &store_ptr_instruction->base);9293 return ir_analyze_void(ira, &store_ptr_instruction->base);
9279 }9294 }
92809295
9281 ir_build_store_ptr_from(&ira->new_irb, &store_ptr_instruction->base, ptr, casted_value);9296 ir_build_store_ptr_from(&ira->new_irb, &store_ptr_instruction->base, ptr, casted_value,
9297 store_ptr_instruction->is_volatile);
9282 return ira->codegen->builtin_types.entry_void;9298 return ira->codegen->builtin_types.entry_void;
9283}9299}
92849300
src/ir_print.cpp+3
...@@ -299,6 +299,9 @@ static void ir_print_store_ptr(IrPrint *irp, IrInstructionStorePtr *instruction)...@@ -299,6 +299,9 @@ static void ir_print_store_ptr(IrPrint *irp, IrInstructionStorePtr *instruction)
299 ir_print_var_instruction(irp, instruction->ptr);299 ir_print_var_instruction(irp, instruction->ptr);
300 fprintf(irp->f, " = ");300 fprintf(irp->f, " = ");
301 ir_print_other_instruction(irp, instruction->value);301 ir_print_other_instruction(irp, instruction->value);
302 if (instruction->is_volatile) {
303 fprintf(irp->f, " // volatile");
304 }
302}305}
303306
304static void ir_print_typeof(IrPrint *irp, IrInstructionTypeOf *instruction) {307static void ir_print_typeof(IrPrint *irp, IrInstructionTypeOf *instruction) {