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
signaturelock-open 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 {
28622862struct IrInstructionCmpxchgSrc {
28632863 IrInstruction base;
28642864
2865 bool is_weak;
28652866 IrInstruction *type_value;
28662867 IrInstruction *ptr;
28672868 IrInstruction *cmp_value;
28682869 IrInstruction *new_value;
28692870 IrInstruction *success_order_value;
28702871 IrInstruction *failure_order_value;
2871
2872 bool is_weak;
2872 ResultLoc *result_loc;
28732873};
28742874
28752875struct IrInstructionCmpxchgGen {
28762876 IrInstruction base;
28772877
2878 bool is_weak;
2879 AtomicOrder success_order;
2880 AtomicOrder failure_order;
28782881 IrInstruction *ptr;
28792882 IrInstruction *cmp_value;
28802883 IrInstruction *new_value;
2881 LLVMValueRef tmp_ptr;
2882 AtomicOrder success_order;
2883 AtomicOrder failure_order;
2884 bool is_weak;
2884 IrInstruction *result_loc;
28852885};
28862886
28872887struct IrInstructionFence {
src/codegen.cpp+8-11
......@@ -4516,28 +4516,28 @@ static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutable *executable, IrIn
45164516 LLVMValueRef result_val = ZigLLVMBuildCmpXchg(g->builder, ptr_val, cmp_val, new_val,
45174517 success_order, failure_order, instruction->is_weak);
45184518
4519 ZigType *maybe_type = instruction->base.value.type;
4520 assert(maybe_type->id == ZigTypeIdOptional);
4521 ZigType *child_type = maybe_type->data.maybe.child_type;
4519 ZigType *optional_type = instruction->base.value.type;
4520 assert(optional_type->id == ZigTypeIdOptional);
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)) {
45244524 LLVMValueRef payload_val = LLVMBuildExtractValue(g->builder, result_val, 0, "");
45254525 LLVMValueRef success_bit = LLVMBuildExtractValue(g->builder, result_val, 1, "");
45264526 return LLVMBuildSelect(g->builder, success_bit, LLVMConstNull(get_llvm_type(g, child_type)), payload_val, "");
45274527 }
45284528
4529 assert(instruction->tmp_ptr != nullptr);
4529 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
45304530 assert(type_has_bits(child_type));
45314531
45324532 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, "");
45344534 gen_assign_raw(g, val_ptr, get_pointer_to_type(g, child_type, false), payload_val);
45354535
45364536 LLVMValueRef success_bit = LLVMBuildExtractValue(g->builder, result_val, 1, "");
45374537 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, "");
45394539 gen_store_untyped(g, nonnull_bit, maybe_ptr, 0, false);
4540 return instruction->tmp_ptr;
4540 return result_loc;
45414541}
45424542
45434543static LLVMValueRef ir_render_fence(CodeGen *g, IrExecutable *executable, IrInstructionFence *instruction) {
......@@ -6840,9 +6840,6 @@ static void do_code_gen(CodeGen *g) {
68406840 slot = &ref_instruction->tmp_ptr;
68416841 assert(instruction->value.type->id == ZigTypeIdPointer);
68426842 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;
68466843 } else if (instruction->id == IrInstructionIdResizeSlice) {
68476844 IrInstructionResizeSlice *resize_slice_instruction = (IrInstructionResizeSlice *)instruction;
68486845 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
20322032
20332033static IrInstruction *ir_build_cmpxchg_src(IrBuilder *irb, Scope *scope, AstNode *source_node,
20342034 IrInstruction *type_value, IrInstruction *ptr, IrInstruction *cmp_value, IrInstruction *new_value,
2035 IrInstruction *success_order_value, IrInstruction *failure_order_value,
2036 bool is_weak)
2035 IrInstruction *success_order_value, IrInstruction *failure_order_value, bool is_weak, ResultLoc *result_loc)
20372036{
20382037 IrInstructionCmpxchgSrc *instruction = ir_build_instruction<IrInstructionCmpxchgSrc>(irb, scope, source_node);
20392038 instruction->type_value = type_value;
......@@ -2043,6 +2042,7 @@ static IrInstruction *ir_build_cmpxchg_src(IrBuilder *irb, Scope *scope, AstNode
20432042 instruction->success_order_value = success_order_value;
20442043 instruction->failure_order_value = failure_order_value;
20452044 instruction->is_weak = is_weak;
2045 instruction->result_loc = result_loc;
20462046
20472047 ir_ref_instruction(type_value, irb->current_basic_block);
20482048 ir_ref_instruction(ptr, irb->current_basic_block);
......@@ -2054,22 +2054,25 @@ static IrInstruction *ir_build_cmpxchg_src(IrBuilder *irb, Scope *scope, AstNode
20542054 return &instruction->base;
20552055}
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,
20582058 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)
20602060{
20612061 IrInstructionCmpxchgGen *instruction = ir_build_instruction<IrInstructionCmpxchgGen>(&ira->new_irb,
20622062 source_instruction->scope, source_instruction->source_node);
2063 instruction->base.value.type = result_type;
20632064 instruction->ptr = ptr;
20642065 instruction->cmp_value = cmp_value;
20652066 instruction->new_value = new_value;
20662067 instruction->success_order = success_order;
20672068 instruction->failure_order = failure_order;
20682069 instruction->is_weak = is_weak;
2070 instruction->result_loc = result_loc;
20692071
20702072 ir_ref_instruction(ptr, ira->new_irb.current_basic_block);
20712073 ir_ref_instruction(cmp_value, ira->new_irb.current_basic_block);
20722074 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
20742077 return &instruction->base;
20752078}
......@@ -4420,7 +4423,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
44204423 return arg5_value;
44214424
44224425 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);
44244428 return ir_lval_wrap(irb, scope, cmpxchg, lval, result_loc);
44254429 }
44264430 case BuiltinFnIdFence:
......@@ -20439,6 +20443,18 @@ static IrInstruction *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstructi
2043920443 if (type_is_invalid(ptr->value.type))
2044020444 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
2044220458 // TODO let this be volatile
2044320459 ZigType *ptr_type = get_pointer_to_type(ira->codegen, operand_type, false);
2044420460 IrInstruction *casted_ptr = ir_implicit_cast(ira, ptr, ptr_type);
......@@ -20502,12 +20518,9 @@ static IrInstruction *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstructi
2050220518 zig_panic("TODO compile-time execution of cmpxchg");
2050320519 }
2050420520
20505 IrInstruction *result = ir_build_cmpxchg_gen(ira, &instruction->base,
20521 return ir_build_cmpxchg_gen(ira, &instruction->base, result_type,
2050620522 casted_ptr, casted_cmp_value, casted_new_value,
20507 success_order, failure_order, instruction->is_weak);
20508 result->value.type = get_optional_type(ira->codegen, operand_type);
20509 ir_add_alloca(ira, result, result->value.type);
20510 return result;
20523 success_order, failure_order, instruction->is_weak, result_loc);
2051120524}
2051220525
2051320526static 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
730730 ir_print_other_instruction(irp, instruction->success_order_value);
731731 fprintf(irp->f, ", ");
732732 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);
734735}
735736
736737static void ir_print_cmpxchg_gen(IrPrint *irp, IrInstructionCmpxchgGen *instruction) {
......@@ -740,7 +741,8 @@ static void ir_print_cmpxchg_gen(IrPrint *irp, IrInstructionCmpxchgGen *instruct
740741 ir_print_other_instruction(irp, instruction->cmp_value);
741742 fprintf(irp->f, ", ");
742743 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);
744746}
745747
746748static void ir_print_fence(IrPrint *irp, IrInstructionFence *instruction) {