authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-06-10 17:49:36-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-06-10 17:49:36-04:00
logee3f7e20f64d715ff22eeff0b7b355bca1981ea1
treea277698e9df0e1aaede8fa57a0e6b860ae4b3b49
parentb9c033ae1ac9c21a5729407b9a6ede88854654aa
signature Commit is signed but in an unrecognized format.

result location semantics for cmpxchg


4 files changed, 41 insertions(+), 29 deletions(-)

src/all_types.hpp+6-6
...@@ -2862,26 +2862,26 @@ struct IrInstructionEmbedFile {...@@ -2862,26 +2862,26 @@ struct IrInstructionEmbedFile {
2862struct IrInstructionCmpxchgSrc {2862struct IrInstructionCmpxchgSrc {
2863 IrInstruction base;2863 IrInstruction base;
28642864
2865 bool is_weak;
2865 IrInstruction *type_value;2866 IrInstruction *type_value;
2866 IrInstruction *ptr;2867 IrInstruction *ptr;
2867 IrInstruction *cmp_value;2868 IrInstruction *cmp_value;
2868 IrInstruction *new_value;2869 IrInstruction *new_value;
2869 IrInstruction *success_order_value;2870 IrInstruction *success_order_value;
2870 IrInstruction *failure_order_value;2871 IrInstruction *failure_order_value;
28712872 ResultLoc *result_loc;
2872 bool is_weak;
2873};2873};
28742874
2875struct IrInstructionCmpxchgGen {2875struct IrInstructionCmpxchgGen {
2876 IrInstruction base;2876 IrInstruction base;
28772877
2878 bool is_weak;
2879 AtomicOrder success_order;
2880 AtomicOrder failure_order;
2878 IrInstruction *ptr;2881 IrInstruction *ptr;
2879 IrInstruction *cmp_value;2882 IrInstruction *cmp_value;
2880 IrInstruction *new_value;2883 IrInstruction *new_value;
2881 LLVMValueRef tmp_ptr;2884 IrInstruction *result_loc;
2882 AtomicOrder success_order;
2883 AtomicOrder failure_order;
2884 bool is_weak;
2885};2885};
28862886
2887struct IrInstructionFence {2887struct IrInstructionFence {
src/codegen.cpp+8-11
...@@ -4516,28 +4516,28 @@ static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutable *executable, IrIn...@@ -4516,28 +4516,28 @@ static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutable *executable, IrIn
4516 LLVMValueRef result_val = ZigLLVMBuildCmpXchg(g->builder, ptr_val, cmp_val, new_val,4516 LLVMValueRef result_val = ZigLLVMBuildCmpXchg(g->builder, ptr_val, cmp_val, new_val,
4517 success_order, failure_order, instruction->is_weak);4517 success_order, failure_order, instruction->is_weak);
45184518
4519 ZigType *maybe_type = instruction->base.value.type;4519 ZigType *optional_type = instruction->base.value.type;
4520 assert(maybe_type->id == ZigTypeIdOptional);4520 assert(optional_type->id == ZigTypeIdOptional);
4521 ZigType *child_type = maybe_type->data.maybe.child_type;4521 ZigType *child_type = optional_type->data.maybe.child_type;
45224522
4523 if (!handle_is_ptr(maybe_type)) {4523 if (!handle_is_ptr(optional_type)) {
4524 LLVMValueRef payload_val = LLVMBuildExtractValue(g->builder, result_val, 0, "");4524 LLVMValueRef payload_val = LLVMBuildExtractValue(g->builder, result_val, 0, "");
4525 LLVMValueRef success_bit = LLVMBuildExtractValue(g->builder, result_val, 1, "");4525 LLVMValueRef success_bit = LLVMBuildExtractValue(g->builder, result_val, 1, "");
4526 return LLVMBuildSelect(g->builder, success_bit, LLVMConstNull(get_llvm_type(g, child_type)), payload_val, "");4526 return LLVMBuildSelect(g->builder, success_bit, LLVMConstNull(get_llvm_type(g, child_type)), payload_val, "");
4527 }4527 }
45284528
4529 assert(instruction->tmp_ptr != nullptr);4529 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
4530 assert(type_has_bits(child_type));4530 assert(type_has_bits(child_type));
45314531
4532 LLVMValueRef payload_val = LLVMBuildExtractValue(g->builder, result_val, 0, "");4532 LLVMValueRef payload_val = LLVMBuildExtractValue(g->builder, result_val, 0, "");
4533 LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, maybe_child_index, "");4533 LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, result_loc, maybe_child_index, "");
4534 gen_assign_raw(g, val_ptr, get_pointer_to_type(g, child_type, false), payload_val);4534 gen_assign_raw(g, val_ptr, get_pointer_to_type(g, child_type, false), payload_val);
45354535
4536 LLVMValueRef success_bit = LLVMBuildExtractValue(g->builder, result_val, 1, "");4536 LLVMValueRef success_bit = LLVMBuildExtractValue(g->builder, result_val, 1, "");
4537 LLVMValueRef nonnull_bit = LLVMBuildNot(g->builder, success_bit, "");4537 LLVMValueRef nonnull_bit = LLVMBuildNot(g->builder, success_bit, "");
4538 LLVMValueRef maybe_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, maybe_null_index, "");4538 LLVMValueRef maybe_ptr = LLVMBuildStructGEP(g->builder, result_loc, maybe_null_index, "");
4539 gen_store_untyped(g, nonnull_bit, maybe_ptr, 0, false);4539 gen_store_untyped(g, nonnull_bit, maybe_ptr, 0, false);
4540 return instruction->tmp_ptr;4540 return result_loc;
4541}4541}
45424542
4543static LLVMValueRef ir_render_fence(CodeGen *g, IrExecutable *executable, IrInstructionFence *instruction) {4543static LLVMValueRef ir_render_fence(CodeGen *g, IrExecutable *executable, IrInstructionFence *instruction) {
...@@ -6840,9 +6840,6 @@ static void do_code_gen(CodeGen *g) {...@@ -6840,9 +6840,6 @@ static void do_code_gen(CodeGen *g) {
6840 slot = &ref_instruction->tmp_ptr;6840 slot = &ref_instruction->tmp_ptr;
6841 assert(instruction->value.type->id == ZigTypeIdPointer);6841 assert(instruction->value.type->id == ZigTypeIdPointer);
6842 slot_type = instruction->value.type->data.pointer.child_type;6842 slot_type = instruction->value.type->data.pointer.child_type;
6843 } else if (instruction->id == IrInstructionIdCmpxchgGen) {
6844 IrInstructionCmpxchgGen *cmpxchg_instruction = (IrInstructionCmpxchgGen *)instruction;
6845 slot = &cmpxchg_instruction->tmp_ptr;
6846 } else if (instruction->id == IrInstructionIdResizeSlice) {6843 } else if (instruction->id == IrInstructionIdResizeSlice) {
6847 IrInstructionResizeSlice *resize_slice_instruction = (IrInstructionResizeSlice *)instruction;6844 IrInstructionResizeSlice *resize_slice_instruction = (IrInstructionResizeSlice *)instruction;
6848 slot = &resize_slice_instruction->tmp_ptr;6845 slot = &resize_slice_instruction->tmp_ptr;
src/ir.cpp+23-10
...@@ -2032,8 +2032,7 @@ static IrInstruction *ir_build_embed_file(IrBuilder *irb, Scope *scope, AstNode...@@ -2032,8 +2032,7 @@ static IrInstruction *ir_build_embed_file(IrBuilder *irb, Scope *scope, AstNode
20322032
2033static IrInstruction *ir_build_cmpxchg_src(IrBuilder *irb, Scope *scope, AstNode *source_node,2033static IrInstruction *ir_build_cmpxchg_src(IrBuilder *irb, Scope *scope, AstNode *source_node,
2034 IrInstruction *type_value, IrInstruction *ptr, IrInstruction *cmp_value, IrInstruction *new_value,2034 IrInstruction *type_value, IrInstruction *ptr, IrInstruction *cmp_value, IrInstruction *new_value,
2035 IrInstruction *success_order_value, IrInstruction *failure_order_value,2035 IrInstruction *success_order_value, IrInstruction *failure_order_value, bool is_weak, ResultLoc *result_loc)
2036 bool is_weak)
2037{2036{
2038 IrInstructionCmpxchgSrc *instruction = ir_build_instruction<IrInstructionCmpxchgSrc>(irb, scope, source_node);2037 IrInstructionCmpxchgSrc *instruction = ir_build_instruction<IrInstructionCmpxchgSrc>(irb, scope, source_node);
2039 instruction->type_value = type_value;2038 instruction->type_value = type_value;
...@@ -2043,6 +2042,7 @@ static IrInstruction *ir_build_cmpxchg_src(IrBuilder *irb, Scope *scope, AstNode...@@ -2043,6 +2042,7 @@ static IrInstruction *ir_build_cmpxchg_src(IrBuilder *irb, Scope *scope, AstNode
2043 instruction->success_order_value = success_order_value;2042 instruction->success_order_value = success_order_value;
2044 instruction->failure_order_value = failure_order_value;2043 instruction->failure_order_value = failure_order_value;
2045 instruction->is_weak = is_weak;2044 instruction->is_weak = is_weak;
2045 instruction->result_loc = result_loc;
20462046
2047 ir_ref_instruction(type_value, irb->current_basic_block);2047 ir_ref_instruction(type_value, irb->current_basic_block);
2048 ir_ref_instruction(ptr, irb->current_basic_block);2048 ir_ref_instruction(ptr, irb->current_basic_block);
...@@ -2054,22 +2054,25 @@ static IrInstruction *ir_build_cmpxchg_src(IrBuilder *irb, Scope *scope, AstNode...@@ -2054,22 +2054,25 @@ static IrInstruction *ir_build_cmpxchg_src(IrBuilder *irb, Scope *scope, AstNode
2054 return &instruction->base;2054 return &instruction->base;
2055}2055}
20562056
2057static IrInstruction *ir_build_cmpxchg_gen(IrAnalyze *ira, IrInstruction *source_instruction,2057static IrInstruction *ir_build_cmpxchg_gen(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *result_type,
2058 IrInstruction *ptr, IrInstruction *cmp_value, IrInstruction *new_value,2058 IrInstruction *ptr, IrInstruction *cmp_value, IrInstruction *new_value,
2059 AtomicOrder success_order, AtomicOrder failure_order, bool is_weak)2059 AtomicOrder success_order, AtomicOrder failure_order, bool is_weak, IrInstruction *result_loc)
2060{2060{
2061 IrInstructionCmpxchgGen *instruction = ir_build_instruction<IrInstructionCmpxchgGen>(&ira->new_irb,2061 IrInstructionCmpxchgGen *instruction = ir_build_instruction<IrInstructionCmpxchgGen>(&ira->new_irb,
2062 source_instruction->scope, source_instruction->source_node);2062 source_instruction->scope, source_instruction->source_node);
2063 instruction->base.value.type = result_type;
2063 instruction->ptr = ptr;2064 instruction->ptr = ptr;
2064 instruction->cmp_value = cmp_value;2065 instruction->cmp_value = cmp_value;
2065 instruction->new_value = new_value;2066 instruction->new_value = new_value;
2066 instruction->success_order = success_order;2067 instruction->success_order = success_order;
2067 instruction->failure_order = failure_order;2068 instruction->failure_order = failure_order;
2068 instruction->is_weak = is_weak;2069 instruction->is_weak = is_weak;
2070 instruction->result_loc = result_loc;
20692071
2070 ir_ref_instruction(ptr, ira->new_irb.current_basic_block);2072 ir_ref_instruction(ptr, ira->new_irb.current_basic_block);
2071 ir_ref_instruction(cmp_value, ira->new_irb.current_basic_block);2073 ir_ref_instruction(cmp_value, ira->new_irb.current_basic_block);
2072 ir_ref_instruction(new_value, ira->new_irb.current_basic_block);2074 ir_ref_instruction(new_value, ira->new_irb.current_basic_block);
2075 if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block);
20732076
2074 return &instruction->base;2077 return &instruction->base;
2075}2078}
...@@ -4420,7 +4423,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4420,7 +4423,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4420 return arg5_value;4423 return arg5_value;
44214424
4422 IrInstruction *cmpxchg = ir_build_cmpxchg_src(irb, scope, node, arg0_value, arg1_value,4425 IrInstruction *cmpxchg = ir_build_cmpxchg_src(irb, scope, node, arg0_value, arg1_value,
4423 arg2_value, arg3_value, arg4_value, arg5_value, (builtin_fn->id == BuiltinFnIdCmpxchgWeak));4426 arg2_value, arg3_value, arg4_value, arg5_value, (builtin_fn->id == BuiltinFnIdCmpxchgWeak),
4427 result_loc);
4424 return ir_lval_wrap(irb, scope, cmpxchg, lval, result_loc);4428 return ir_lval_wrap(irb, scope, cmpxchg, lval, result_loc);
4425 }4429 }
4426 case BuiltinFnIdFence:4430 case BuiltinFnIdFence:
...@@ -20439,6 +20443,18 @@ static IrInstruction *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstructi...@@ -20439,6 +20443,18 @@ static IrInstruction *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstructi
20439 if (type_is_invalid(ptr->value.type))20443 if (type_is_invalid(ptr->value.type))
20440 return ira->codegen->invalid_instruction;20444 return ira->codegen->invalid_instruction;
2044120445
20446 ZigType *result_type = get_optional_type(ira->codegen, operand_type);
20447 IrInstruction *result_loc;
20448 if (handle_is_ptr(result_type)) {
20449 result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,
20450 result_type, nullptr);
20451 if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) {
20452 return result_loc;
20453 }
20454 } else {
20455 result_loc = nullptr;
20456 }
20457
20442 // TODO let this be volatile20458 // TODO let this be volatile
20443 ZigType *ptr_type = get_pointer_to_type(ira->codegen, operand_type, false);20459 ZigType *ptr_type = get_pointer_to_type(ira->codegen, operand_type, false);
20444 IrInstruction *casted_ptr = ir_implicit_cast(ira, ptr, ptr_type);20460 IrInstruction *casted_ptr = ir_implicit_cast(ira, ptr, ptr_type);
...@@ -20502,12 +20518,9 @@ static IrInstruction *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstructi...@@ -20502,12 +20518,9 @@ static IrInstruction *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstructi
20502 zig_panic("TODO compile-time execution of cmpxchg");20518 zig_panic("TODO compile-time execution of cmpxchg");
20503 }20519 }
2050420520
20505 IrInstruction *result = ir_build_cmpxchg_gen(ira, &instruction->base,20521 return ir_build_cmpxchg_gen(ira, &instruction->base, result_type,
20506 casted_ptr, casted_cmp_value, casted_new_value,20522 casted_ptr, casted_cmp_value, casted_new_value,
20507 success_order, failure_order, instruction->is_weak);20523 success_order, failure_order, instruction->is_weak, result_loc);
20508 result->value.type = get_optional_type(ira->codegen, operand_type);
20509 ir_add_alloca(ira, result, result->value.type);
20510 return result;
20511}20524}
2051220525
20513static IrInstruction *ir_analyze_instruction_fence(IrAnalyze *ira, IrInstructionFence *instruction) {20526static IrInstruction *ir_analyze_instruction_fence(IrAnalyze *ira, IrInstructionFence *instruction) {
src/ir_print.cpp+4-2
...@@ -730,7 +730,8 @@ static void ir_print_cmpxchg_src(IrPrint *irp, IrInstructionCmpxchgSrc *instruct...@@ -730,7 +730,8 @@ static void ir_print_cmpxchg_src(IrPrint *irp, IrInstructionCmpxchgSrc *instruct
730 ir_print_other_instruction(irp, instruction->success_order_value);730 ir_print_other_instruction(irp, instruction->success_order_value);
731 fprintf(irp->f, ", ");731 fprintf(irp->f, ", ");
732 ir_print_other_instruction(irp, instruction->failure_order_value);732 ir_print_other_instruction(irp, instruction->failure_order_value);
733 fprintf(irp->f, ")");733 fprintf(irp->f, ")result=");
734 ir_print_result_loc(irp, instruction->result_loc);
734}735}
735736
736static void ir_print_cmpxchg_gen(IrPrint *irp, IrInstructionCmpxchgGen *instruction) {737static void ir_print_cmpxchg_gen(IrPrint *irp, IrInstructionCmpxchgGen *instruction) {
...@@ -740,7 +741,8 @@ static void ir_print_cmpxchg_gen(IrPrint *irp, IrInstructionCmpxchgGen *instruct...@@ -740,7 +741,8 @@ static void ir_print_cmpxchg_gen(IrPrint *irp, IrInstructionCmpxchgGen *instruct
740 ir_print_other_instruction(irp, instruction->cmp_value);741 ir_print_other_instruction(irp, instruction->cmp_value);
741 fprintf(irp->f, ", ");742 fprintf(irp->f, ", ");
742 ir_print_other_instruction(irp, instruction->new_value);743 ir_print_other_instruction(irp, instruction->new_value);
743 fprintf(irp->f, ", TODO print atomic orders)");744 fprintf(irp->f, ", TODO print atomic orders)result=");
745 ir_print_other_instruction(irp, instruction->result_loc);
744}746}
745747
746static void ir_print_fence(IrPrint *irp, IrInstructionFence *instruction) {748static void ir_print_fence(IrPrint *irp, IrInstructionFence *instruction) {