diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2017-11-10 16:45:01 -0500 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2017-11-10 16:45:01 -0500 |
| commit | df89291d1ca04a5891dd48ea5f6d1a99b6006bcb (patch) | |
| tree | 83970de0fdaa7383c11f64efceff7f88d6fd9cd9 /src | |
| parent | e9d7623e1f0300b1b652373f2e0e7b605eaf13d1 (diff) | |
| parent | 019f18058bb74816f8754de63a219347597e06da (diff) | |
| download | zig-df89291d1ca04a5891dd48ea5f6d1a99b6006bcb.tar.gz zig-df89291d1ca04a5891dd48ea5f6d1a99b6006bcb.zip | |
Merge remote-tracking branch 'origin/master' into llvm6
Diffstat (limited to 'src')
| -rw-r--r-- | src/all_types.hpp | 6 | ||||
| -rw-r--r-- | src/analyze.cpp | 3 | ||||
| -rw-r--r-- | src/codegen.cpp | 97 | ||||
| -rw-r--r-- | src/ir.cpp | 1 |
4 files changed, 45 insertions, 62 deletions
diff --git a/src/all_types.hpp b/src/all_types.hpp index 797897e425..0b4efd8415 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1508,13 +1508,9 @@ struct CodeGen { bool linker_rdynamic; const char *linker_script; - // The function definitions this module includes. There must be a corresponding - // fn_protos entry. + // The function definitions this module includes. ZigList<FnTableEntry *> fn_defs; size_t fn_defs_index; - // The function prototypes this module includes. In the case of external declarations, - // there will not be a corresponding fn_defs entry. - ZigList<FnTableEntry *> fn_protos; ZigList<TldVar *> global_vars; OutType out_type; diff --git a/src/analyze.cpp b/src/analyze.cpp index 7d46ebc908..343b1ecdb0 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -2121,8 +2121,6 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { } if (!fn_table_entry->type_entry->data.fn.is_generic) { - g->fn_protos.append(fn_table_entry); - if (fn_def_node) g->fn_defs.append(fn_table_entry); @@ -2162,7 +2160,6 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { fn_table_entry->body_node = source_node->data.test_decl.body; fn_table_entry->is_test = true; - g->fn_protos.append(fn_table_entry); g->fn_defs.append(fn_table_entry); g->test_fns.append(fn_table_entry); diff --git a/src/codegen.cpp b/src/codegen.cpp index 38a1a2cbea..17c0ffc653 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -408,6 +408,7 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) { LLVMValueRef existing_llvm_fn = LLVMGetNamedFunction(g->module, buf_ptr(symbol_name)); if (existing_llvm_fn) { fn_table_entry->llvm_value = LLVMConstBitCast(existing_llvm_fn, LLVMPointerType(fn_llvm_type, 0)); + return fn_table_entry->llvm_value; } else { fn_table_entry->llvm_value = LLVMAddFunction(g->module, buf_ptr(symbol_name), fn_llvm_type); } @@ -493,6 +494,49 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) { // use the ABI alignment, which is fine. } + if (!type_has_bits(fn_type->data.fn.fn_type_id.return_type)) { + // nothing to do + } else if (fn_type->data.fn.fn_type_id.return_type->id == TypeTableEntryIdPointer || + fn_type->data.fn.fn_type_id.return_type->id == TypeTableEntryIdFn) + { + addLLVMAttr(fn_table_entry->llvm_value, 0, "nonnull"); + } else if (handle_is_ptr(fn_type->data.fn.fn_type_id.return_type) && + calling_convention_does_first_arg_return(fn_type->data.fn.fn_type_id.cc)) + { + addLLVMArgAttr(fn_table_entry->llvm_value, 0, "sret"); + addLLVMArgAttr(fn_table_entry->llvm_value, 0, "nonnull"); + } + + + // set parameter attributes + for (size_t param_i = 0; param_i < fn_type->data.fn.fn_type_id.param_count; param_i += 1) { + FnGenParamInfo *gen_info = &fn_type->data.fn.gen_param_info[param_i]; + size_t gen_index = gen_info->gen_index; + bool is_byval = gen_info->is_byval; + + if (gen_index == SIZE_MAX) { + continue; + } + + FnTypeParamInfo *param_info = &fn_type->data.fn.fn_type_id.param_info[param_i]; + + TypeTableEntry *param_type = gen_info->type; + if (param_info->is_noalias) { + addLLVMArgAttr(fn_table_entry->llvm_value, (unsigned)gen_index, "noalias"); + } + if ((param_type->id == TypeTableEntryIdPointer && param_type->data.pointer.is_const) || is_byval) { + addLLVMArgAttr(fn_table_entry->llvm_value, (unsigned)gen_index, "readonly"); + } + if (param_type->id == TypeTableEntryIdPointer) { + addLLVMArgAttr(fn_table_entry->llvm_value, (unsigned)gen_index, "nonnull"); + } + // Note: byval is disabled on windows due to an LLVM bug: + // https://github.com/zig-lang/zig/issues/536 + if (is_byval && g->zig_target.os != ZigLLVM_Win32) { + addLLVMArgAttr(fn_table_entry->llvm_value, (unsigned)gen_index, "byval"); + } + } + return fn_table_entry->llvm_value; } @@ -4297,59 +4341,6 @@ static void do_code_gen(CodeGen *g) { var->value_ref = global_value; } - // Generate function prototypes - for (size_t fn_proto_i = 0; fn_proto_i < g->fn_protos.length; fn_proto_i += 1) { - FnTableEntry *fn_table_entry = g->fn_protos.at(fn_proto_i); - - TypeTableEntry *fn_type = fn_table_entry->type_entry; - FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; - - LLVMValueRef fn_val = fn_llvm_value(g, fn_table_entry); - - if (!type_has_bits(fn_type->data.fn.fn_type_id.return_type)) { - // nothing to do - } else if (fn_type->data.fn.fn_type_id.return_type->id == TypeTableEntryIdPointer || - fn_type->data.fn.fn_type_id.return_type->id == TypeTableEntryIdFn) - { - addLLVMAttr(fn_val, 0, "nonnull"); - } else if (handle_is_ptr(fn_type->data.fn.fn_type_id.return_type) && - calling_convention_does_first_arg_return(fn_type->data.fn.fn_type_id.cc)) - { - addLLVMArgAttr(fn_val, 0, "sret"); - addLLVMArgAttr(fn_val, 0, "nonnull"); - } - - - // set parameter attributes - for (size_t param_i = 0; param_i < fn_type_id->param_count; param_i += 1) { - FnGenParamInfo *gen_info = &fn_type->data.fn.gen_param_info[param_i]; - size_t gen_index = gen_info->gen_index; - bool is_byval = gen_info->is_byval; - - if (gen_index == SIZE_MAX) { - continue; - } - - FnTypeParamInfo *param_info = &fn_type_id->param_info[param_i]; - - TypeTableEntry *param_type = gen_info->type; - if (param_info->is_noalias) { - addLLVMArgAttr(fn_val, (unsigned)gen_index, "noalias"); - } - if ((param_type->id == TypeTableEntryIdPointer && param_type->data.pointer.is_const) || is_byval) { - addLLVMArgAttr(fn_val, (unsigned)gen_index, "readonly"); - } - if (param_type->id == TypeTableEntryIdPointer) { - addLLVMArgAttr(fn_val, (unsigned)gen_index, "nonnull"); - } - // Note: byval is disabled on windows due to an LLVM bug: - // https://github.com/zig-lang/zig/issues/536 - if (is_byval && g->zig_target.os != ZigLLVM_Win32) { - addLLVMArgAttr(fn_val, (unsigned)gen_index, "byval"); - } - } - } - // Generate function definitions. for (size_t fn_i = 0; fn_i < g->fn_defs.length; fn_i += 1) { FnTableEntry *fn_table_entry = g->fn_defs.at(fn_i); diff --git a/src/ir.cpp b/src/ir.cpp index 901ba47b76..fdaced6806 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -10584,7 +10584,6 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal impl_fn->analyzed_executable.source_node = call_instruction->base.source_node; impl_fn->analyzed_executable.parent_exec = ira->new_irb.exec; - ira->codegen->fn_protos.append(impl_fn); ira->codegen->fn_defs.append(impl_fn); } |
