Add support for code model selection
This commit is contained in:
parent
59bc1d2721
commit
d448c3d38a
@ -1149,6 +1149,7 @@ pub const LibExeObjStep = struct {
|
|||||||
name_prefix: []const u8,
|
name_prefix: []const u8,
|
||||||
filter: ?[]const u8,
|
filter: ?[]const u8,
|
||||||
single_threaded: bool,
|
single_threaded: bool,
|
||||||
|
code_model: builtin.CodeModel = .default,
|
||||||
|
|
||||||
root_src: ?FileSource,
|
root_src: ?FileSource,
|
||||||
out_h_filename: []const u8,
|
out_h_filename: []const u8,
|
||||||
@ -1970,6 +1971,11 @@ pub const LibExeObjStep = struct {
|
|||||||
try zig_args.append("-fno-sanitize-c");
|
try zig_args.append("-fno-sanitize-c");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (self.code_model != .default) {
|
||||||
|
try zig_args.append("-code-model");
|
||||||
|
try zig_args.append(@tagName(self.code_model));
|
||||||
|
}
|
||||||
|
|
||||||
switch (self.target) {
|
switch (self.target) {
|
||||||
.Native => {},
|
.Native => {},
|
||||||
.Cross => |cross| {
|
.Cross => |cross| {
|
||||||
|
@ -91,6 +91,21 @@ pub const AtomicRmwOp = enum {
|
|||||||
Min,
|
Min,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// The code model puts constraints on the location of symbols and the size of code and data.
|
||||||
|
/// 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.
|
||||||
|
/// 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.
|
||||||
|
///
|
||||||
|
/// This data structure is used by the Zig language code generation and
|
||||||
|
/// therefore must be kept in sync with the compiler implementation.
|
||||||
|
pub const CodeModel = enum {
|
||||||
|
default,
|
||||||
|
tiny,
|
||||||
|
small,
|
||||||
|
kernel,
|
||||||
|
medium,
|
||||||
|
large,
|
||||||
|
};
|
||||||
|
|
||||||
/// This data structure is used by the Zig language code generation and
|
/// This data structure is used by the Zig language code generation and
|
||||||
/// therefore must be kept in sync with the compiler implementation.
|
/// therefore must be kept in sync with the compiler implementation.
|
||||||
pub const Mode = enum {
|
pub const Mode = enum {
|
||||||
|
@ -1947,6 +1947,15 @@ enum BuildMode {
|
|||||||
BuildModeSmallRelease,
|
BuildModeSmallRelease,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum CodeModel {
|
||||||
|
CodeModelDefault,
|
||||||
|
CodeModelTiny,
|
||||||
|
CodeModelSmall,
|
||||||
|
CodeModelKernel,
|
||||||
|
CodeModelMedium,
|
||||||
|
CodeModelLarge,
|
||||||
|
};
|
||||||
|
|
||||||
enum EmitFileType {
|
enum EmitFileType {
|
||||||
EmitFileTypeBinary,
|
EmitFileTypeBinary,
|
||||||
EmitFileTypeAssembly,
|
EmitFileTypeAssembly,
|
||||||
@ -2235,6 +2244,7 @@ struct CodeGen {
|
|||||||
bool enable_dump_analysis;
|
bool enable_dump_analysis;
|
||||||
bool enable_doc_generation;
|
bool enable_doc_generation;
|
||||||
bool disable_bin_generation;
|
bool disable_bin_generation;
|
||||||
|
CodeModel code_model;
|
||||||
|
|
||||||
Buf *mmacosx_version_min;
|
Buf *mmacosx_version_min;
|
||||||
Buf *mios_version_min;
|
Buf *mios_version_min;
|
||||||
|
@ -8365,6 +8365,25 @@ static bool detect_err_ret_tracing(CodeGen *g) {
|
|||||||
g->build_mode != BuildModeSmallRelease;
|
g->build_mode != BuildModeSmallRelease;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static LLVMCodeModel to_llvm_code_model(CodeGen *g) {
|
||||||
|
switch (g->code_model) {
|
||||||
|
case CodeModelDefault:
|
||||||
|
return LLVMCodeModelDefault;
|
||||||
|
case CodeModelTiny:
|
||||||
|
return LLVMCodeModelTiny;
|
||||||
|
case CodeModelSmall:
|
||||||
|
return LLVMCodeModelSmall;
|
||||||
|
case CodeModelKernel:
|
||||||
|
return LLVMCodeModelKernel;
|
||||||
|
case CodeModelMedium:
|
||||||
|
return LLVMCodeModelMedium;
|
||||||
|
case CodeModelLarge:
|
||||||
|
return LLVMCodeModelLarge;
|
||||||
|
}
|
||||||
|
|
||||||
|
zig_unreachable();
|
||||||
|
}
|
||||||
|
|
||||||
Buf *codegen_generate_builtin_source(CodeGen *g) {
|
Buf *codegen_generate_builtin_source(CodeGen *g) {
|
||||||
g->have_dynamic_link = detect_dynamic_link(g);
|
g->have_dynamic_link = detect_dynamic_link(g);
|
||||||
g->have_pic = detect_pic(g);
|
g->have_pic = detect_pic(g);
|
||||||
@ -8544,6 +8563,34 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
|
|||||||
buf_appendf(contents, "pub const position_independent_code = %s;\n", bool_to_str(g->have_pic));
|
buf_appendf(contents, "pub const position_independent_code = %s;\n", bool_to_str(g->have_pic));
|
||||||
buf_appendf(contents, "pub const strip_debug_info = %s;\n", bool_to_str(g->strip_debug_symbols));
|
buf_appendf(contents, "pub const strip_debug_info = %s;\n", bool_to_str(g->strip_debug_symbols));
|
||||||
|
|
||||||
|
{
|
||||||
|
const char *code_model;
|
||||||
|
switch (g->code_model) {
|
||||||
|
case CodeModelDefault:
|
||||||
|
code_model = "default";
|
||||||
|
break;
|
||||||
|
case CodeModelTiny:
|
||||||
|
code_model = "tiny";
|
||||||
|
break;
|
||||||
|
case CodeModelSmall:
|
||||||
|
code_model = "small";
|
||||||
|
break;
|
||||||
|
case CodeModelKernel:
|
||||||
|
code_model = "kernel";
|
||||||
|
break;
|
||||||
|
case CodeModelMedium:
|
||||||
|
code_model = "medium";
|
||||||
|
break;
|
||||||
|
case CodeModelLarge:
|
||||||
|
code_model = "large";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
zig_unreachable();
|
||||||
|
}
|
||||||
|
|
||||||
|
buf_appendf(contents, "pub const code_model = CodeModel.%s;\n", code_model);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
TargetSubsystem detected_subsystem = detect_subsystem(g);
|
TargetSubsystem detected_subsystem = detect_subsystem(g);
|
||||||
if (detected_subsystem != TargetSubsystemAuto) {
|
if (detected_subsystem != TargetSubsystemAuto) {
|
||||||
@ -8588,6 +8635,7 @@ static Error define_builtin_compile_vars(CodeGen *g) {
|
|||||||
cache_bool(&cache_hash, g->is_dynamic);
|
cache_bool(&cache_hash, g->is_dynamic);
|
||||||
cache_bool(&cache_hash, g->is_test_build);
|
cache_bool(&cache_hash, g->is_test_build);
|
||||||
cache_bool(&cache_hash, g->is_single_threaded);
|
cache_bool(&cache_hash, g->is_single_threaded);
|
||||||
|
cache_int(&cache_hash, g->code_model);
|
||||||
cache_int(&cache_hash, g->zig_target->is_native);
|
cache_int(&cache_hash, g->zig_target->is_native);
|
||||||
cache_int(&cache_hash, g->zig_target->arch);
|
cache_int(&cache_hash, g->zig_target->arch);
|
||||||
cache_int(&cache_hash, g->zig_target->sub_arch);
|
cache_int(&cache_hash, g->zig_target->sub_arch);
|
||||||
@ -8745,7 +8793,7 @@ static void init(CodeGen *g) {
|
|||||||
|
|
||||||
g->target_machine = ZigLLVMCreateTargetMachine(target_ref, buf_ptr(&g->llvm_triple_str),
|
g->target_machine = ZigLLVMCreateTargetMachine(target_ref, buf_ptr(&g->llvm_triple_str),
|
||||||
target_specific_cpu_args, target_specific_features, opt_level, reloc_mode,
|
target_specific_cpu_args, target_specific_features, opt_level, reloc_mode,
|
||||||
LLVMCodeModelDefault, g->function_sections);
|
to_llvm_code_model(g), g->function_sections);
|
||||||
|
|
||||||
g->target_data_ref = LLVMCreateTargetDataLayout(g->target_machine);
|
g->target_data_ref = LLVMCreateTargetDataLayout(g->target_machine);
|
||||||
|
|
||||||
@ -9527,6 +9575,8 @@ Error create_c_object_cache(CodeGen *g, CacheHash **out_cache_hash, bool verbose
|
|||||||
cache_bool(cache_hash, g->have_sanitize_c);
|
cache_bool(cache_hash, g->have_sanitize_c);
|
||||||
cache_bool(cache_hash, want_valgrind_support(g));
|
cache_bool(cache_hash, want_valgrind_support(g));
|
||||||
cache_bool(cache_hash, g->function_sections);
|
cache_bool(cache_hash, g->function_sections);
|
||||||
|
cache_int(cache_hash, g->code_model);
|
||||||
|
|
||||||
for (size_t arg_i = 0; arg_i < g->clang_argv_len; arg_i += 1) {
|
for (size_t arg_i = 0; arg_i < g->clang_argv_len; arg_i += 1) {
|
||||||
cache_str(cache_hash, g->clang_argv[arg_i]);
|
cache_str(cache_hash, g->clang_argv[arg_i]);
|
||||||
}
|
}
|
||||||
@ -10696,6 +10746,7 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget
|
|||||||
g->one_possible_values.init(32);
|
g->one_possible_values.init(32);
|
||||||
g->is_test_build = is_test_build;
|
g->is_test_build = is_test_build;
|
||||||
g->is_single_threaded = false;
|
g->is_single_threaded = false;
|
||||||
|
g->code_model = CodeModelDefault;
|
||||||
buf_resize(&g->global_asm, 0);
|
buf_resize(&g->global_asm, 0);
|
||||||
|
|
||||||
for (size_t i = 0; i < array_length(symbols_that_llvm_depends_on); i += 1) {
|
for (size_t i = 0; i < array_length(symbols_that_llvm_depends_on); i += 1) {
|
||||||
|
22
src/main.cpp
22
src/main.cpp
@ -103,6 +103,9 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {
|
|||||||
" -D[macro]=[value] define C [macro] to [value] (1 if [value] omitted)\n"
|
" -D[macro]=[value] define C [macro] to [value] (1 if [value] omitted)\n"
|
||||||
" -target-cpu [cpu] target one specific CPU by name\n"
|
" -target-cpu [cpu] target one specific CPU by name\n"
|
||||||
" -target-feature [features] specify the set of CPU features to target\n"
|
" -target-feature [features] specify the set of CPU features to target\n"
|
||||||
|
" -code-model [default|tiny| set target code model\n"
|
||||||
|
" small|kernel|\n"
|
||||||
|
" medium|large]\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Link Options:\n"
|
"Link Options:\n"
|
||||||
" --bundle-compiler-rt for static libraries, include compiler-rt symbols\n"
|
" --bundle-compiler-rt for static libraries, include compiler-rt symbols\n"
|
||||||
@ -452,6 +455,7 @@ int main(int argc, char **argv) {
|
|||||||
bool function_sections = false;
|
bool function_sections = false;
|
||||||
const char *cpu = nullptr;
|
const char *cpu = nullptr;
|
||||||
const char *features = nullptr;
|
const char *features = nullptr;
|
||||||
|
CodeModel code_model = CodeModelDefault;
|
||||||
|
|
||||||
ZigList<const char *> llvm_argv = {0};
|
ZigList<const char *> llvm_argv = {0};
|
||||||
llvm_argv.append("zig (LLVM option parsing)");
|
llvm_argv.append("zig (LLVM option parsing)");
|
||||||
@ -768,6 +772,23 @@ int main(int argc, char **argv) {
|
|||||||
clang_argv.append(argv[i]);
|
clang_argv.append(argv[i]);
|
||||||
|
|
||||||
llvm_argv.append(argv[i]);
|
llvm_argv.append(argv[i]);
|
||||||
|
} else if (strcmp(arg, "-code-model") == 0) {
|
||||||
|
if (strcmp(argv[i], "default") == 0) {
|
||||||
|
code_model = CodeModelDefault;
|
||||||
|
} else if (strcmp(argv[i], "tiny") == 0) {
|
||||||
|
code_model = CodeModelTiny;
|
||||||
|
} else if (strcmp(argv[i], "small") == 0) {
|
||||||
|
code_model = CodeModelSmall;
|
||||||
|
} else if (strcmp(argv[i], "kernel") == 0) {
|
||||||
|
code_model = CodeModelKernel;
|
||||||
|
} else if (strcmp(argv[i], "medium") == 0) {
|
||||||
|
code_model = CodeModelMedium;
|
||||||
|
} else if (strcmp(argv[i], "large") == 0) {
|
||||||
|
code_model = CodeModelLarge;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "-code-model options are 'default', 'tiny', 'small', 'kernel', 'medium', or 'large'\n");
|
||||||
|
return print_error_usage(arg0);
|
||||||
|
}
|
||||||
} else if (strcmp(arg, "--override-lib-dir") == 0) {
|
} else if (strcmp(arg, "--override-lib-dir") == 0) {
|
||||||
override_lib_dir = buf_create_from_str(argv[i]);
|
override_lib_dir = buf_create_from_str(argv[i]);
|
||||||
} else if (strcmp(arg, "--main-pkg-path") == 0) {
|
} else if (strcmp(arg, "--main-pkg-path") == 0) {
|
||||||
@ -1170,6 +1191,7 @@ int main(int argc, char **argv) {
|
|||||||
codegen_set_errmsg_color(g, color);
|
codegen_set_errmsg_color(g, color);
|
||||||
g->system_linker_hack = system_linker_hack;
|
g->system_linker_hack = system_linker_hack;
|
||||||
g->function_sections = function_sections;
|
g->function_sections = function_sections;
|
||||||
|
g->code_model = code_model;
|
||||||
|
|
||||||
|
|
||||||
for (size_t i = 0; i < lib_dirs.length; i += 1) {
|
for (size_t i = 0; i < lib_dirs.length; i += 1) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user