Commit b4b1c4df64
Changed files (4)
src
src/codegen/spirv.zig
@@ -99,6 +99,15 @@ pub const Object = struct {
air: Air,
liveness: Liveness,
) !void {
+ const target = mod.getTarget();
+ // We always want a structured control flow in shaders. This option is only relevant
+ // for OpenCL kernels.
+ const want_structured_cfg = switch (target.os.tag) {
+ .opencl => mod.comp.bin_file.options.want_structured_cfg orelse false,
+ else => true,
+ };
+ _ = want_structured_cfg;
+
var decl_gen = DeclGen{
.gpa = self.gpa,
.object = self,
src/Compilation.zig
@@ -1002,6 +1002,8 @@ pub const InitOptions = struct {
/// (Windows) PDB output path
pdb_out_path: ?[]const u8 = null,
error_limit: ?Module.ErrorInt = null,
+ /// (SPIR-V) whether to generate a structured control flow graph or not
+ want_structured_cfg: ?bool = null,
};
fn addModuleTableToCacheHash(
@@ -1447,6 +1449,8 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
};
const formatted_panics = options.formatted_panics orelse (options.optimize_mode == .Debug);
+ const error_limit = options.error_limit orelse (std.math.maxInt(u16) - 1);
+
// We put everything into the cache hash that *cannot be modified
// during an incremental update*. For example, one cannot change the
// target between updates, but one can change source files, so the
@@ -1545,6 +1549,9 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
hash.add(options.skip_linker_dependencies);
hash.add(options.parent_compilation_link_libc);
hash.add(formatted_panics);
+ hash.add(options.emit_h != null);
+ hash.add(error_limit);
+ hash.addOptional(options.want_structured_cfg);
// In the case of incremental cache mode, this `zig_cache_artifact_directory`
// is computed based on a hash of non-linker inputs, and it is where all
@@ -1699,7 +1706,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
.local_zir_cache = local_zir_cache,
.emit_h = emit_h,
.tmp_hack_arena = std.heap.ArenaAllocator.init(gpa),
- .error_limit = options.error_limit orelse (std.math.maxInt(u16) - 1),
+ .error_limit = error_limit,
};
try module.init();
@@ -1958,6 +1965,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
.force_undefined_symbols = options.force_undefined_symbols,
.pdb_source_path = options.pdb_source_path,
.pdb_out_path = options.pdb_out_path,
+ .want_structured_cfg = options.want_structured_cfg,
});
errdefer bin_file.destroy();
comp.* = .{
@@ -2732,6 +2740,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes
man.hash.add(comp.bin_file.options.valgrind);
man.hash.add(comp.bin_file.options.single_threaded);
man.hash.add(comp.bin_file.options.use_llvm);
+ man.hash.add(comp.bin_file.options.use_lib_llvm);
man.hash.add(comp.bin_file.options.dll_export_fns);
man.hash.add(comp.bin_file.options.is_test);
man.hash.add(comp.test_evented_io);
@@ -2739,8 +2748,10 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes
man.hash.addOptionalBytes(comp.test_name_prefix);
man.hash.add(comp.bin_file.options.skip_linker_dependencies);
man.hash.add(comp.bin_file.options.parent_compilation_link_libc);
+ man.hash.add(comp.formatted_panics);
man.hash.add(mod.emit_h != null);
man.hash.add(mod.error_limit);
+ man.hash.addOptional(comp.bin_file.options.want_structured_cfg);
}
try man.addOptionalFile(comp.bin_file.options.linker_script);
@@ -6823,6 +6834,7 @@ fn buildOutputFromZig(
.clang_passthrough_mode = comp.clang_passthrough_mode,
.skip_linker_dependencies = true,
.parent_compilation_link_libc = comp.bin_file.options.link_libc,
+ .want_structured_cfg = comp.bin_file.options.want_structured_cfg,
});
defer sub_compilation.destroy();
@@ -6903,6 +6915,7 @@ pub fn build_crt_file(
.clang_passthrough_mode = comp.clang_passthrough_mode,
.skip_linker_dependencies = true,
.parent_compilation_link_libc = comp.bin_file.options.link_libc,
+ .want_structured_cfg = comp.bin_file.options.want_structured_cfg,
});
defer sub_compilation.destroy();
src/link.zig
@@ -268,6 +268,9 @@ pub const Options = struct {
/// (Windows) .def file to specify when linking
module_definition_file: ?[]const u8 = null,
+ /// (SPIR-V) whether to generate a structured control flow graph or not
+ want_structured_cfg: ?bool = null,
+
pub fn effectiveOutputMode(options: Options) std.builtin.OutputMode {
return if (options.use_lld) .Obj else options.output_mode;
}
src/main.zig
@@ -493,6 +493,8 @@ const usage_build_generic =
\\ msvc Use msvc include paths (must be present on the system)
\\ gnu Use mingw include paths (distributed with Zig)
\\ none Do not use any autodetected include paths
+ \\ -fstructured-cfg (SPIR-V) force SPIR-V kernels to use structured control flow
+ \\ -fno-structured-cfg (SPIR-V) force SPIR-V kernels to not use structured control flow
\\
\\Link Options:
\\ -l[lib], --library [lib] Link against system library (only if actually used)
@@ -913,7 +915,7 @@ fn buildOutputType(
var pdb_out_path: ?[]const u8 = null;
var dwarf_format: ?std.dwarf.Format = null;
var error_limit: ?Module.ErrorInt = null;
-
+ var want_structured_cfg: ?bool = null;
// e.g. -m3dnow or -mno-outline-atomics. They correspond to std.Target llvm cpu feature names.
// This array is populated by zig cc frontend and then has to be converted to zig-style
// CPU features.
@@ -1070,6 +1072,10 @@ fn buildOutputType(
if (mem.eql(u8, next_arg, "--")) break;
try extra_rcflags.append(next_arg);
}
+ } else if (mem.startsWith(u8, arg, "-fstructured-cfg")) {
+ want_structured_cfg = true;
+ } else if (mem.startsWith(u8, arg, "-fno-structured-cfg")) {
+ want_structured_cfg = false;
} else if (mem.eql(u8, arg, "--color")) {
const next_arg = args_iter.next() orelse {
fatal("expected [auto|on|off] after --color", .{});
@@ -3595,6 +3601,7 @@ fn buildOutputType(
.error_tracing = error_tracing,
.pdb_out_path = pdb_out_path,
.error_limit = error_limit,
+ .want_structured_cfg = want_structured_cfg,
}) catch |err| switch (err) {
error.LibCUnavailable => {
const target = target_info.target;