authorgravatar for syrupthinker@gryphno.deValentin Anger <syrupthinker@gryphno.de> 2020-01-29 13:22:11+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-01-29 16:09:07-05:00
logd448c3d38af9f8f70daaa2817a5834e30da4b8ca
tree647e1885ea02bbe9557338d0edb818f17abaae21
parent59bc1d272120bd860cc3cd1f894a2a4e08fc1f3f

Add support for code model selection


5 files changed, 105 insertions(+), 1 deletions(-)

lib/std/build.zig+6
...@@ -1149,6 +1149,7 @@ pub const LibExeObjStep = struct {...@@ -1149,6 +1149,7 @@ pub const LibExeObjStep = struct {
1149 name_prefix: []const u8,1149 name_prefix: []const u8,
1150 filter: ?[]const u8,1150 filter: ?[]const u8,
1151 single_threaded: bool,1151 single_threaded: bool,
1152 code_model: builtin.CodeModel = .default,
11521153
1153 root_src: ?FileSource,1154 root_src: ?FileSource,
1154 out_h_filename: []const u8,1155 out_h_filename: []const u8,
...@@ -1970,6 +1971,11 @@ pub const LibExeObjStep = struct {...@@ -1970,6 +1971,11 @@ pub const LibExeObjStep = struct {
1970 try zig_args.append("-fno-sanitize-c");1971 try zig_args.append("-fno-sanitize-c");
1971 }1972 }
19721973
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 switch (self.target) {1979 switch (self.target) {
1974 .Native => {},1980 .Native => {},
1975 .Cross => |cross| {1981 .Cross => |cross| {
lib/std/builtin.zig+15
...@@ -91,6 +91,21 @@ pub const AtomicRmwOp = enum {...@@ -91,6 +91,21 @@ pub const AtomicRmwOp = enum {
91 Min,91 Min,
92};92};
9393
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.
100pub const CodeModel = enum {
101 default,
102 tiny,
103 small,
104 kernel,
105 medium,
106 large,
107};
108
94/// This data structure is used by the Zig language code generation and109/// This data structure is used by the Zig language code generation and
95/// therefore must be kept in sync with the compiler implementation.110/// therefore must be kept in sync with the compiler implementation.
96pub const Mode = enum {111pub const Mode = enum {
src/all_types.hpp+10
...@@ -1947,6 +1947,15 @@ enum BuildMode {...@@ -1947,6 +1947,15 @@ enum BuildMode {
1947 BuildModeSmallRelease,1947 BuildModeSmallRelease,
1948};1948};
19491949
1950enum CodeModel {
1951 CodeModelDefault,
1952 CodeModelTiny,
1953 CodeModelSmall,
1954 CodeModelKernel,
1955 CodeModelMedium,
1956 CodeModelLarge,
1957};
1958
1950enum EmitFileType {1959enum EmitFileType {
1951 EmitFileTypeBinary,1960 EmitFileTypeBinary,
1952 EmitFileTypeAssembly,1961 EmitFileTypeAssembly,
...@@ -2235,6 +2244,7 @@ struct CodeGen {...@@ -2235,6 +2244,7 @@ struct CodeGen {
2235 bool enable_dump_analysis;2244 bool enable_dump_analysis;
2236 bool enable_doc_generation;2245 bool enable_doc_generation;
2237 bool disable_bin_generation;2246 bool disable_bin_generation;
2247 CodeModel code_model;
22382248
2239 Buf *mmacosx_version_min;2249 Buf *mmacosx_version_min;
2240 Buf *mios_version_min;2250 Buf *mios_version_min;
src/codegen.cpp+52-1
...@@ -8365,6 +8365,25 @@ static bool detect_err_ret_tracing(CodeGen *g) {...@@ -8365,6 +8365,25 @@ static bool detect_err_ret_tracing(CodeGen *g) {
8365 g->build_mode != BuildModeSmallRelease;8365 g->build_mode != BuildModeSmallRelease;
8366}8366}
83678367
8368static 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
8368Buf *codegen_generate_builtin_source(CodeGen *g) {8387Buf *codegen_generate_builtin_source(CodeGen *g) {
8369 g->have_dynamic_link = detect_dynamic_link(g);8388 g->have_dynamic_link = detect_dynamic_link(g);
8370 g->have_pic = detect_pic(g);8389 g->have_pic = detect_pic(g);
...@@ -8544,6 +8563,34 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {...@@ -8544,6 +8563,34 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
8544 buf_appendf(contents, "pub const position_independent_code = %s;\n", bool_to_str(g->have_pic));8563 buf_appendf(contents, "pub const position_independent_code = %s;\n", bool_to_str(g->have_pic));
8545 buf_appendf(contents, "pub const strip_debug_info = %s;\n", bool_to_str(g->strip_debug_symbols));8564 buf_appendf(contents, "pub const strip_debug_info = %s;\n", bool_to_str(g->strip_debug_symbols));
85468565
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 TargetSubsystem detected_subsystem = detect_subsystem(g);8595 TargetSubsystem detected_subsystem = detect_subsystem(g);
8549 if (detected_subsystem != TargetSubsystemAuto) {8596 if (detected_subsystem != TargetSubsystemAuto) {
...@@ -8588,6 +8635,7 @@ static Error define_builtin_compile_vars(CodeGen *g) {...@@ -8588,6 +8635,7 @@ static Error define_builtin_compile_vars(CodeGen *g) {
8588 cache_bool(&cache_hash, g->is_dynamic);8635 cache_bool(&cache_hash, g->is_dynamic);
8589 cache_bool(&cache_hash, g->is_test_build);8636 cache_bool(&cache_hash, g->is_test_build);
8590 cache_bool(&cache_hash, g->is_single_threaded);8637 cache_bool(&cache_hash, g->is_single_threaded);
8638 cache_int(&cache_hash, g->code_model);
8591 cache_int(&cache_hash, g->zig_target->is_native);8639 cache_int(&cache_hash, g->zig_target->is_native);
8592 cache_int(&cache_hash, g->zig_target->arch);8640 cache_int(&cache_hash, g->zig_target->arch);
8593 cache_int(&cache_hash, g->zig_target->sub_arch);8641 cache_int(&cache_hash, g->zig_target->sub_arch);
...@@ -8745,7 +8793,7 @@ static void init(CodeGen *g) {...@@ -8745,7 +8793,7 @@ static void init(CodeGen *g) {
8745 8793
8746 g->target_machine = ZigLLVMCreateTargetMachine(target_ref, buf_ptr(&g->llvm_triple_str),8794 g->target_machine = ZigLLVMCreateTargetMachine(target_ref, buf_ptr(&g->llvm_triple_str),
8747 target_specific_cpu_args, target_specific_features, opt_level, reloc_mode,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);
87498797
8750 g->target_data_ref = LLVMCreateTargetDataLayout(g->target_machine);8798 g->target_data_ref = LLVMCreateTargetDataLayout(g->target_machine);
87518799
...@@ -9527,6 +9575,8 @@ Error create_c_object_cache(CodeGen *g, CacheHash **out_cache_hash, bool verbose...@@ -9527,6 +9575,8 @@ Error create_c_object_cache(CodeGen *g, CacheHash **out_cache_hash, bool verbose
9527 cache_bool(cache_hash, g->have_sanitize_c);9575 cache_bool(cache_hash, g->have_sanitize_c);
9528 cache_bool(cache_hash, want_valgrind_support(g));9576 cache_bool(cache_hash, want_valgrind_support(g));
9529 cache_bool(cache_hash, g->function_sections);9577 cache_bool(cache_hash, g->function_sections);
9578 cache_int(cache_hash, g->code_model);
9579
9530 for (size_t arg_i = 0; arg_i < g->clang_argv_len; arg_i += 1) {9580 for (size_t arg_i = 0; arg_i < g->clang_argv_len; arg_i += 1) {
9531 cache_str(cache_hash, g->clang_argv[arg_i]);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,6 +10746,7 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget
10696 g->one_possible_values.init(32);10746 g->one_possible_values.init(32);
10697 g->is_test_build = is_test_build;10747 g->is_test_build = is_test_build;
10698 g->is_single_threaded = false;10748 g->is_single_threaded = false;
10749 g->code_model = CodeModelDefault;
10699 buf_resize(&g->global_asm, 0);10750 buf_resize(&g->global_asm, 0);
1070010751
10701 for (size_t i = 0; i < array_length(symbols_that_llvm_depends_on); i += 1) {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,6 +103,9 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {
103 " -D[macro]=[value] define C [macro] to [value] (1 if [value] omitted)\n"103 " -D[macro]=[value] define C [macro] to [value] (1 if [value] omitted)\n"
104 " -target-cpu [cpu] target one specific CPU by name\n"104 " -target-cpu [cpu] target one specific CPU by name\n"
105 " -target-feature [features] specify the set of CPU features to target\n"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 "\n"109 "\n"
107 "Link Options:\n"110 "Link Options:\n"
108 " --bundle-compiler-rt for static libraries, include compiler-rt symbols\n"111 " --bundle-compiler-rt for static libraries, include compiler-rt symbols\n"
...@@ -452,6 +455,7 @@ int main(int argc, char **argv) {...@@ -452,6 +455,7 @@ int main(int argc, char **argv) {
452 bool function_sections = false;455 bool function_sections = false;
453 const char *cpu = nullptr;456 const char *cpu = nullptr;
454 const char *features = nullptr;457 const char *features = nullptr;
458 CodeModel code_model = CodeModelDefault;
455459
456 ZigList<const char *> llvm_argv = {0};460 ZigList<const char *> llvm_argv = {0};
457 llvm_argv.append("zig (LLVM option parsing)");461 llvm_argv.append("zig (LLVM option parsing)");
...@@ -768,6 +772,23 @@ int main(int argc, char **argv) {...@@ -768,6 +772,23 @@ int main(int argc, char **argv) {
768 clang_argv.append(argv[i]);772 clang_argv.append(argv[i]);
769773
770 llvm_argv.append(argv[i]);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 } else if (strcmp(arg, "--override-lib-dir") == 0) {792 } else if (strcmp(arg, "--override-lib-dir") == 0) {
772 override_lib_dir = buf_create_from_str(argv[i]);793 override_lib_dir = buf_create_from_str(argv[i]);
773 } else if (strcmp(arg, "--main-pkg-path") == 0) {794 } else if (strcmp(arg, "--main-pkg-path") == 0) {
...@@ -1170,6 +1191,7 @@ int main(int argc, char **argv) {...@@ -1170,6 +1191,7 @@ int main(int argc, char **argv) {
1170 codegen_set_errmsg_color(g, color);1191 codegen_set_errmsg_color(g, color);
1171 g->system_linker_hack = system_linker_hack;1192 g->system_linker_hack = system_linker_hack;
1172 g->function_sections = function_sections;1193 g->function_sections = function_sections;
1194 g->code_model = code_model;
11731195
11741196
1175 for (size_t i = 0; i < lib_dirs.length; i += 1) {1197 for (size_t i = 0; i < lib_dirs.length; i += 1) {