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 {
11491149 name_prefix: []const u8,
11501150 filter: ?[]const u8,
11511151 single_threaded: bool,
1152 code_model: builtin.CodeModel = .default,
11521153
11531154 root_src: ?FileSource,
11541155 out_h_filename: []const u8,
......@@ -1970,6 +1971,11 @@ pub const LibExeObjStep = struct {
19701971 try zig_args.append("-fno-sanitize-c");
19711972 }
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
19731979 switch (self.target) {
19741980 .Native => {},
19751981 .Cross => |cross| {
lib/std/builtin.zig+15
......@@ -91,6 +91,21 @@ pub const AtomicRmwOp = enum {
9191 Min,
9292};
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
94109/// This data structure is used by the Zig language code generation and
95110/// therefore must be kept in sync with the compiler implementation.
96111pub const Mode = enum {
src/all_types.hpp+10
......@@ -1947,6 +1947,15 @@ enum BuildMode {
19471947 BuildModeSmallRelease,
19481948};
19491949
1950enum CodeModel {
1951 CodeModelDefault,
1952 CodeModelTiny,
1953 CodeModelSmall,
1954 CodeModelKernel,
1955 CodeModelMedium,
1956 CodeModelLarge,
1957};
1958
19501959enum EmitFileType {
19511960 EmitFileTypeBinary,
19521961 EmitFileTypeAssembly,
......@@ -2235,6 +2244,7 @@ struct CodeGen {
22352244 bool enable_dump_analysis;
22362245 bool enable_doc_generation;
22372246 bool disable_bin_generation;
2247 CodeModel code_model;
22382248
22392249 Buf *mmacosx_version_min;
22402250 Buf *mios_version_min;
src/codegen.cpp+52-1
......@@ -8365,6 +8365,25 @@ static bool detect_err_ret_tracing(CodeGen *g) {
83658365 g->build_mode != BuildModeSmallRelease;
83668366}
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
83688387Buf *codegen_generate_builtin_source(CodeGen *g) {
83698388 g->have_dynamic_link = detect_dynamic_link(g);
83708389 g->have_pic = detect_pic(g);
......@@ -8544,6 +8563,34 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
85448563 buf_appendf(contents, "pub const position_independent_code = %s;\n", bool_to_str(g->have_pic));
85458564 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
85478594 {
85488595 TargetSubsystem detected_subsystem = detect_subsystem(g);
85498596 if (detected_subsystem != TargetSubsystemAuto) {
......@@ -8588,6 +8635,7 @@ static Error define_builtin_compile_vars(CodeGen *g) {
85888635 cache_bool(&cache_hash, g->is_dynamic);
85898636 cache_bool(&cache_hash, g->is_test_build);
85908637 cache_bool(&cache_hash, g->is_single_threaded);
8638 cache_int(&cache_hash, g->code_model);
85918639 cache_int(&cache_hash, g->zig_target->is_native);
85928640 cache_int(&cache_hash, g->zig_target->arch);
85938641 cache_int(&cache_hash, g->zig_target->sub_arch);
......@@ -8745,7 +8793,7 @@ static void init(CodeGen *g) {
87458793
87468794 g->target_machine = ZigLLVMCreateTargetMachine(target_ref, buf_ptr(&g->llvm_triple_str),
87478795 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
87508798 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
95279575 cache_bool(cache_hash, g->have_sanitize_c);
95289576 cache_bool(cache_hash, want_valgrind_support(g));
95299577 cache_bool(cache_hash, g->function_sections);
9578 cache_int(cache_hash, g->code_model);
9579
95309580 for (size_t arg_i = 0; arg_i < g->clang_argv_len; arg_i += 1) {
95319581 cache_str(cache_hash, g->clang_argv[arg_i]);
95329582 }
......@@ -10696,6 +10746,7 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget
1069610746 g->one_possible_values.init(32);
1069710747 g->is_test_build = is_test_build;
1069810748 g->is_single_threaded = false;
10749 g->code_model = CodeModelDefault;
1069910750 buf_resize(&g->global_asm, 0);
1070010751
1070110752 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) {
103103 " -D[macro]=[value] define C [macro] to [value] (1 if [value] omitted)\n"
104104 " -target-cpu [cpu] target one specific CPU by name\n"
105105 " -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"
106109 "\n"
107110 "Link Options:\n"
108111 " --bundle-compiler-rt for static libraries, include compiler-rt symbols\n"
......@@ -452,6 +455,7 @@ int main(int argc, char **argv) {
452455 bool function_sections = false;
453456 const char *cpu = nullptr;
454457 const char *features = nullptr;
458 CodeModel code_model = CodeModelDefault;
455459
456460 ZigList<const char *> llvm_argv = {0};
457461 llvm_argv.append("zig (LLVM option parsing)");
......@@ -768,6 +772,23 @@ int main(int argc, char **argv) {
768772 clang_argv.append(argv[i]);
769773
770774 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 }
771792 } else if (strcmp(arg, "--override-lib-dir") == 0) {
772793 override_lib_dir = buf_create_from_str(argv[i]);
773794 } else if (strcmp(arg, "--main-pkg-path") == 0) {
......@@ -1170,6 +1191,7 @@ int main(int argc, char **argv) {
11701191 codegen_set_errmsg_color(g, color);
11711192 g->system_linker_hack = system_linker_hack;
11721193 g->function_sections = function_sections;
1194 g->code_model = code_model;
11731195
11741196
11751197 for (size_t i = 0; i < lib_dirs.length; i += 1) {