| author | |
| committer | |
| log | 372b615ace0d92d51521b8b0e347d90400f8f7a1 |
| tree | 17ff3a599b689a99c674e23d8d7f015a35933d18 |
| parent | 53ca4118bdd3908092a53b6b4c59762a85b78dfc |
| parent | 4606baee072f832ef794d86f428a7f27d91c6a11 |
| signature |
8 files changed, 82 insertions(+), 4 deletions(-)
src-self-hosted/compilation.zig+1| ... | @@ -516,6 +516,7 @@ pub const Compilation = struct { | ... | @@ -516,6 +516,7 @@ pub const Compilation = struct { |
| 516 | opt_level, | 516 | opt_level, |
| 517 | reloc_mode, | 517 | reloc_mode, |
| 518 | llvm.CodeModelDefault, | 518 | llvm.CodeModelDefault, |
| 519 | false // TODO: add -ffunction-sections option | ||
| 519 | ) orelse return error.OutOfMemory; | 520 | ) orelse return error.OutOfMemory; |
| 520 | defer llvm.DisposeTargetMachine(comp.target_machine); | 521 | defer llvm.DisposeTargetMachine(comp.target_machine); |
| 521 | 522 |
src-self-hosted/llvm.zig+3-2| ... | @@ -163,8 +163,8 @@ extern fn LLVMCopyStringRepOfTargetData(TD: *TargetData) ?[*]u8; | ... | @@ -163,8 +163,8 @@ extern fn LLVMCopyStringRepOfTargetData(TD: *TargetData) ?[*]u8; |
| 163 | pub const CreateTargetDataLayout = LLVMCreateTargetDataLayout; | 163 | pub const CreateTargetDataLayout = LLVMCreateTargetDataLayout; |
| 164 | extern fn LLVMCreateTargetDataLayout(T: *TargetMachine) ?*TargetData; | 164 | extern fn LLVMCreateTargetDataLayout(T: *TargetMachine) ?*TargetData; |
| 165 | 165 | ||
| 166 | pub const CreateTargetMachine = LLVMCreateTargetMachine; | 166 | pub const CreateTargetMachine = ZigLLVMCreateTargetMachine; |
| 167 | extern fn LLVMCreateTargetMachine( | 167 | extern fn ZigLLVMCreateTargetMachine( |
| 168 | T: *Target, | 168 | T: *Target, |
| 169 | Triple: [*]const u8, | 169 | Triple: [*]const u8, |
| 170 | CPU: [*]const u8, | 170 | CPU: [*]const u8, |
| ... | @@ -172,6 +172,7 @@ extern fn LLVMCreateTargetMachine( | ... | @@ -172,6 +172,7 @@ extern fn LLVMCreateTargetMachine( |
| 172 | Level: CodeGenOptLevel, | 172 | Level: CodeGenOptLevel, |
| 173 | Reloc: RelocMode, | 173 | Reloc: RelocMode, |
| 174 | CodeModel: CodeModel, | 174 | CodeModel: CodeModel, |
| 175 | function_sections: bool, | ||
| 175 | ) ?*TargetMachine; | 176 | ) ?*TargetMachine; |
| 176 | 177 | ||
| 177 | pub const GetHostCPUName = LLVMGetHostCPUName; | 178 | pub const GetHostCPUName = LLVMGetHostCPUName; |
src/all_types.hpp+1| ... | @@ -1910,6 +1910,7 @@ struct CodeGen { | ... | @@ -1910,6 +1910,7 @@ struct CodeGen { |
| 1910 | bool have_pic; | 1910 | bool have_pic; |
| 1911 | bool have_dynamic_link; // this is whether the final thing will be dynamically linked. see also is_dynamic | 1911 | bool have_dynamic_link; // this is whether the final thing will be dynamically linked. see also is_dynamic |
| 1912 | bool have_stack_probing; | 1912 | bool have_stack_probing; |
| 1913 | bool function_sections; | ||
| 1913 | 1914 | ||
| 1914 | Buf *mmacosx_version_min; | 1915 | Buf *mmacosx_version_min; |
| 1915 | Buf *mios_version_min; | 1916 | Buf *mios_version_min; |
src/codegen.cpp+9-2| ... | @@ -8134,8 +8134,9 @@ static void init(CodeGen *g) { | ... | @@ -8134,8 +8134,9 @@ static void init(CodeGen *g) { |
| 8134 | target_specific_features = ""; | 8134 | target_specific_features = ""; |
| 8135 | } | 8135 | } |
| 8136 | 8136 | ||
| 8137 | g->target_machine = LLVMCreateTargetMachine(target_ref, buf_ptr(&g->triple_str), | 8137 | g->target_machine = ZigLLVMCreateTargetMachine(target_ref, buf_ptr(&g->triple_str), |
| 8138 | target_specific_cpu_args, target_specific_features, opt_level, reloc_mode, LLVMCodeModelDefault); | 8138 | target_specific_cpu_args, target_specific_features, opt_level, reloc_mode, |
| 8139 | LLVMCodeModelDefault, g->function_sections); | ||
| 8139 | 8140 | ||
| 8140 | g->target_data_ref = LLVMCreateTargetDataLayout(g->target_machine); | 8141 | g->target_data_ref = LLVMCreateTargetDataLayout(g->target_machine); |
| 8141 | 8142 | ||
| ... | @@ -8340,6 +8341,10 @@ void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_pa | ... | @@ -8340,6 +8341,10 @@ void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_pa |
| 8340 | args.append("-nostdinc"); | 8341 | args.append("-nostdinc"); |
| 8341 | args.append("-fno-spell-checking"); | 8342 | args.append("-fno-spell-checking"); |
| 8342 | 8343 | ||
| 8344 | if (g->function_sections) { | ||
| 8345 | args.append("-ffunction-sections"); | ||
| 8346 | } | ||
| 8347 | |||
| 8343 | if (translate_c) { | 8348 | if (translate_c) { |
| 8344 | // this gives us access to preprocessing entities, presumably at | 8349 | // this gives us access to preprocessing entities, presumably at |
| 8345 | // the cost of performance | 8350 | // the cost of performance |
| ... | @@ -8764,6 +8769,7 @@ Error create_c_object_cache(CodeGen *g, CacheHash **out_cache_hash, bool verbose | ... | @@ -8764,6 +8769,7 @@ Error create_c_object_cache(CodeGen *g, CacheHash **out_cache_hash, bool verbose |
| 8764 | cache_int(cache_hash, g->build_mode); | 8769 | cache_int(cache_hash, g->build_mode); |
| 8765 | cache_bool(cache_hash, g->have_pic); | 8770 | cache_bool(cache_hash, g->have_pic); |
| 8766 | cache_bool(cache_hash, want_valgrind_support(g)); | 8771 | cache_bool(cache_hash, want_valgrind_support(g)); |
| 8772 | cache_bool(cache_hash, g->function_sections); | ||
| 8767 | for (size_t arg_i = 0; arg_i < g->clang_argv_len; arg_i += 1) { | 8773 | for (size_t arg_i = 0; arg_i < g->clang_argv_len; arg_i += 1) { |
| 8768 | cache_str(cache_hash, g->clang_argv[arg_i]); | 8774 | cache_str(cache_hash, g->clang_argv[arg_i]); |
| 8769 | } | 8775 | } |
| ... | @@ -9479,6 +9485,7 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { | ... | @@ -9479,6 +9485,7 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { |
| 9479 | cache_bool(ch, g->have_dynamic_link); | 9485 | cache_bool(ch, g->have_dynamic_link); |
| 9480 | cache_bool(ch, g->have_stack_probing); | 9486 | cache_bool(ch, g->have_stack_probing); |
| 9481 | cache_bool(ch, g->is_dummy_so); | 9487 | cache_bool(ch, g->is_dummy_so); |
| 9488 | cache_bool(ch, g->function_sections); | ||
| 9482 | cache_buf_opt(ch, g->mmacosx_version_min); | 9489 | cache_buf_opt(ch, g->mmacosx_version_min); |
| 9483 | cache_buf_opt(ch, g->mios_version_min); | 9490 | cache_buf_opt(ch, g->mios_version_min); |
| 9484 | cache_usize(ch, g->version_major); | 9491 | cache_usize(ch, g->version_major); |
src/link.cpp+2| ... | @@ -791,6 +791,8 @@ static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path, | ... | @@ -791,6 +791,8 @@ static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path, |
| 791 | new_link_lib->provided_explicitly = parent_gen->libc_link_lib->provided_explicitly; | 791 | new_link_lib->provided_explicitly = parent_gen->libc_link_lib->provided_explicitly; |
| 792 | } | 792 | } |
| 793 | 793 | ||
| 794 | child_gen->function_sections = true; | ||
| 795 | |||
| 794 | codegen_build_and_link(child_gen); | 796 | codegen_build_and_link(child_gen); |
| 795 | return &child_gen->output_file_path; | 797 | return &child_gen->output_file_path; |
| 796 | } | 798 | } |
src/main.cpp+5| ... | @@ -85,6 +85,7 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) { | ... | @@ -85,6 +85,7 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) { |
| 85 | " -isystem [dir] add additional search path for other .h files\n" | 85 | " -isystem [dir] add additional search path for other .h files\n" |
| 86 | " -mllvm [arg] forward an arg to LLVM's option processing\n" | 86 | " -mllvm [arg] forward an arg to LLVM's option processing\n" |
| 87 | " --override-std-dir [arg] use an alternate Zig standard library\n" | 87 | " --override-std-dir [arg] use an alternate Zig standard library\n" |
| 88 | " -ffunction-sections places each function in a seperate section\n" | ||
| 88 | "\n" | 89 | "\n" |
| 89 | "Link Options:\n" | 90 | "Link Options:\n" |
| 90 | " --bundle-compiler-rt [path] for static libraries, include compiler-rt symbols\n" | 91 | " --bundle-compiler-rt [path] for static libraries, include compiler-rt symbols\n" |
| ... | @@ -452,6 +453,7 @@ int main(int argc, char **argv) { | ... | @@ -452,6 +453,7 @@ int main(int argc, char **argv) { |
| 452 | ValgrindSupport valgrind_support = ValgrindSupportAuto; | 453 | ValgrindSupport valgrind_support = ValgrindSupportAuto; |
| 453 | WantPIC want_pic = WantPICAuto; | 454 | WantPIC want_pic = WantPICAuto; |
| 454 | WantStackCheck want_stack_check = WantStackCheckAuto; | 455 | WantStackCheck want_stack_check = WantStackCheckAuto; |
| 456 | bool function_sections = false; | ||
| 455 | 457 | ||
| 456 | ZigList<const char *> llvm_argv = {0}; | 458 | ZigList<const char *> llvm_argv = {0}; |
| 457 | llvm_argv.append("zig (LLVM option parsing)"); | 459 | llvm_argv.append("zig (LLVM option parsing)"); |
| ... | @@ -690,6 +692,8 @@ int main(int argc, char **argv) { | ... | @@ -690,6 +692,8 @@ int main(int argc, char **argv) { |
| 690 | return EXIT_FAILURE; | 692 | return EXIT_FAILURE; |
| 691 | } | 693 | } |
| 692 | cur_pkg = cur_pkg->parent; | 694 | cur_pkg = cur_pkg->parent; |
| 695 | } else if (strcmp(arg, "-ffunction-sections") == 0) { | ||
| 696 | function_sections = true; | ||
| 693 | } else if (i + 1 >= argc) { | 697 | } else if (i + 1 >= argc) { |
| 694 | fprintf(stderr, "Expected another argument after %s\n", arg); | 698 | fprintf(stderr, "Expected another argument after %s\n", arg); |
| 695 | return print_error_usage(arg0); | 699 | return print_error_usage(arg0); |
| ... | @@ -1103,6 +1107,7 @@ int main(int argc, char **argv) { | ... | @@ -1103,6 +1107,7 @@ int main(int argc, char **argv) { |
| 1103 | g->bundle_compiler_rt = bundle_compiler_rt; | 1107 | g->bundle_compiler_rt = bundle_compiler_rt; |
| 1104 | codegen_set_errmsg_color(g, color); | 1108 | codegen_set_errmsg_color(g, color); |
| 1105 | g->system_linker_hack = system_linker_hack; | 1109 | g->system_linker_hack = system_linker_hack; |
| 1110 | g->function_sections = function_sections; | ||
| 1106 | 1111 | ||
| 1107 | for (size_t i = 0; i < lib_dirs.length; i += 1) { | 1112 | for (size_t i = 0; i < lib_dirs.length; i += 1) { |
| 1108 | codegen_add_lib_dir(g, lib_dirs.at(i)); | 1113 | codegen_add_lib_dir(g, lib_dirs.at(i)); |
src/zig_llvm.cpp+57| ... | @@ -39,7 +39,9 @@ | ... | @@ -39,7 +39,9 @@ |
| 39 | #include <llvm/Support/TargetParser.h> | 39 | #include <llvm/Support/TargetParser.h> |
| 40 | #include <llvm/Support/Timer.h> | 40 | #include <llvm/Support/Timer.h> |
| 41 | #include <llvm/Support/raw_ostream.h> | 41 | #include <llvm/Support/raw_ostream.h> |
| 42 | #include <llvm/Support/TargetRegistry.h> | ||
| 42 | #include <llvm/Target/TargetMachine.h> | 43 | #include <llvm/Target/TargetMachine.h> |
| 44 | #include <llvm/Target/CodeGenCWrappers.h> | ||
| 43 | #include <llvm/Transforms/Coroutines.h> | 45 | #include <llvm/Transforms/Coroutines.h> |
| 44 | #include <llvm/Transforms/IPO.h> | 46 | #include <llvm/Transforms/IPO.h> |
| 45 | #include <llvm/Transforms/IPO/AlwaysInliner.h> | 47 | #include <llvm/Transforms/IPO/AlwaysInliner.h> |
| ... | @@ -93,6 +95,61 @@ static const bool assertions_on = true; | ... | @@ -93,6 +95,61 @@ static const bool assertions_on = true; |
| 93 | static const bool assertions_on = false; | 95 | static const bool assertions_on = false; |
| 94 | #endif | 96 | #endif |
| 95 | 97 | ||
| 98 | LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, const char *Triple, | ||
| 99 | const char *CPU, const char *Features, LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc, | ||
| 100 | LLVMCodeModel CodeModel, bool function_sections) | ||
| 101 | { | ||
| 102 | Optional<Reloc::Model> RM; | ||
| 103 | switch (Reloc){ | ||
| 104 | case LLVMRelocStatic: | ||
| 105 | RM = Reloc::Static; | ||
| 106 | break; | ||
| 107 | case LLVMRelocPIC: | ||
| 108 | RM = Reloc::PIC_; | ||
| 109 | break; | ||
| 110 | case LLVMRelocDynamicNoPic: | ||
| 111 | RM = Reloc::DynamicNoPIC; | ||
| 112 | break; | ||
| 113 | case LLVMRelocROPI: | ||
| 114 | RM = Reloc::ROPI; | ||
| 115 | break; | ||
| 116 | case LLVMRelocRWPI: | ||
| 117 | RM = Reloc::RWPI; | ||
| 118 | break; | ||
| 119 | case LLVMRelocROPI_RWPI: | ||
| 120 | RM = Reloc::ROPI_RWPI; | ||
| 121 | break; | ||
| 122 | default: | ||
| 123 | break; | ||
| 124 | } | ||
| 125 | |||
| 126 | bool JIT; | ||
| 127 | Optional<CodeModel::Model> CM = unwrap(CodeModel, JIT); | ||
| 128 | |||
| 129 | CodeGenOpt::Level OL; | ||
| 130 | switch (Level) { | ||
| 131 | case LLVMCodeGenLevelNone: | ||
| 132 | OL = CodeGenOpt::None; | ||
| 133 | break; | ||
| 134 | case LLVMCodeGenLevelLess: | ||
| 135 | OL = CodeGenOpt::Less; | ||
| 136 | break; | ||
| 137 | case LLVMCodeGenLevelAggressive: | ||
| 138 | OL = CodeGenOpt::Aggressive; | ||
| 139 | break; | ||
| 140 | default: | ||
| 141 | OL = CodeGenOpt::Default; | ||
| 142 | break; | ||
| 143 | } | ||
| 144 | |||
| 145 | TargetOptions opt; | ||
| 146 | opt.FunctionSections = function_sections; | ||
| 147 | |||
| 148 | TargetMachine *TM = reinterpret_cast<Target*>(T)->createTargetMachine(Triple, CPU, Features, opt, RM, CM, | ||
| 149 | OL, JIT); | ||
| 150 | return reinterpret_cast<LLVMTargetMachineRef>(TM); | ||
| 151 | } | ||
| 152 | |||
| 96 | bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref, | 153 | bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref, |
| 97 | const char *filename, ZigLLVM_EmitOutputType output_type, char **error_message, bool is_debug, | 154 | const char *filename, ZigLLVM_EmitOutputType output_type, char **error_message, bool is_debug, |
| 98 | bool is_small, bool time_report) | 155 | bool is_small, bool time_report) |
src/zig_llvm.h+4| ... | @@ -58,6 +58,10 @@ ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machi | ... | @@ -58,6 +58,10 @@ ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machi |
| 58 | const char *filename, enum ZigLLVM_EmitOutputType output_type, char **error_message, bool is_debug, | 58 | const char *filename, enum ZigLLVM_EmitOutputType output_type, char **error_message, bool is_debug, |
| 59 | bool is_small, bool time_report); | 59 | bool is_small, bool time_report); |
| 60 | 60 | ||
| 61 | ZIG_EXTERN_C LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, const char *Triple, | ||
| 62 | const char *CPU, const char *Features, LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc, | ||
| 63 | LLVMCodeModel CodeModel, bool function_sections); | ||
| 64 | |||
| 61 | ZIG_EXTERN_C LLVMTypeRef ZigLLVMTokenTypeInContext(LLVMContextRef context_ref); | 65 | ZIG_EXTERN_C LLVMTypeRef ZigLLVMTokenTypeInContext(LLVMContextRef context_ref); |
| 62 | 66 | ||
| 63 | enum ZigLLVM_FnInline { | 67 | enum ZigLLVM_FnInline { |