authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-01-11 22:01:16-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-01-11 22:07:21-07:00
log5b2a79848ced20db80f3f4ce46b3ef7f4a051d53
treedfdd8caf259e2d03ba89d4c0211d9cafb45c6064
parent8932c2d7456fc86b9e92c7976cedcce798caef1a

stage2: cleanups regarding red zone CLI flags

* CLI: change to -mred-zone and -mno-red-zone to match gcc/clang. * build.zig: remove the double negative and make it an optional bool. This follows precedent from other flags, allowing the compiler CLI to be the decider of what is default instead of duplicating the default value into the build system code. * Compilation: make it an optional `want_red_zone` instead of a `no_red_zone` bool. The default is decided by a call to `target_util.hasRedZone`. * When creating a Clang command line, put -mred-zone on the command line if we are forcing it to be enabled. * Update update_clang_options.zig with respect to the recent {s}/{} format changes. * `zig cc` integration with red zone preference.

16 files changed, 114 insertions(+), 62 deletions(-)

lib/std/build.zig+8-3
......@@ -1262,7 +1262,6 @@ pub const LibExeObjStep = struct {
12621262 disable_stack_probing: bool,
12631263 disable_sanitize_c: bool,
12641264 sanitize_thread: bool,
1265 no_red_zone: bool = false,
12661265 rdynamic: bool,
12671266 c_std: Builder.CStd,
12681267 override_lib_dir: ?[]const u8,
......@@ -1333,6 +1332,8 @@ pub const LibExeObjStep = struct {
13331332 /// Position Independent Executable
13341333 pie: ?bool = null,
13351334
1335 red_zone: ?bool = null,
1336
13361337 subsystem: ?builtin.SubSystem = null,
13371338
13381339 /// Overrides the default stack size
......@@ -2261,8 +2262,12 @@ pub const LibExeObjStep = struct {
22612262 if (self.disable_stack_probing) {
22622263 try zig_args.append("-fno-stack-check");
22632264 }
2264 if (self.no_red_zone) {
2265 try zig_args.append("-fno-red-zone");
2265 if (self.red_zone) |red_zone| {
2266 if (red_zone) {
2267 try zig_args.append("-mred-zone");
2268 } else {
2269 try zig_args.append("-mno-red-zone");
2270 }
22662271 }
22672272 if (self.disable_sanitize_c) {
22682273 try zig_args.append("-fno-sanitize-c");
src/Compilation.zig+12-9
......@@ -392,7 +392,7 @@ pub const InitOptions = struct {
392392 want_pie: ?bool = null,
393393 want_sanitize_c: ?bool = null,
394394 want_stack_check: ?bool = null,
395 no_red_zone: bool = false,
395 want_red_zone: ?bool = null,
396396 want_valgrind: ?bool = null,
397397 want_tsan: ?bool = null,
398398 want_compiler_rt: ?bool = null,
......@@ -744,6 +744,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
744744 } else null;
745745
746746 const strip = options.strip or !target_util.hasDebugInfo(options.target);
747 const red_zone = options.want_red_zone orelse target_util.hasRedZone(options.target);
747748
748749 // We put everything into the cache hash that *cannot be modified during an incremental update*.
749750 // For example, one cannot change the target between updates, but one can change source files,
......@@ -774,7 +775,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
774775 cache.hash.add(pie);
775776 cache.hash.add(tsan);
776777 cache.hash.add(stack_check);
777 cache.hash.add(options.no_red_zone);
778 cache.hash.add(red_zone);
778779 cache.hash.add(link_mode);
779780 cache.hash.add(options.function_sections);
780781 cache.hash.add(strip);
......@@ -984,7 +985,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
984985 .valgrind = valgrind,
985986 .tsan = tsan,
986987 .stack_check = stack_check,
987 .no_red_zone = options.no_red_zone,
988 .red_zone = red_zone,
988989 .single_threaded = single_threaded,
989990 .verbose_link = options.verbose_link,
990991 .machine_code_model = options.machine_code_model,
......@@ -2258,11 +2259,13 @@ pub fn addCCArgs(
22582259 } else if (!comp.sanitize_c and comp.bin_file.options.tsan) {
22592260 try argv.append("-fsanitize=thread");
22602261 }
2261
2262 if (comp.bin_file.options.no_red_zone) {
2262
2263 if (comp.bin_file.options.red_zone) {
2264 try argv.append("-mred-zone");
2265 } else if (target_util.hasRedZone(target)) {
22632266 try argv.append("-mno-red-zone");
22642267 }
2265
2268
22662269 switch (comp.bin_file.options.optimize_mode) {
22672270 .Debug => {
22682271 // windows c runtime requires -D_DEBUG if using debug libraries
......@@ -2967,7 +2970,7 @@ fn buildOutputFromZig(
29672970 .function_sections = true,
29682971 .want_sanitize_c = false,
29692972 .want_stack_check = false,
2970 .no_red_zone = comp.bin_file.options.no_red_zone,
2973 .want_red_zone = comp.bin_file.options.red_zone,
29712974 .want_valgrind = false,
29722975 .want_tsan = false,
29732976 .want_pic = comp.bin_file.options.pic,
......@@ -3206,7 +3209,7 @@ fn updateStage1Module(comp: *Compilation, main_progress_node: *std.Progress.Node
32063209 .tsan_enabled = comp.bin_file.options.tsan,
32073210 .function_sections = comp.bin_file.options.function_sections,
32083211 .enable_stack_probing = comp.bin_file.options.stack_check,
3209 .no_red_zone = comp.bin_file.options.no_red_zone,
3212 .red_zone = comp.bin_file.options.red_zone,
32103213 .enable_time_report = comp.time_report,
32113214 .enable_stack_report = comp.stack_report,
32123215 .test_is_evented = comp.test_evented_io,
......@@ -3351,7 +3354,7 @@ pub fn build_crt_file(
33513354 .optimize_mode = comp.compilerRtOptMode(),
33523355 .want_sanitize_c = false,
33533356 .want_stack_check = false,
3354 .no_red_zone = comp.bin_file.options.no_red_zone,
3357 .want_red_zone = comp.bin_file.options.red_zone,
33553358 .want_valgrind = false,
33563359 .want_tsan = false,
33573360 .want_pic = comp.bin_file.options.pic,
src/clang_options_data.zig+16-2
......@@ -3803,7 +3803,14 @@ flagpd1("mno-qpx"),
38033803flagpd1("mno-rdpid"),
38043804flagpd1("mno-rdrnd"),
38053805flagpd1("mno-rdseed"),
3806flagpd1("mno-red-zone"),
3806.{
3807 .name = "mno-red-zone",
3808 .syntax = .flag,
3809 .zig_equivalent = .no_red_zone,
3810 .pd1 = true,
3811 .pd2 = false,
3812 .psl = false,
3813},
38073814flagpd1("mno-reference-types"),
38083815flagpd1("mno-relax"),
38093816flagpd1("mno-relax-all"),
......@@ -3901,7 +3908,14 @@ flagpd1("mrdseed"),
39013908flagpd1("mreassociate"),
39023909flagpd1("mrecip"),
39033910flagpd1("mrecord-mcount"),
3904flagpd1("mred-zone"),
3911.{
3912 .name = "mred-zone",
3913 .syntax = .flag,
3914 .zig_equivalent = .red_zone,
3915 .pd1 = true,
3916 .pd2 = false,
3917 .psl = false,
3918},
39053919flagpd1("mreference-types"),
39063920sepd1("mregparm"),
39073921flagpd1("mrelax"),
src/glibc.zig+1-1
......@@ -934,7 +934,7 @@ fn buildSharedLib(
934934 .optimize_mode = comp.compilerRtOptMode(),
935935 .want_sanitize_c = false,
936936 .want_stack_check = false,
937 .no_red_zone = comp.bin_file.options.no_red_zone,
937 .want_red_zone = comp.bin_file.options.red_zone,
938938 .want_valgrind = false,
939939 .want_tsan = false,
940940 .emit_h = null,
src/libcxx.zig+2-2
......@@ -167,7 +167,7 @@ pub fn buildLibCXX(comp: *Compilation) !void {
167167 .link_mode = link_mode,
168168 .want_sanitize_c = false,
169169 .want_stack_check = false,
170 .no_red_zone = comp.bin_file.options.no_red_zone,
170 .want_red_zone = comp.bin_file.options.red_zone,
171171 .want_valgrind = false,
172172 .want_tsan = comp.bin_file.options.tsan,
173173 .want_pic = comp.bin_file.options.pic,
......@@ -285,7 +285,7 @@ pub fn buildLibCXXABI(comp: *Compilation) !void {
285285 .link_mode = link_mode,
286286 .want_sanitize_c = false,
287287 .want_stack_check = false,
288 .no_red_zone = comp.bin_file.options.no_red_zone,
288 .want_red_zone = comp.bin_file.options.red_zone,
289289 .want_valgrind = false,
290290 .want_tsan = comp.bin_file.options.tsan,
291291 .want_pic = comp.bin_file.options.pic,
src/libunwind.zig+1-1
......@@ -108,7 +108,7 @@ pub fn buildStaticLib(comp: *Compilation) !void {
108108 .link_mode = link_mode,
109109 .want_sanitize_c = false,
110110 .want_stack_check = false,
111 .no_red_zone = comp.bin_file.options.no_red_zone,
111 .want_red_zone = comp.bin_file.options.red_zone,
112112 .want_valgrind = false,
113113 .want_tsan = false,
114114 .want_pic = comp.bin_file.options.pic,
src/link.zig+1-1
......@@ -77,7 +77,7 @@ pub const Options = struct {
7777 valgrind: bool,
7878 tsan: bool,
7979 stack_check: bool,
80 no_red_zone: bool,
80 red_zone: bool,
8181 single_threaded: bool,
8282 verbose_link: bool,
8383 dll_export_fns: bool,
src/main.zig+12-8
......@@ -267,6 +267,8 @@ const usage_build_generic =
267267 \\ -mcmodel=[default|tiny| Limit range of code and data virtual addresses
268268 \\ small|kernel|
269269 \\ medium|large]
270 \\ -mred-zone Force-enable the "red-zone"
271 \\ -mno-red-zone Force-disable the "red-zone"
270272 \\ --name [name] Override root name (not a file path)
271273 \\ -O [mode] Choose what to optimize for
272274 \\ Debug (default) Optimizations off, safety on
......@@ -282,8 +284,6 @@ const usage_build_generic =
282284 \\ -fno-PIE Force-disable Position Independent Executable
283285 \\ -fstack-check Enable stack probing in unsafe builds
284286 \\ -fno-stack-check Disable stack probing in safe builds
285 \\ -fred-zone Enable the "red-zone"
286 \\ -fno-red-zone Disable the "red-zone"
287287 \\ -fsanitize-c Enable C undefined behavior detection in unsafe builds
288288 \\ -fno-sanitize-c Disable C undefined behavior detection in safe builds
289289 \\ -fvalgrind Include valgrind client requests in release builds
......@@ -507,7 +507,7 @@ fn buildOutputType(
507507 var want_pie: ?bool = null;
508508 var want_sanitize_c: ?bool = null;
509509 var want_stack_check: ?bool = null;
510 var no_red_zone: bool = false;
510 var want_red_zone: ?bool = null;
511511 var want_valgrind: ?bool = null;
512512 var want_tsan: ?bool = null;
513513 var want_compiler_rt: ?bool = null;
......@@ -846,10 +846,10 @@ fn buildOutputType(
846846 want_stack_check = true;
847847 } else if (mem.eql(u8, arg, "-fno-stack-check")) {
848848 want_stack_check = false;
849 } else if (mem.eql(u8, arg, "-fred-zone")) {
850 no_red_zone = false;
851 } else if (mem.eql(u8, arg, "-fno-red-zone")) {
852 no_red_zone = true;
849 } else if (mem.eql(u8, arg, "-mred-zone")) {
850 want_red_zone = true;
851 } else if (mem.eql(u8, arg, "-mno-red-zone")) {
852 want_red_zone = false;
853853 } else if (mem.eql(u8, arg, "-fsanitize-c")) {
854854 want_sanitize_c = true;
855855 } else if (mem.eql(u8, arg, "-fno-sanitize-c")) {
......@@ -1075,6 +1075,8 @@ fn buildOutputType(
10751075 .no_pic => want_pic = false,
10761076 .pie => want_pie = true,
10771077 .no_pie => want_pie = false,
1078 .red_zone => want_red_zone = true,
1079 .no_red_zone => want_red_zone = false,
10781080 .nostdlib => ensure_libc_on_non_freestanding = false,
10791081 .nostdlib_cpp => ensure_libcpp_on_non_freestanding = false,
10801082 .shared => {
......@@ -1767,7 +1769,7 @@ fn buildOutputType(
17671769 .want_pie = want_pie,
17681770 .want_sanitize_c = want_sanitize_c,
17691771 .want_stack_check = want_stack_check,
1770 .no_red_zone = no_red_zone,
1772 .want_red_zone = want_red_zone,
17711773 .want_valgrind = want_valgrind,
17721774 .want_tsan = want_tsan,
17731775 .want_compiler_rt = want_compiler_rt,
......@@ -2977,6 +2979,8 @@ pub const ClangArgIterator = struct {
29772979 framework_dir,
29782980 framework,
29792981 nostdlibinc,
2982 red_zone,
2983 no_red_zone,
29802984 };
29812985
29822986 const Args = struct {
src/musl.zig+1-1
......@@ -206,7 +206,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
206206 .optimize_mode = comp.compilerRtOptMode(),
207207 .want_sanitize_c = false,
208208 .want_stack_check = false,
209 .no_red_zone = comp.bin_file.options.no_red_zone,
209 .want_red_zone = comp.bin_file.options.red_zone,
210210 .want_valgrind = false,
211211 .want_tsan = false,
212212 .emit_h = null,
src/stage1.zig+1-1
......@@ -119,7 +119,7 @@ pub const Module = extern struct {
119119 tsan_enabled: bool,
120120 function_sections: bool,
121121 enable_stack_probing: bool,
122 no_red_zone: bool,
122 red_zone: bool,
123123 enable_time_report: bool,
124124 enable_stack_report: bool,
125125 test_is_evented: bool,
src/stage1/all_types.hpp+1-1
......@@ -2195,7 +2195,7 @@ struct CodeGen {
21952195 bool link_mode_dynamic;
21962196 bool dll_export_fns;
21972197 bool have_stack_probing;
2198 bool no_red_zone;
2198 bool red_zone;
21992199 bool function_sections;
22002200 bool test_is_evented;
22012201 bool valgrind_enabled;
src/stage1/codegen.cpp+2-2
......@@ -513,8 +513,8 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) {
513513 } else {
514514 maybe_import_dll(g, llvm_fn, linkage);
515515 }
516
517 if (g->no_red_zone) {
516
517 if (!g->red_zone) {
518518 addLLVMFnAttr(llvm_fn, "noredzone");
519519 }
520520
src/stage1/stage1.cpp+1-1
......@@ -91,7 +91,7 @@ void zig_stage1_build_object(struct ZigStage1 *stage1) {
9191 g->have_pic = stage1->pic;
9292 g->have_pie = stage1->pie;
9393 g->have_stack_probing = stage1->enable_stack_probing;
94 g->no_red_zone = stage1->no_red_zone;
94 g->red_zone = stage1->red_zone;
9595 g->is_single_threaded = stage1->is_single_threaded;
9696 g->valgrind_enabled = stage1->valgrind_enabled;
9797 g->tsan_enabled = stage1->tsan_enabled;
src/stage1/stage1.h+1-1
......@@ -188,7 +188,7 @@ struct ZigStage1 {
188188 bool tsan_enabled;
189189 bool function_sections;
190190 bool enable_stack_probing;
191 bool no_red_zone;
191 bool red_zone;
192192 bool enable_time_report;
193193 bool enable_stack_report;
194194 bool test_is_evented;
src/target.zig+18
......@@ -349,3 +349,21 @@ pub fn defaultCompilerRtOptimizeMode(target: std.Target) std.builtin.Mode {
349349 return .ReleaseFast;
350350 }
351351}
352
353pub fn hasRedZone(target: std.Target) bool {
354 return switch (target.cpu.arch) {
355 .x86_64,
356 .i386,
357 .wasm32,
358 .wasm64,
359 .powerpc,
360 .powerpc64,
361 .powerpc64le,
362 .aarch64,
363 .aarch64_be,
364 .aarch64_32,
365 => true,
366
367 else => false,
368 };
369}
tools/update_clang_options.zig+36-28
......@@ -248,6 +248,14 @@ const known_options = [_]KnownOpt{
248248 .name = "mtune",
249249 .ident = "mcpu",
250250 },
251 .{
252 .name = "mred-zone",
253 .ident = "red_zone",
254 },
255 .{
256 .name = "mno-red-zone",
257 .ident = "no_red_zone",
258 },
251259 .{
252260 .name = "MD",
253261 .ident = "dep_file",
......@@ -340,9 +348,9 @@ pub fn main() anyerror!void {
340348 const child_args = [_][]const u8{
341349 llvm_tblgen_exe,
342350 "--dump-json",
343 try std.fmt.allocPrint(allocator, "{}/clang/include/clang/Driver/Options.td", .{llvm_src_root}),
344 try std.fmt.allocPrint(allocator, "-I={}/llvm/include", .{llvm_src_root}),
345 try std.fmt.allocPrint(allocator, "-I={}/clang/include/clang/Driver", .{llvm_src_root}),
351 try std.fmt.allocPrint(allocator, "{s}/clang/include/clang/Driver/Options.td", .{llvm_src_root}),
352 try std.fmt.allocPrint(allocator, "-I={s}/llvm/include", .{llvm_src_root}),
353 try std.fmt.allocPrint(allocator, "-I={s}/clang/include/clang/Driver", .{llvm_src_root}),
346354 };
347355
348356 const child_result = try std.ChildProcess.exec(.{
......@@ -351,11 +359,11 @@ pub fn main() anyerror!void {
351359 .max_output_bytes = 100 * 1024 * 1024,
352360 });
353361
354 std.debug.warn("{}\n", .{child_result.stderr});
362 std.debug.warn("{s}\n", .{child_result.stderr});
355363
356364 const json_text = switch (child_result.term) {
357365 .Exited => |code| if (code == 0) child_result.stdout else {
358 std.debug.warn("llvm-tblgen exited with code {}\n", .{code});
366 std.debug.warn("llvm-tblgen exited with code {d}\n", .{code});
359367 std.process.exit(1);
360368 },
361369 else => {
......@@ -412,7 +420,7 @@ pub fn main() anyerror!void {
412420 } else if (std.mem.eql(u8, prefix, "/")) {
413421 pslash = true;
414422 } else {
415 std.debug.warn("{} has unrecognized prefix '{}'\n", .{ name, prefix });
423 std.debug.warn("{s} has unrecognized prefix '{s}'\n", .{ name, prefix });
416424 std.process.exit(1);
417425 }
418426 }
......@@ -422,7 +430,7 @@ pub fn main() anyerror!void {
422430 // `-MT foo` is ambiguous because there is also an -MT flag
423431 // The canonical way to specify the flag is with `/MT` and so we make this
424432 // the only way.
425 try stdout.print("flagpsl(\"{}\"),\n", .{name});
433 try stdout.print("flagpsl(\"{s}\"),\n", .{name});
426434 } else if (knownOption(name)) |ident| {
427435
428436 // Workaround the fact that in 'Options.td' -Ofast is listed as 'joined'
......@@ -430,34 +438,34 @@ pub fn main() anyerror!void {
430438
431439 try stdout.print(
432440 \\.{{
433 \\ .name = "{}",
434 \\ .syntax = {},
435 \\ .zig_equivalent = .{},
436 \\ .pd1 = {},
437 \\ .pd2 = {},
438 \\ .psl = {},
441 \\ .name = "{s}",
442 \\ .syntax = {s},
443 \\ .zig_equivalent = .{s},
444 \\ .pd1 = {s},
445 \\ .pd2 = {s},
446 \\ .psl = {s},
439447 \\}},
440448 \\
441449 , .{ name, final_syntax, ident, pd1, pd2, pslash });
442450 } else if (pd1 and !pd2 and !pslash and syntax == .flag) {
443 try stdout.print("flagpd1(\"{}\"),\n", .{name});
451 try stdout.print("flagpd1(\"{s}\"),\n", .{name});
444452 } else if (!pd1 and !pd2 and pslash and syntax == .flag) {
445 try stdout.print("flagpsl(\"{}\"),\n", .{name});
453 try stdout.print("flagpsl(\"{s}\"),\n", .{name});
446454 } else if (pd1 and !pd2 and !pslash and syntax == .joined) {
447 try stdout.print("joinpd1(\"{}\"),\n", .{name});
455 try stdout.print("joinpd1(\"{s}\"),\n", .{name});
448456 } else if (pd1 and !pd2 and !pslash and syntax == .joined_or_separate) {
449 try stdout.print("jspd1(\"{}\"),\n", .{name});
457 try stdout.print("jspd1(\"{s}\"),\n", .{name});
450458 } else if (pd1 and !pd2 and !pslash and syntax == .separate) {
451 try stdout.print("sepd1(\"{}\"),\n", .{name});
459 try stdout.print("sepd1(\"{s}\"),\n", .{name});
452460 } else {
453461 try stdout.print(
454462 \\.{{
455 \\ .name = "{}",
456 \\ .syntax = {},
463 \\ .name = "{s}",
464 \\ .syntax = {s},
457465 \\ .zig_equivalent = .other,
458 \\ .pd1 = {},
459 \\ .pd2 = {},
460 \\ .psl = {},
466 \\ .pd1 = {s},
467 \\ .pd2 = {s},
468 \\ .psl = {s},
461469 \\}},
462470 \\
463471 , .{ name, syntax, pd1, pd2, pslash });
......@@ -506,8 +514,8 @@ const Syntax = union(enum) {
506514 out_stream: anytype,
507515 ) !void {
508516 switch (self) {
509 .multi_arg => |n| return out_stream.print(".{{.{}={}}}", .{ @tagName(self), n }),
510 else => return out_stream.print(".{}", .{@tagName(self)}),
517 .multi_arg => |n| return out_stream.print(".{{.{s}={}}}", .{ @tagName(self), n }),
518 else => return out_stream.print(".{s}", .{@tagName(self)}),
511519 }
512520 }
513521};
......@@ -559,9 +567,9 @@ fn objSyntax(obj: *json.ObjectMap) Syntax {
559567 return .flag;
560568 }
561569 const key = obj.get("!name").?.String;
562 std.debug.warn("{} (key {}) has unrecognized superclasses:\n", .{ name, key });
570 std.debug.warn("{s} (key {s}) has unrecognized superclasses:\n", .{ name, key });
563571 for (obj.get("!superclasses").?.Array.items) |superclass_json| {
564 std.debug.warn(" {}\n", .{superclass_json.String});
572 std.debug.warn(" {s}\n", .{superclass_json.String});
565573 }
566574 std.process.exit(1);
567575}
......@@ -612,7 +620,7 @@ fn objectLessThan(context: void, a: *json.ObjectMap, b: *json.ObjectMap) bool {
612620
613621fn usageAndExit(file: fs.File, arg0: []const u8, code: u8) noreturn {
614622 file.writer().print(
615 \\Usage: {} /path/to/llvm-tblgen /path/to/git/llvm/llvm-project
623 \\Usage: {s} /path/to/llvm-tblgen /path/to/git/llvm/llvm-project
616624 \\Alternative Usage: zig run /path/to/git/zig/tools/update_clang_options.zig -- /path/to/llvm-tblgen /path/to/git/llvm/llvm-project
617625 \\
618626 \\Prints to stdout Zig code which you can use to replace the file src/clang_options_data.zig.