diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2017-02-03 15:14:18 -0500 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2017-02-03 15:14:18 -0500 |
| commit | 5a86c0499694d4dafa3af97c6b26860714bc8983 (patch) | |
| tree | 36c7b589fa136e75ae8f104009f360fc2ee25431 /src | |
| parent | 8c9016b6d1a62da847faf95b6124515cdcd9fe0b (diff) | |
| download | zig-5a86c0499694d4dafa3af97c6b26860714bc8983.tar.gz zig-5a86c0499694d4dafa3af97c6b26860714bc8983.zip | |
add volatileStore() builtin function
See #238
We can revisit how volatile will work later - for now
here's a builtin function to do it.
Diffstat (limited to 'src')
| -rw-r--r-- | src/all_types.hpp | 2 | ||||
| -rw-r--r-- | src/codegen.cpp | 6 | ||||
| -rw-r--r-- | src/ir.cpp | 34 | ||||
| -rw-r--r-- | src/ir_print.cpp | 3 |
4 files changed, 35 insertions, 10 deletions
diff --git a/src/all_types.hpp b/src/all_types.hpp index 99032e8f43..ba57187446 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1109,6 +1109,7 @@ enum BuiltinFnId { BuiltinFnIdCanImplicitCast, BuiltinFnIdSetGlobalAlign, BuiltinFnIdSetGlobalSection, + BuiltinFnIdVolatileStore, }; struct BuiltinFnEntry { @@ -1691,6 +1692,7 @@ struct IrInstructionStorePtr { IrInstruction *ptr; IrInstruction *value; + bool is_volatile; }; struct IrInstructionFieldPtr { diff --git a/src/codegen.cpp b/src/codegen.cpp index 8ebee75ac0..44b10dfca6 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -1303,7 +1303,10 @@ static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, Ir return gen_struct_memcpy(g, value, ptr, op1_type); } - LLVMBuildStore(g->builder, value, ptr); + LLVMValueRef llvm_instruction = LLVMBuildStore(g->builder, value, ptr); + + LLVMSetVolatile(llvm_instruction, instruction->is_volatile); + return nullptr; } @@ -3686,6 +3689,7 @@ static void define_builtin_fns(CodeGen *g) { create_builtin_fn(g, BuiltinFnIdAlloca, "alloca", 2); create_builtin_fn(g, BuiltinFnIdSetGlobalAlign, "setGlobalAlign", 2); create_builtin_fn(g, BuiltinFnIdSetGlobalSection, "setGlobalSection", 2); + create_builtin_fn(g, BuiltinFnIdVolatileStore, "volatileStore", 2); } static void init(CodeGen *g, Buf *source_path) { diff --git a/src/ir.cpp b/src/ir.cpp index 751f4760c1..3473893fc1 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -1042,13 +1042,14 @@ static IrInstruction *ir_build_unreachable_from(IrBuilder *irb, IrInstruction *o } static IrInstruction *ir_build_store_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *ptr, IrInstruction *value) + IrInstruction *ptr, IrInstruction *value, bool is_volatile) { IrInstructionStorePtr *instruction = ir_build_instruction<IrInstructionStorePtr>(irb, scope, source_node); instruction->base.value.special = ConstValSpecialStatic; instruction->base.value.type = irb->codegen->builtin_types.entry_void; instruction->ptr = ptr; instruction->value = value; + instruction->is_volatile = is_volatile; ir_ref_instruction(ptr, irb->current_basic_block); ir_ref_instruction(value, irb->current_basic_block); @@ -1057,10 +1058,10 @@ static IrInstruction *ir_build_store_ptr(IrBuilder *irb, Scope *scope, AstNode * } static IrInstruction *ir_build_store_ptr_from(IrBuilder *irb, IrInstruction *old_instruction, - IrInstruction *ptr, IrInstruction *value) + IrInstruction *ptr, IrInstruction *value, bool is_volatile) { IrInstruction *new_instruction = ir_build_store_ptr(irb, old_instruction->scope, - old_instruction->source_node, ptr, value); + old_instruction->source_node, ptr, value, is_volatile); ir_link_new_instruction(new_instruction, old_instruction); return new_instruction; } @@ -3298,7 +3299,7 @@ static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node) if (lvalue == irb->codegen->invalid_instruction || rvalue == irb->codegen->invalid_instruction) return irb->codegen->invalid_instruction; - ir_build_store_ptr(irb, scope, node, lvalue, rvalue); + ir_build_store_ptr(irb, scope, node, lvalue, rvalue, false); return ir_build_const_void(irb, scope, node); } @@ -3311,7 +3312,7 @@ static IrInstruction *ir_gen_assign_op(IrBuilder *irb, Scope *scope, AstNode *no if (op2 == irb->codegen->invalid_instruction) return op2; IrInstruction *result = ir_build_bin_op(irb, scope, node, op_id, op1, op2, true); - ir_build_store_ptr(irb, scope, node, lvalue, result); + ir_build_store_ptr(irb, scope, node, lvalue, result, false); return ir_build_const_void(irb, scope, node); } @@ -4199,6 +4200,20 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo return ir_build_set_global_section(irb, scope, node, var, arg1_value); } } + case BuiltinFnIdVolatileStore: + { + AstNode *arg0_node = node->data.fn_call_expr.params.at(0); + IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_instruction) + return arg0_value; + + AstNode *arg1_node = node->data.fn_call_expr.params.at(1); + IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_instruction) + return arg1_value; + + return ir_build_store_ptr(irb, scope, node, arg0_value, arg1_value, true); + } } zig_unreachable(); } @@ -4613,7 +4628,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo } else { elem_val = ir_build_load_ptr(irb, child_scope, node, elem_ptr); } - ir_mark_gen(ir_build_store_ptr(irb, child_scope, node, elem_var_ptr, elem_val)); + ir_mark_gen(ir_build_store_ptr(irb, child_scope, node, elem_var_ptr, elem_val, false)); LoopStackItem *loop_stack_item = irb->loop_stack.add_one(); loop_stack_item->break_block = end_block; @@ -4627,7 +4642,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo ir_set_cursor_at_end(irb, continue_block); IrInstruction *new_index_val = ir_build_bin_op(irb, child_scope, node, IrBinOpAdd, index_val, one, false); - ir_mark_gen(ir_build_store_ptr(irb, child_scope, node, index_ptr, new_index_val)); + ir_mark_gen(ir_build_store_ptr(irb, child_scope, node, index_ptr, new_index_val, false)); ir_build_br(irb, child_scope, node, cond_block, is_comptime); ir_set_cursor_at_end(irb, end_block); @@ -9274,11 +9289,12 @@ static TypeTableEntry *ir_analyze_instruction_store_ptr(IrAnalyze *ira, IrInstru } new_ptr_inst->value.type = ptr->value.type; ir_build_store_ptr(&ira->new_irb, store_ptr_instruction->base.scope, - store_ptr_instruction->base.source_node, new_ptr_inst, casted_value); + store_ptr_instruction->base.source_node, new_ptr_inst, casted_value, false); return ir_analyze_void(ira, &store_ptr_instruction->base); } - ir_build_store_ptr_from(&ira->new_irb, &store_ptr_instruction->base, ptr, casted_value); + ir_build_store_ptr_from(&ira->new_irb, &store_ptr_instruction->base, ptr, casted_value, + store_ptr_instruction->is_volatile); return ira->codegen->builtin_types.entry_void; } diff --git a/src/ir_print.cpp b/src/ir_print.cpp index fa7ff97d81..a5ca1f1197 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -299,6 +299,9 @@ static void ir_print_store_ptr(IrPrint *irp, IrInstructionStorePtr *instruction) ir_print_var_instruction(irp, instruction->ptr); fprintf(irp->f, " = "); ir_print_other_instruction(irp, instruction->value); + if (instruction->is_volatile) { + fprintf(irp->f, " // volatile"); + } } static void ir_print_typeof(IrPrint *irp, IrInstructionTypeOf *instruction) { |
