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
signaturelock-open 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);