From 253ecd5c11747f49575b8425a506c2fecfe26ee2 Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Mon, 16 Apr 2018 03:26:10 +0300 Subject: [PATCH 1/4] Added ReleaseSmall mode --- src/all_types.hpp | 1 + src/codegen.cpp | 18 ++++++++++++------ src/main.cpp | 3 +++ src/zig_llvm.cpp | 4 ++-- src/zig_llvm.h | 2 +- std/build.zig | 15 ++++++++++----- std/special/builtin.zig | 4 +++- 7 files changed, 32 insertions(+), 15 deletions(-) diff --git a/src/all_types.hpp b/src/all_types.hpp index 708ad8179..7ef7c1039 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1457,6 +1457,7 @@ enum BuildMode { BuildModeDebug, BuildModeFastRelease, BuildModeSafeRelease, + BuildModeSmallRelease, }; enum EmitFileType { diff --git a/src/codegen.cpp b/src/codegen.cpp index 9f319d912..0279771be 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -512,7 +512,9 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) { } if (fn_table_entry->body_node != nullptr) { - bool want_fn_safety = g->build_mode != BuildModeFastRelease && !fn_table_entry->def_scope->safety_off; + bool want_fn_safety = g->build_mode != BuildModeFastRelease && + g->build_mode != BuildModeSmallRelease && + !fn_table_entry->def_scope->safety_off; if (want_fn_safety) { if (g->libc_link_lib != nullptr) { addLLVMFnAttr(fn_table_entry->llvm_value, "sspstrong"); @@ -817,7 +819,7 @@ static bool ir_want_fast_math(CodeGen *g, IrInstruction *instruction) { } static bool ir_want_runtime_safety(CodeGen *g, IrInstruction *instruction) { - if (g->build_mode == BuildModeFastRelease) + if (g->build_mode == BuildModeFastRelease || g->build_mode == BuildModeSmallRelease) return false; // TODO memoize @@ -5747,10 +5749,12 @@ static void do_code_gen(CodeGen *g) { os_path_join(g->cache_dir, o_basename, output_path); ensure_cache_dir(g); + bool is_small = g->build_mode == BuildModeSmallRelease; + switch (g->emit_file_type) { case EmitFileTypeBinary: if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path), - ZigLLVM_EmitBinary, &err_msg, g->build_mode == BuildModeDebug)) + ZigLLVM_EmitBinary, &err_msg, g->build_mode == BuildModeDebug, is_small)) { zig_panic("unable to write object file %s: %s", buf_ptr(output_path), err_msg); } @@ -5760,7 +5764,7 @@ static void do_code_gen(CodeGen *g) { case EmitFileTypeAssembly: if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path), - ZigLLVM_EmitAssembly, &err_msg, g->build_mode == BuildModeDebug)) + ZigLLVM_EmitAssembly, &err_msg, g->build_mode == BuildModeDebug, is_small)) { zig_panic("unable to write assembly file %s: %s", buf_ptr(output_path), err_msg); } @@ -5769,7 +5773,7 @@ static void do_code_gen(CodeGen *g) { case EmitFileTypeLLVMIr: if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path), - ZigLLVM_EmitLLVMIr, &err_msg, g->build_mode == BuildModeDebug)) + ZigLLVM_EmitLLVMIr, &err_msg, g->build_mode == BuildModeDebug, is_small)) { zig_panic("unable to write llvm-ir file %s: %s", buf_ptr(output_path), err_msg); } @@ -6160,6 +6164,7 @@ static const char *build_mode_to_str(BuildMode build_mode) { case BuildModeDebug: return "Mode.Debug"; case BuildModeSafeRelease: return "Mode.ReleaseSafe"; case BuildModeFastRelease: return "Mode.ReleaseFast"; + case BuildModeSmallRelease: return "Mode.ReleaseSmall"; } zig_unreachable(); } @@ -6300,6 +6305,7 @@ static void define_builtin_compile_vars(CodeGen *g) { " Debug,\n" " ReleaseSafe,\n" " ReleaseFast,\n" + " ReleaseSmall,\n" "};\n\n"); } { @@ -6471,7 +6477,7 @@ static void init(CodeGen *g) { } } - g->have_err_ret_tracing = g->build_mode != BuildModeFastRelease; + g->have_err_ret_tracing = g->build_mode != BuildModeFastRelease && g->build_mode != BuildModeSmallRelease; define_builtin_fns(g); define_builtin_compile_vars(g); diff --git a/src/main.cpp b/src/main.cpp index 35c7462f4..3398fd1de 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -43,6 +43,7 @@ static int usage(const char *arg0) { " --pkg-end pop current pkg\n" " --release-fast build with optimizations on and safety off\n" " --release-safe build with optimizations on and safety on\n" + " --release-small build with size optimizations on and safety off\n" " --static output will be statically linked\n" " --strip exclude debug symbols\n" " --target-arch [name] specify target architecture\n" @@ -482,6 +483,8 @@ int main(int argc, char **argv) { build_mode = BuildModeFastRelease; } else if (strcmp(arg, "--release-safe") == 0) { build_mode = BuildModeSafeRelease; + } else if (strcmp(arg, "--release-small") == 0) { + build_mode = BuildModeSmallRelease; } else if (strcmp(arg, "--strip") == 0) { strip = true; } else if (strcmp(arg, "--static") == 0) { diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index b4eef13cc..ef0e9f24a 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -81,7 +81,7 @@ static const bool assertions_on = false; #endif bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref, - const char *filename, ZigLLVM_EmitOutputType output_type, char **error_message, bool is_debug) + const char *filename, ZigLLVM_EmitOutputType output_type, char **error_message, bool is_debug, bool is_small) { std::error_code EC; raw_fd_ostream dest(filename, EC, sys::fs::F_None); @@ -100,7 +100,7 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM return true; } PMBuilder->OptLevel = target_machine->getOptLevel(); - PMBuilder->SizeLevel = 0; + PMBuilder->SizeLevel = is_small ? 1 : 0; PMBuilder->DisableTailCalls = is_debug; PMBuilder->DisableUnitAtATime = is_debug; diff --git a/src/zig_llvm.h b/src/zig_llvm.h index d6809000c..0d267b101 100644 --- a/src/zig_llvm.h +++ b/src/zig_llvm.h @@ -52,7 +52,7 @@ enum ZigLLVM_EmitOutputType { }; ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref, - const char *filename, enum ZigLLVM_EmitOutputType output_type, char **error_message, bool is_debug); + const char *filename, enum ZigLLVM_EmitOutputType output_type, char **error_message, bool is_debug, bool is_small); ZIG_EXTERN_C LLVMTypeRef ZigLLVMTokenTypeInContext(LLVMContextRef context_ref); diff --git a/std/build.zig b/std/build.zig index a4d745e45..a312b28a6 100644 --- a/std/build.zig +++ b/std/build.zig @@ -426,15 +426,18 @@ pub const Builder = struct { const release_safe = self.option(bool, "release-safe", "optimizations on and safety on") ?? false; const release_fast = self.option(bool, "release-fast", "optimizations on and safety off") ?? false; + const release_small = self.option(bool, "release-small", "size optimizations on and safety off") ?? false; - const mode = if (release_safe and !release_fast) + const mode = if (release_safe and !release_fast and !release_small) builtin.Mode.ReleaseSafe - else if (release_fast and !release_safe) + else if (release_fast and !release_safe and !release_small) builtin.Mode.ReleaseFast - else if (!release_fast and !release_safe) + else if (release_small and !release_fast and !release_safe) + builtin.Mode.ReleaseSmall + else if (!release_fast and !release_safe and !release_small) builtin.Mode.Debug else x: { - warn("Both -Drelease-safe and -Drelease-fast specified"); + warn("Multiple release modes (of -Drelease-safe, -Drelease-fast and -Drelease-small)"); self.markInvalidUserInput(); break :x builtin.Mode.Debug; }; @@ -1229,6 +1232,7 @@ pub const LibExeObjStep = struct { builtin.Mode.Debug => {}, builtin.Mode.ReleaseSafe => zig_args.append("--release-safe") catch unreachable, builtin.Mode.ReleaseFast => zig_args.append("--release-fast") catch unreachable, + builtin.Mode.ReleaseSmall => zig_args.append("--release-small") catch unreachable, } zig_args.append("--cache-dir") catch unreachable; @@ -1369,7 +1373,7 @@ pub const LibExeObjStep = struct { args.append("ssp-buffer-size=4") catch unreachable; } }, - builtin.Mode.ReleaseFast => { + builtin.Mode.ReleaseFast, builtin.Mode.ReleaseSmall => { args.append("-O2") catch unreachable; args.append("-fno-stack-protector") catch unreachable; }, @@ -1706,6 +1710,7 @@ pub const TestStep = struct { builtin.Mode.Debug => {}, builtin.Mode.ReleaseSafe => try zig_args.append("--release-safe"), builtin.Mode.ReleaseFast => try zig_args.append("--release-fast"), + builtin.Mode.ReleaseSmall => try zig_args.append("--release-small"), } switch (self.target) { diff --git a/std/special/builtin.zig b/std/special/builtin.zig index 56aa2ebaf..a5126bc4f 100644 --- a/std/special/builtin.zig +++ b/std/special/builtin.zig @@ -54,7 +54,9 @@ export fn memmove(dest: ?&u8, src: ?&const u8, n: usize) ?&u8 { } comptime { - if (builtin.mode != builtin.Mode.ReleaseFast and builtin.os != builtin.Os.windows) { + if (builtin.mode != builtin.Mode.ReleaseFast and + builtin.mode != builtin.Mode.ReleaseSmall and + builtin.os != builtin.Os.windows) { @export("__stack_chk_fail", __stack_chk_fail, builtin.GlobalLinkage.Strong); } if (builtin.os == builtin.Os.linux and builtin.arch == builtin.Arch.x86_64) { From 1c85050dad6a7e1d486606205ca2eb2cd7028ef5 Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Mon, 16 Apr 2018 03:54:40 +0300 Subject: [PATCH 2/4] Set SizeLevel to 2 in ReleaseSmall mode --- src/zig_llvm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index ef0e9f24a..a56378ab3 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -100,7 +100,7 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM return true; } PMBuilder->OptLevel = target_machine->getOptLevel(); - PMBuilder->SizeLevel = is_small ? 1 : 0; + PMBuilder->SizeLevel = is_small ? 2 : 0; PMBuilder->DisableTailCalls = is_debug; PMBuilder->DisableUnitAtATime = is_debug; From 6492763befb40e65be3fca2bbb2c093997935746 Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Mon, 16 Apr 2018 04:06:00 +0300 Subject: [PATCH 3/4] Fixed test build code --- test/tests.zig | 1 + 1 file changed, 1 insertion(+) diff --git a/test/tests.zig b/test/tests.zig index 19a4f82b7..c3c7bf9d4 100644 --- a/test/tests.zig +++ b/test/tests.zig @@ -583,6 +583,7 @@ pub const CompileErrorContext = struct { Mode.Debug => {}, Mode.ReleaseSafe => zig_args.append("--release-safe") catch unreachable, Mode.ReleaseFast => zig_args.append("--release-fast") catch unreachable, + Mode.ReleaseSmall => zig_args.append("--release-small") catch unreachable, } warn("Test {}/{} {}...", self.test_index+1, self.context.test_index, self.name); From 1bc140964fb394819908d267561103b6c7e5036c Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Mon, 16 Apr 2018 04:18:52 +0300 Subject: [PATCH 4/4] Added ReleaseSmall mode to docgen --- doc/docgen.zig | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/doc/docgen.zig b/doc/docgen.zig index 56d9a0441..bd9dc6c14 100644 --- a/doc/docgen.zig +++ b/doc/docgen.zig @@ -749,6 +749,10 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: var try build_args.append("--release-fast"); try out.print(" --release-fast"); }, + builtin.Mode.ReleaseSmall => { + try build_args.append("--release-small"); + try out.print(" --release-small"); + }, } for (code.link_objects) |link_object| { const name_with_ext = try std.fmt.allocPrint(allocator, "{}{}", link_object, obj_ext); @@ -810,6 +814,10 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: var try test_args.append("--release-fast"); try out.print(" --release-fast"); }, + builtin.Mode.ReleaseSmall => { + try test_args.append("--release-small"); + try out.print(" --release-small"); + }, } if (code.target_windows) { try test_args.appendSlice([][]const u8{ @@ -840,6 +848,10 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: var try test_args.append("--release-fast"); try out.print(" --release-fast"); }, + builtin.Mode.ReleaseSmall => { + try test_args.append("--release-small"); + try out.print(" --release-small"); + }, } const result = try os.ChildProcess.exec(allocator, test_args.toSliceConst(), null, null, max_doc_file_size); switch (result.term) { @@ -874,6 +886,7 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: var builtin.Mode.Debug => {}, builtin.Mode.ReleaseSafe => try test_args.append("--release-safe"), builtin.Mode.ReleaseFast => try test_args.append("--release-fast"), + builtin.Mode.ReleaseSmall => try test_args.append("--release-small"), } const result = try os.ChildProcess.exec(allocator, test_args.toSliceConst(), null, null, max_doc_file_size); @@ -927,6 +940,12 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: var try out.print(" --release-fast"); } }, + builtin.Mode.ReleaseSmall => { + try build_args.append("--release-small"); + if (!code.is_inline) { + try out.print(" --release-small"); + } + }, } if (maybe_error_match) |error_match| {