authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-09-02 21:08:59-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-09-02 21:08:59-04:00
logd5968086fe357aa5cf678327295677dba5102fc8
tree95ce9cd8c98d984a886ce92814e41c26e73a8308
parent8558caecb591af94a7e51cd226e7291a9337e76d
signature Commit is signed but in an unrecognized format.

use the sret attribute at the callsite when appropriate

Thanks to Shawn Landden for the original pull request. closes #1450

1 files changed, 9 insertions(+), 1 deletions(-)

src/codegen.cpp+9-1
...@@ -3101,6 +3101,12 @@ static void gen_set_stack_pointer(CodeGen *g, LLVMValueRef aligned_end_addr) {...@@ -3101,6 +3101,12 @@ static void gen_set_stack_pointer(CodeGen *g, LLVMValueRef aligned_end_addr) {
3101 LLVMBuildCall(g->builder, write_register_fn_val, params, 2, "");3101 LLVMBuildCall(g->builder, write_register_fn_val, params, 2, "");
3102}3102}
31033103
3104static void set_call_instr_sret(CodeGen *g, LLVMValueRef call_instr) {
3105 unsigned attr_kind_id = LLVMGetEnumAttributeKindForName("sret", 4);
3106 LLVMAttributeRef sret_attr = LLVMCreateEnumAttribute(LLVMGetGlobalContext(), attr_kind_id, 1);
3107 LLVMAddCallSiteAttribute(call_instr, 1, sret_attr);
3108}
3109
3104static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstructionCall *instruction) {3110static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstructionCall *instruction) {
3105 LLVMValueRef fn_val;3111 LLVMValueRef fn_val;
3106 TypeTableEntry *fn_type;3112 TypeTableEntry *fn_type;
...@@ -3196,6 +3202,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr...@@ -3196,6 +3202,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
3196 } else if (!ret_has_bits) {3202 } else if (!ret_has_bits) {
3197 return nullptr;3203 return nullptr;
3198 } else if (first_arg_ret) {3204 } else if (first_arg_ret) {
3205 set_call_instr_sret(g, result);
3199 return instruction->tmp_ptr;3206 return instruction->tmp_ptr;
3200 } else if (handle_is_ptr(src_return_type)) {3207 } else if (handle_is_ptr(src_return_type)) {
3201 auto store_instr = LLVMBuildStore(g->builder, result, instruction->tmp_ptr);3208 auto store_instr = LLVMBuildStore(g->builder, result, instruction->tmp_ptr);
...@@ -4662,8 +4669,9 @@ static LLVMValueRef get_coro_alloc_helper_fn_val(CodeGen *g, LLVMTypeRef alloc_f...@@ -4662,8 +4669,9 @@ static LLVMValueRef get_coro_alloc_helper_fn_val(CodeGen *g, LLVMTypeRef alloc_f
4662 args.append(allocator_val);4669 args.append(allocator_val);
4663 args.append(coro_size);4670 args.append(coro_size);
4664 args.append(alignment_val);4671 args.append(alignment_val);
4665 ZigLLVMBuildCall(g->builder, alloc_fn_val, args.items, args.length,4672 LLVMValueRef call_instruction = ZigLLVMBuildCall(g->builder, alloc_fn_val, args.items, args.length,
4666 get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_FnInlineAuto, "");4673 get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_FnInlineAuto, "");
4674 set_call_instr_sret(g, call_instruction);
4667 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, sret_ptr, err_union_err_index, "");4675 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, sret_ptr, err_union_err_index, "");
4668 LLVMValueRef err_val = LLVMBuildLoad(g->builder, err_val_ptr, "");4676 LLVMValueRef err_val = LLVMBuildLoad(g->builder, err_val_ptr, "");
4669 LLVMBuildStore(g->builder, err_val, err_code_ptr);4677 LLVMBuildStore(g->builder, err_val, err_code_ptr);