| author | |
| committer | |
| log | d448c3d38af9f8f70daaa2817a5834e30da4b8ca |
| tree | 647e1885ea02bbe9557338d0edb818f17abaae21 |
| parent | 59bc1d272120bd860cc3cd1f894a2a4e08fc1f3f |
5 files changed, 105 insertions(+), 1 deletions(-)
lib/std/build.zig+6| ... | ... | @@ -1149,6 +1149,7 @@ pub const LibExeObjStep = struct { |
| 1149 | 1149 | name_prefix: []const u8, |
| 1150 | 1150 | filter: ?[]const u8, |
| 1151 | 1151 | single_threaded: bool, |
| 1152 | code_model: builtin.CodeModel = .default, | |
| 1152 | 1153 | |
| 1153 | 1154 | root_src: ?FileSource, |
| 1154 | 1155 | out_h_filename: []const u8, |
| ... | ... | @@ -1970,6 +1971,11 @@ pub const LibExeObjStep = struct { |
| 1970 | 1971 | try zig_args.append("-fno-sanitize-c"); |
| 1971 | 1972 | } |
| 1972 | 1973 | |
| 1974 | if (self.code_model != .default) { | |
| 1975 | try zig_args.append("-code-model"); | |
| 1976 | try zig_args.append(@tagName(self.code_model)); | |
| 1977 | } | |
| 1978 | ||
| 1973 | 1979 | switch (self.target) { |
| 1974 | 1980 | .Native => {}, |
| 1975 | 1981 | .Cross => |cross| { |
lib/std/builtin.zig+15| ... | ... | @@ -91,6 +91,21 @@ pub const AtomicRmwOp = enum { |
| 91 | 91 | Min, |
| 92 | 92 | }; |
| 93 | 93 | |
| 94 | /// The code model puts constraints on the location of symbols and the size of code and data. | |
| 95 | /// The selection of a code model is a trade off on speed and restrictions that needs to be selected on a per application basis to meet its requirements. | |
| 96 | /// A slightly more detailed explanation can be found in (for example) the [System V Application Binary Interface (x86_64)](https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf) 3.5.1. | |
| 97 | /// | |
| 98 | /// This data structure is used by the Zig language code generation and | |
| 99 | /// therefore must be kept in sync with the compiler implementation. | |
| 100 | pub const CodeModel = enum { | |
| 101 | default, | |
| 102 | tiny, | |
| 103 | small, | |
| 104 | kernel, | |
| 105 | medium, | |
| 106 | large, | |
| 107 | }; | |
| 108 | ||
| 94 | 109 | /// This data structure is used by the Zig language code generation and |
| 95 | 110 | /// therefore must be kept in sync with the compiler implementation. |
| 96 | 111 | pub const Mode = enum { |
src/all_types.hpp+10| ... | ... | @@ -1947,6 +1947,15 @@ enum BuildMode { |
| 1947 | 1947 | BuildModeSmallRelease, |
| 1948 | 1948 | }; |
| 1949 | 1949 | |
| 1950 | enum CodeModel { | |
| 1951 | CodeModelDefault, | |
| 1952 | CodeModelTiny, | |
| 1953 | CodeModelSmall, | |
| 1954 | CodeModelKernel, | |
| 1955 | CodeModelMedium, | |
| 1956 | CodeModelLarge, | |
| 1957 | }; | |
| 1958 | ||
| 1950 | 1959 | enum EmitFileType { |
| 1951 | 1960 | EmitFileTypeBinary, |
| 1952 | 1961 | EmitFileTypeAssembly, |
| ... | ... | @@ -2235,6 +2244,7 @@ struct CodeGen { |
| 2235 | 2244 | bool enable_dump_analysis; |
| 2236 | 2245 | bool enable_doc_generation; |
| 2237 | 2246 | bool disable_bin_generation; |
| 2247 | CodeModel code_model; | |
| 2238 | 2248 | |
| 2239 | 2249 | Buf *mmacosx_version_min; |
| 2240 | 2250 | Buf *mios_version_min; |
src/codegen.cpp+52-1| ... | ... | @@ -8365,6 +8365,25 @@ static bool detect_err_ret_tracing(CodeGen *g) { |
| 8365 | 8365 | g->build_mode != BuildModeSmallRelease; |
| 8366 | 8366 | } |
| 8367 | 8367 | |
| 8368 | static LLVMCodeModel to_llvm_code_model(CodeGen *g) { | |
| 8369 | switch (g->code_model) { | |
| 8370 | case CodeModelDefault: | |
| 8371 | return LLVMCodeModelDefault; | |
| 8372 | case CodeModelTiny: | |
| 8373 | return LLVMCodeModelTiny; | |
| 8374 | case CodeModelSmall: | |
| 8375 | return LLVMCodeModelSmall; | |
| 8376 | case CodeModelKernel: | |
| 8377 | return LLVMCodeModelKernel; | |
| 8378 | case CodeModelMedium: | |
| 8379 | return LLVMCodeModelMedium; | |
| 8380 | case CodeModelLarge: | |
| 8381 | return LLVMCodeModelLarge; | |
| 8382 | } | |
| 8383 | ||
| 8384 | zig_unreachable(); | |
| 8385 | } | |
| 8386 | ||
| 8368 | 8387 | Buf *codegen_generate_builtin_source(CodeGen *g) { |
| 8369 | 8388 | g->have_dynamic_link = detect_dynamic_link(g); |
| 8370 | 8389 | g->have_pic = detect_pic(g); |
| ... | ... | @@ -8544,6 +8563,34 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { |
| 8544 | 8563 | buf_appendf(contents, "pub const position_independent_code = %s;\n", bool_to_str(g->have_pic)); |
| 8545 | 8564 | buf_appendf(contents, "pub const strip_debug_info = %s;\n", bool_to_str(g->strip_debug_symbols)); |
| 8546 | 8565 | |
| 8566 | { | |
| 8567 | const char *code_model; | |
| 8568 | switch (g->code_model) { | |
| 8569 | case CodeModelDefault: | |
| 8570 | code_model = "default"; | |
| 8571 | break; | |
| 8572 | case CodeModelTiny: | |
| 8573 | code_model = "tiny"; | |
| 8574 | break; | |
| 8575 | case CodeModelSmall: | |
| 8576 | code_model = "small"; | |
| 8577 | break; | |
| 8578 | case CodeModelKernel: | |
| 8579 | code_model = "kernel"; | |
| 8580 | break; | |
| 8581 | case CodeModelMedium: | |
| 8582 | code_model = "medium"; | |
| 8583 | break; | |
| 8584 | case CodeModelLarge: | |
| 8585 | code_model = "large"; | |
| 8586 | break; | |
| 8587 | default: | |
| 8588 | zig_unreachable(); | |
| 8589 | } | |
| 8590 | ||
| 8591 | buf_appendf(contents, "pub const code_model = CodeModel.%s;\n", code_model); | |
| 8592 | } | |
| 8593 | ||
| 8547 | 8594 | { |
| 8548 | 8595 | TargetSubsystem detected_subsystem = detect_subsystem(g); |
| 8549 | 8596 | if (detected_subsystem != TargetSubsystemAuto) { |
| ... | ... | @@ -8588,6 +8635,7 @@ static Error define_builtin_compile_vars(CodeGen *g) { |
| 8588 | 8635 | cache_bool(&cache_hash, g->is_dynamic); |
| 8589 | 8636 | cache_bool(&cache_hash, g->is_test_build); |
| 8590 | 8637 | cache_bool(&cache_hash, g->is_single_threaded); |
| 8638 | cache_int(&cache_hash, g->code_model); | |
| 8591 | 8639 | cache_int(&cache_hash, g->zig_target->is_native); |
| 8592 | 8640 | cache_int(&cache_hash, g->zig_target->arch); |
| 8593 | 8641 | cache_int(&cache_hash, g->zig_target->sub_arch); |
| ... | ... | @@ -8745,7 +8793,7 @@ static void init(CodeGen *g) { |
| 8745 | 8793 | |
| 8746 | 8794 | g->target_machine = ZigLLVMCreateTargetMachine(target_ref, buf_ptr(&g->llvm_triple_str), |
| 8747 | 8795 | target_specific_cpu_args, target_specific_features, opt_level, reloc_mode, |
| 8748 | LLVMCodeModelDefault, g->function_sections); | |
| 8796 | to_llvm_code_model(g), g->function_sections); | |
| 8749 | 8797 | |
| 8750 | 8798 | g->target_data_ref = LLVMCreateTargetDataLayout(g->target_machine); |
| 8751 | 8799 | |
| ... | ... | @@ -9527,6 +9575,8 @@ Error create_c_object_cache(CodeGen *g, CacheHash **out_cache_hash, bool verbose |
| 9527 | 9575 | cache_bool(cache_hash, g->have_sanitize_c); |
| 9528 | 9576 | cache_bool(cache_hash, want_valgrind_support(g)); |
| 9529 | 9577 | cache_bool(cache_hash, g->function_sections); |
| 9578 | cache_int(cache_hash, g->code_model); | |
| 9579 | ||
| 9530 | 9580 | for (size_t arg_i = 0; arg_i < g->clang_argv_len; arg_i += 1) { |
| 9531 | 9581 | cache_str(cache_hash, g->clang_argv[arg_i]); |
| 9532 | 9582 | } |
| ... | ... | @@ -10696,6 +10746,7 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget |
| 10696 | 10746 | g->one_possible_values.init(32); |
| 10697 | 10747 | g->is_test_build = is_test_build; |
| 10698 | 10748 | g->is_single_threaded = false; |
| 10749 | g->code_model = CodeModelDefault; | |
| 10699 | 10750 | buf_resize(&g->global_asm, 0); |
| 10700 | 10751 | |
| 10701 | 10752 | for (size_t i = 0; i < array_length(symbols_that_llvm_depends_on); i += 1) { |
src/main.cpp+22| ... | ... | @@ -103,6 +103,9 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) { |
| 103 | 103 | " -D[macro]=[value] define C [macro] to [value] (1 if [value] omitted)\n" |
| 104 | 104 | " -target-cpu [cpu] target one specific CPU by name\n" |
| 105 | 105 | " -target-feature [features] specify the set of CPU features to target\n" |
| 106 | " -code-model [default|tiny| set target code model\n" | |
| 107 | " small|kernel|\n" | |
| 108 | " medium|large]\n" | |
| 106 | 109 | "\n" |
| 107 | 110 | "Link Options:\n" |
| 108 | 111 | " --bundle-compiler-rt for static libraries, include compiler-rt symbols\n" |
| ... | ... | @@ -452,6 +455,7 @@ int main(int argc, char **argv) { |
| 452 | 455 | bool function_sections = false; |
| 453 | 456 | const char *cpu = nullptr; |
| 454 | 457 | const char *features = nullptr; |
| 458 | CodeModel code_model = CodeModelDefault; | |
| 455 | 459 | |
| 456 | 460 | ZigList<const char *> llvm_argv = {0}; |
| 457 | 461 | llvm_argv.append("zig (LLVM option parsing)"); |
| ... | ... | @@ -768,6 +772,23 @@ int main(int argc, char **argv) { |
| 768 | 772 | clang_argv.append(argv[i]); |
| 769 | 773 | |
| 770 | 774 | llvm_argv.append(argv[i]); |
| 775 | } else if (strcmp(arg, "-code-model") == 0) { | |
| 776 | if (strcmp(argv[i], "default") == 0) { | |
| 777 | code_model = CodeModelDefault; | |
| 778 | } else if (strcmp(argv[i], "tiny") == 0) { | |
| 779 | code_model = CodeModelTiny; | |
| 780 | } else if (strcmp(argv[i], "small") == 0) { | |
| 781 | code_model = CodeModelSmall; | |
| 782 | } else if (strcmp(argv[i], "kernel") == 0) { | |
| 783 | code_model = CodeModelKernel; | |
| 784 | } else if (strcmp(argv[i], "medium") == 0) { | |
| 785 | code_model = CodeModelMedium; | |
| 786 | } else if (strcmp(argv[i], "large") == 0) { | |
| 787 | code_model = CodeModelLarge; | |
| 788 | } else { | |
| 789 | fprintf(stderr, "-code-model options are 'default', 'tiny', 'small', 'kernel', 'medium', or 'large'\n"); | |
| 790 | return print_error_usage(arg0); | |
| 791 | } | |
| 771 | 792 | } else if (strcmp(arg, "--override-lib-dir") == 0) { |
| 772 | 793 | override_lib_dir = buf_create_from_str(argv[i]); |
| 773 | 794 | } else if (strcmp(arg, "--main-pkg-path") == 0) { |
| ... | ... | @@ -1170,6 +1191,7 @@ int main(int argc, char **argv) { |
| 1170 | 1191 | codegen_set_errmsg_color(g, color); |
| 1171 | 1192 | g->system_linker_hack = system_linker_hack; |
| 1172 | 1193 | g->function_sections = function_sections; |
| 1194 | g->code_model = code_model; | |
| 1173 | 1195 | |
| 1174 | 1196 | |
| 1175 | 1197 | for (size_t i = 0; i < lib_dirs.length; i += 1) { |