authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-01-14 14:35:43-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-01-14 14:35:43-05:00
logfa024f80924d35e4aac4b4edcac88193def03175
tree7e5ad2c4b795a983d38b9a7c5c1b1e47fc7ea7ed
parent971a6fc5317b0e2d3a1f611702a4892f4aace942

error return trace pointer prefixes other params

instead of being last. This increases the chances that it can remain in the same register between calls.

2 files changed, 32 insertions(+), 20 deletions(-)

src/analyze.cpp+9-9
......@@ -925,7 +925,7 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
925925 if (!skip_debug_info) {
926926 bool first_arg_return = calling_convention_does_first_arg_return(fn_type_id->cc) &&
927927 handle_is_ptr(fn_type_id->return_type);
928 bool last_arg_error_return_trace = fn_type_id->return_type->id == TypeTableEntryIdErrorUnion ||
928 bool prefix_arg_error_return_trace = fn_type_id->return_type->id == TypeTableEntryIdErrorUnion ||
929929 fn_type_id->return_type->id == TypeTableEntryIdPureError;
930930 // +1 for maybe making the first argument the return value
931931 // +1 for maybe last argument the error return trace
......@@ -951,6 +951,14 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
951951 }
952952 fn_type->data.fn.gen_return_type = gen_return_type;
953953
954 if (prefix_arg_error_return_trace) {
955 TypeTableEntry *gen_type = get_ptr_to_stack_trace_type(g);
956 gen_param_types[gen_param_index] = gen_type->type_ref;
957 gen_param_index += 1;
958 // after the gen_param_index += 1 because 0 is the return type
959 param_di_types[gen_param_index] = gen_type->di_type;
960 }
961
954962 fn_type->data.fn.gen_param_info = allocate<FnGenParamInfo>(fn_type_id->param_count);
955963 for (size_t i = 0; i < fn_type_id->param_count; i += 1) {
956964 FnTypeParamInfo *src_param_info = &fn_type->data.fn.fn_type_id.param_info[i];
......@@ -980,14 +988,6 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
980988 }
981989 }
982990
983 if (last_arg_error_return_trace) {
984 TypeTableEntry *gen_type = get_ptr_to_stack_trace_type(g);
985 gen_param_types[gen_param_index] = gen_type->type_ref;
986 gen_param_index += 1;
987 // after the gen_param_index += 1 because 0 is the return type
988 param_di_types[gen_param_index] = gen_type->di_type;
989 }
990
991991 fn_type->data.fn.gen_param_count = gen_param_index;
992992
993993 fn_type->data.fn.raw_type_ref = LLVMFunctionType(gen_return_type->type_ref,
src/codegen.cpp+23-11
......@@ -406,6 +406,16 @@ static LLVMLinkage to_llvm_linkage(GlobalLinkageId id) {
406406 zig_unreachable();
407407}
408408
409static uint32_t get_err_ret_trace_arg_index(FnTableEntry *fn_table_entry) {
410 TypeTableEntry *fn_type = fn_table_entry->type_entry;
411 TypeTableEntry *return_type = fn_type->data.fn.fn_type_id.return_type;
412 if (return_type->id != TypeTableEntryIdErrorUnion && return_type->id != TypeTableEntryIdPureError) {
413 return UINT32_MAX;
414 }
415 bool first_arg_ret = type_has_bits(return_type) && handle_is_ptr(return_type);
416 return first_arg_ret ? 1 : 0;
417}
418
409419static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) {
410420 if (fn_table_entry->llvm_value)
411421 return fn_table_entry->llvm_value;
......@@ -563,9 +573,10 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) {
563573 addLLVMArgAttr(fn_table_entry->llvm_value, (unsigned)gen_index, "byval");
564574 }
565575 }
566 if (return_type->id == TypeTableEntryIdErrorUnion || return_type->id == TypeTableEntryIdPureError) {
567 unsigned gen_index = LLVMCountParamTypes(fn_llvm_type) - 1;
568 addLLVMArgAttr(fn_table_entry->llvm_value, (unsigned)gen_index, "nonnull");
576
577 uint32_t err_ret_trace_arg_index = get_err_ret_trace_arg_index(fn_table_entry);
578 if (err_ret_trace_arg_index != UINT32_MAX) {
579 addLLVMArgAttr(fn_table_entry->llvm_value, (unsigned)err_ret_trace_arg_index, "nonnull");
569580 }
570581
571582 return fn_table_entry->llvm_value;
......@@ -2400,8 +2411,8 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
24002411 TypeTableEntry *src_return_type = fn_type_id->return_type;
24012412 bool ret_has_bits = type_has_bits(src_return_type);
24022413 bool first_arg_ret = ret_has_bits && handle_is_ptr(src_return_type);
2403 bool last_arg_err_ret_stack = src_return_type->id == TypeTableEntryIdErrorUnion || src_return_type->id == TypeTableEntryIdPureError;
2404 size_t actual_param_count = instruction->arg_count + (first_arg_ret ? 1 : 0) + (last_arg_err_ret_stack ? 1 : 0);
2414 bool prefix_arg_err_ret_stack = src_return_type->id == TypeTableEntryIdErrorUnion || src_return_type->id == TypeTableEntryIdPureError;
2415 size_t actual_param_count = instruction->arg_count + (first_arg_ret ? 1 : 0) + (prefix_arg_err_ret_stack ? 1 : 0);
24052416 bool is_var_args = fn_type_id->is_var_args;
24062417 LLVMValueRef *gen_param_values = allocate<LLVMValueRef>(actual_param_count);
24072418 size_t gen_param_index = 0;
......@@ -2409,6 +2420,10 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
24092420 gen_param_values[gen_param_index] = instruction->tmp_ptr;
24102421 gen_param_index += 1;
24112422 }
2423 if (prefix_arg_err_ret_stack) {
2424 gen_param_values[gen_param_index] = g->cur_err_ret_trace_val;
2425 gen_param_index += 1;
2426 }
24122427 for (size_t call_i = 0; call_i < instruction->arg_count; call_i += 1) {
24132428 IrInstruction *param_instruction = instruction->args[call_i];
24142429 TypeTableEntry *param_type = param_instruction->value.type;
......@@ -2419,10 +2434,6 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
24192434 gen_param_index += 1;
24202435 }
24212436 }
2422 if (last_arg_err_ret_stack) {
2423 gen_param_values[gen_param_index] = g->cur_err_ret_trace_val;
2424 gen_param_index += 1;
2425 }
24262437
24272438 ZigLLVM_FnInline fn_inline;
24282439 switch (instruction->fn_inline) {
......@@ -4578,8 +4589,9 @@ static void do_code_gen(CodeGen *g) {
45784589 build_all_basic_blocks(g, fn_table_entry);
45794590 clear_debug_source_node(g);
45804591
4581 if (return_type->id == TypeTableEntryIdPureError || return_type->id == TypeTableEntryIdErrorUnion) {
4582 g->cur_err_ret_trace_val = LLVMGetParam(fn, LLVMCountParamTypes(fn_table_entry->type_entry->data.fn.raw_type_ref) - 1);
4592 uint32_t err_ret_trace_arg_index = get_err_ret_trace_arg_index(fn_table_entry);
4593 if (err_ret_trace_arg_index != UINT32_MAX) {
4594 g->cur_err_ret_trace_val = LLVMGetParam(fn, err_ret_trace_arg_index);
45834595 } else if (fn_table_entry->calls_errorable_function) {
45844596 g->cur_err_ret_trace_val = build_alloca(g, g->stack_trace_type, "error_return_trace", get_abi_alignment(g, g->stack_trace_type));
45854597 size_t index_field_index = g->stack_trace_type->data.structure.fields[0].gen_index;