| 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 | 516 | opt_level, |
| 517 | 517 | reloc_mode, |
| 518 | 518 | llvm.CodeModelDefault, |
| 519 | false // TODO: add -ffunction-sections option | |
| 519 | 520 | ) orelse return error.OutOfMemory; |
| 520 | 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 | 163 | pub const CreateTargetDataLayout = LLVMCreateTargetDataLayout; |
| 164 | 164 | extern fn LLVMCreateTargetDataLayout(T: *TargetMachine) ?*TargetData; |
| 165 | 165 | |
| 166 | pub const CreateTargetMachine = LLVMCreateTargetMachine; | |
| 167 | extern fn LLVMCreateTargetMachine( | |
| 166 | pub const CreateTargetMachine = ZigLLVMCreateTargetMachine; | |
| 167 | extern fn ZigLLVMCreateTargetMachine( | |
| 168 | 168 | T: *Target, |
| 169 | 169 | Triple: [*]const u8, |
| 170 | 170 | CPU: [*]const u8, |
| ... | ... | @@ -172,6 +172,7 @@ extern fn LLVMCreateTargetMachine( |
| 172 | 172 | Level: CodeGenOptLevel, |
| 173 | 173 | Reloc: RelocMode, |
| 174 | 174 | CodeModel: CodeModel, |
| 175 | function_sections: bool, | |
| 175 | 176 | ) ?*TargetMachine; |
| 176 | 177 | |
| 177 | 178 | pub const GetHostCPUName = LLVMGetHostCPUName; |
src/all_types.hpp+1| ... | ... | @@ -1910,6 +1910,7 @@ struct CodeGen { |
| 1910 | 1910 | bool have_pic; |
| 1911 | 1911 | bool have_dynamic_link; // this is whether the final thing will be dynamically linked. see also is_dynamic |
| 1912 | 1912 | bool have_stack_probing; |
| 1913 | bool function_sections; | |
| 1913 | 1914 | |
| 1914 | 1915 | Buf *mmacosx_version_min; |
| 1915 | 1916 | Buf *mios_version_min; |
src/codegen.cpp+9-2| ... | ... | @@ -8134,8 +8134,9 @@ static void init(CodeGen *g) { |
| 8134 | 8134 | target_specific_features = ""; |
| 8135 | 8135 | } |
| 8136 | 8136 | |
| 8137 | g->target_machine = LLVMCreateTargetMachine(target_ref, buf_ptr(&g->triple_str), | |
| 8138 | target_specific_cpu_args, target_specific_features, opt_level, reloc_mode, LLVMCodeModelDefault); | |
| 8137 | g->target_machine = ZigLLVMCreateTargetMachine(target_ref, buf_ptr(&g->triple_str), | |
| 8138 | target_specific_cpu_args, target_specific_features, opt_level, reloc_mode, | |
| 8139 | LLVMCodeModelDefault, g->function_sections); | |
| 8139 | 8140 | |
| 8140 | 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 | 8341 | args.append("-nostdinc"); |
| 8341 | 8342 | args.append("-fno-spell-checking"); |
| 8342 | 8343 | |
| 8344 | if (g->function_sections) { | |
| 8345 | args.append("-ffunction-sections"); | |
| 8346 | } | |
| 8347 | ||
| 8343 | 8348 | if (translate_c) { |
| 8344 | 8349 | // this gives us access to preprocessing entities, presumably at |
| 8345 | 8350 | // the cost of performance |
| ... | ... | @@ -8764,6 +8769,7 @@ Error create_c_object_cache(CodeGen *g, CacheHash **out_cache_hash, bool verbose |
| 8764 | 8769 | cache_int(cache_hash, g->build_mode); |
| 8765 | 8770 | cache_bool(cache_hash, g->have_pic); |
| 8766 | 8771 | cache_bool(cache_hash, want_valgrind_support(g)); |
| 8772 | cache_bool(cache_hash, g->function_sections); | |
| 8767 | 8773 | for (size_t arg_i = 0; arg_i < g->clang_argv_len; arg_i += 1) { |
| 8768 | 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 | 9485 | cache_bool(ch, g->have_dynamic_link); |
| 9480 | 9486 | cache_bool(ch, g->have_stack_probing); |
| 9481 | 9487 | cache_bool(ch, g->is_dummy_so); |
| 9488 | cache_bool(ch, g->function_sections); | |
| 9482 | 9489 | cache_buf_opt(ch, g->mmacosx_version_min); |
| 9483 | 9490 | cache_buf_opt(ch, g->mios_version_min); |
| 9484 | 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 | 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 | 796 | codegen_build_and_link(child_gen); |
| 795 | 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 | 85 | " -isystem [dir] add additional search path for other .h files\n" |
| 86 | 86 | " -mllvm [arg] forward an arg to LLVM's option processing\n" |
| 87 | 87 | " --override-std-dir [arg] use an alternate Zig standard library\n" |
| 88 | " -ffunction-sections places each function in a seperate section\n" | |
| 88 | 89 | "\n" |
| 89 | 90 | "Link Options:\n" |
| 90 | 91 | " --bundle-compiler-rt [path] for static libraries, include compiler-rt symbols\n" |
| ... | ... | @@ -452,6 +453,7 @@ int main(int argc, char **argv) { |
| 452 | 453 | ValgrindSupport valgrind_support = ValgrindSupportAuto; |
| 453 | 454 | WantPIC want_pic = WantPICAuto; |
| 454 | 455 | WantStackCheck want_stack_check = WantStackCheckAuto; |
| 456 | bool function_sections = false; | |
| 455 | 457 | |
| 456 | 458 | ZigList<const char *> llvm_argv = {0}; |
| 457 | 459 | llvm_argv.append("zig (LLVM option parsing)"); |
| ... | ... | @@ -690,6 +692,8 @@ int main(int argc, char **argv) { |
| 690 | 692 | return EXIT_FAILURE; |
| 691 | 693 | } |
| 692 | 694 | cur_pkg = cur_pkg->parent; |
| 695 | } else if (strcmp(arg, "-ffunction-sections") == 0) { | |
| 696 | function_sections = true; | |
| 693 | 697 | } else if (i + 1 >= argc) { |
| 694 | 698 | fprintf(stderr, "Expected another argument after %s\n", arg); |
| 695 | 699 | return print_error_usage(arg0); |
| ... | ... | @@ -1103,6 +1107,7 @@ int main(int argc, char **argv) { |
| 1103 | 1107 | g->bundle_compiler_rt = bundle_compiler_rt; |
| 1104 | 1108 | codegen_set_errmsg_color(g, color); |
| 1105 | 1109 | g->system_linker_hack = system_linker_hack; |
| 1110 | g->function_sections = function_sections; | |
| 1106 | 1111 | |
| 1107 | 1112 | for (size_t i = 0; i < lib_dirs.length; i += 1) { |
| 1108 | 1113 | codegen_add_lib_dir(g, lib_dirs.at(i)); |
src/zig_llvm.cpp+57| ... | ... | @@ -39,7 +39,9 @@ |
| 39 | 39 | #include <llvm/Support/TargetParser.h> |
| 40 | 40 | #include <llvm/Support/Timer.h> |
| 41 | 41 | #include <llvm/Support/raw_ostream.h> |
| 42 | #include <llvm/Support/TargetRegistry.h> | |
| 42 | 43 | #include <llvm/Target/TargetMachine.h> |
| 44 | #include <llvm/Target/CodeGenCWrappers.h> | |
| 43 | 45 | #include <llvm/Transforms/Coroutines.h> |
| 44 | 46 | #include <llvm/Transforms/IPO.h> |
| 45 | 47 | #include <llvm/Transforms/IPO/AlwaysInliner.h> |
| ... | ... | @@ -93,6 +95,61 @@ static const bool assertions_on = true; |
| 93 | 95 | static const bool assertions_on = false; |
| 94 | 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 | 153 | bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref, |
| 97 | 154 | const char *filename, ZigLLVM_EmitOutputType output_type, char **error_message, bool is_debug, |
| 98 | 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 | 58 | const char *filename, enum ZigLLVM_EmitOutputType output_type, char **error_message, bool is_debug, |
| 59 | 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 | 65 | ZIG_EXTERN_C LLVMTypeRef ZigLLVMTokenTypeInContext(LLVMContextRef context_ref); |
| 62 | 66 | |
| 63 | 67 | enum ZigLLVM_FnInline { |