From 7586f613d58db8f210649c890c467edce11643b9 Mon Sep 17 00:00:00 2001 From: Timon Kruiper Date: Fri, 28 Jun 2019 00:58:35 +0200 Subject: [PATCH] Added function-section functionality --- src-self-hosted/llvm.zig | 1 + src/all_types.hpp | 1 + src/codegen.cpp | 7 ++++--- src/link.cpp | 2 ++ src/main.cpp | 5 +++++ src/zig_llvm.cpp | 4 +++- src/zig_llvm.h | 2 +- 7 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src-self-hosted/llvm.zig b/src-self-hosted/llvm.zig index 5cb95682ab..149b534ea0 100644 --- a/src-self-hosted/llvm.zig +++ b/src-self-hosted/llvm.zig @@ -283,6 +283,7 @@ extern fn ZigLLVMTargetMachineEmitToFile( error_message: *[*]u8, is_debug: bool, is_small: bool, + function_sections: bool, ) bool; pub const BuildCall = ZigLLVMBuildCall; diff --git a/src/all_types.hpp b/src/all_types.hpp index 0dc86c4f55..3f957ddc0c 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1908,6 +1908,7 @@ struct CodeGen { bool have_pic; bool have_dynamic_link; // this is whether the final thing will be dynamically linked. see also is_dynamic bool have_stack_probing; + bool function_sections; Buf *mmacosx_version_min; Buf *mios_version_min; diff --git a/src/codegen.cpp b/src/codegen.cpp index 72ba3c6c99..ba6cab4285 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -7042,7 +7042,7 @@ static void zig_llvm_emit_output(CodeGen *g) { case EmitFileTypeBinary: if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path), ZigLLVM_EmitBinary, &err_msg, g->build_mode == BuildModeDebug, is_small, - g->enable_time_report)) + g->enable_time_report, g->function_sections)) { zig_panic("unable to write object file %s: %s", buf_ptr(output_path), err_msg); } @@ -7058,7 +7058,7 @@ static void zig_llvm_emit_output(CodeGen *g) { case EmitFileTypeAssembly: if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path), ZigLLVM_EmitAssembly, &err_msg, g->build_mode == BuildModeDebug, is_small, - g->enable_time_report)) + g->enable_time_report, g->function_sections)) { zig_panic("unable to write assembly file %s: %s", buf_ptr(output_path), err_msg); } @@ -7068,7 +7068,7 @@ static void zig_llvm_emit_output(CodeGen *g) { case EmitFileTypeLLVMIr: if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path), ZigLLVM_EmitLLVMIr, &err_msg, g->build_mode == BuildModeDebug, is_small, - g->enable_time_report)) + g->enable_time_report, g->function_sections)) { zig_panic("unable to write llvm-ir file %s: %s", buf_ptr(output_path), err_msg); } @@ -8735,6 +8735,7 @@ Error create_c_object_cache(CodeGen *g, CacheHash **out_cache_hash, bool verbose for (size_t arg_i = 0; arg_i < g->clang_argv_len; arg_i += 1) { cache_str(cache_hash, g->clang_argv[arg_i]); } + cache_bool(cache_hash, g->function_sections); *out_cache_hash = cache_hash; return ErrorNone; diff --git a/src/link.cpp b/src/link.cpp index 277dcbc5c6..401f477760 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -791,6 +791,8 @@ static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path, new_link_lib->provided_explicitly = parent_gen->libc_link_lib->provided_explicitly; } + child_gen->function_sections = true; + codegen_build_and_link(child_gen); return &child_gen->output_file_path; } diff --git a/src/main.cpp b/src/main.cpp index 57eeef59df..0074b0ddf8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -85,6 +85,7 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) { " -isystem [dir] add additional search path for other .h files\n" " -mllvm [arg] forward an arg to LLVM's option processing\n" " --override-std-dir [arg] use an alternate Zig standard library\n" + " -ffunction-sections places each function in a seperate section\n" "\n" "Link Options:\n" " --bundle-compiler-rt [path] for static libraries, include compiler-rt symbols\n" @@ -450,6 +451,7 @@ int main(int argc, char **argv) { ValgrindSupport valgrind_support = ValgrindSupportAuto; WantPIC want_pic = WantPICAuto; WantStackCheck want_stack_check = WantStackCheckAuto; + bool function_sections = false; ZigList llvm_argv = {0}; llvm_argv.append("zig (LLVM option parsing)"); @@ -688,6 +690,8 @@ int main(int argc, char **argv) { return EXIT_FAILURE; } cur_pkg = cur_pkg->parent; + } else if (strcmp(arg, "-ffunction-sections") == 0) { + function_sections = true; } else if (i + 1 >= argc) { fprintf(stderr, "Expected another argument after %s\n", arg); return print_error_usage(arg0); @@ -1101,6 +1105,7 @@ int main(int argc, char **argv) { g->bundle_compiler_rt = bundle_compiler_rt; codegen_set_errmsg_color(g, color); g->system_linker_hack = system_linker_hack; + g->function_sections = function_sections; for (size_t i = 0; i < lib_dirs.length; i += 1) { codegen_add_lib_dir(g, lib_dirs.at(i)); diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index fe1b279cf0..bd118d936b 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -95,7 +95,7 @@ static const bool assertions_on = false; bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref, const char *filename, ZigLLVM_EmitOutputType output_type, char **error_message, bool is_debug, - bool is_small, bool time_report) + bool is_small, bool time_report, bool function_sections) { TimePassesIsEnabled = time_report; @@ -108,6 +108,8 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM TargetMachine* target_machine = reinterpret_cast(targ_machine_ref); target_machine->setO0WantsFastISel(true); + target_machine->Options.FunctionSections = function_sections; + Module* module = unwrap(module_ref); PassManagerBuilder *PMBuilder = new(std::nothrow) PassManagerBuilder(); diff --git a/src/zig_llvm.h b/src/zig_llvm.h index d667e0423d..985933242d 100644 --- a/src/zig_llvm.h +++ b/src/zig_llvm.h @@ -56,7 +56,7 @@ enum ZigLLVM_EmitOutputType { ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref, const char *filename, enum ZigLLVM_EmitOutputType output_type, char **error_message, bool is_debug, - bool is_small, bool time_report); + bool is_small, bool time_report, bool function_sections); ZIG_EXTERN_C LLVMTypeRef ZigLLVMTokenTypeInContext(LLVMContextRef context_ref);