mirror of
https://github.com/openharmony/third_party_spirv-tools.git
synced 2026-07-19 15:13:44 -04:00
Add WebGPU->Vulkan and Vulkan->WebGPU flags in spirv-opt (#2496)
Renames the existing flag '--webgpu-mode' to '--vulkan-to-webgpu' for the Vulkan->WebGPU operation, and adds a new flag '--webgpu-to-vulkan' for the WebGPU->Vulkan operation. Currently '--webgpu-to-vulkan' doesn't have any passes associated with it yet, but further patches will implement them. Fixes #2495
This commit is contained in:
@@ -101,10 +101,15 @@ class Optimizer {
|
||||
// from time to time.
|
||||
Optimizer& RegisterSizePasses();
|
||||
|
||||
// Registers passes that have been prescribed for WebGPU environments.
|
||||
// This sequence of passes is subject to constant review and will change
|
||||
// from time to time.
|
||||
Optimizer& RegisterWebGPUPasses();
|
||||
// Registers passes that have been prescribed for converting from Vulkan to
|
||||
// WebGPU. This sequence of passes is subject to constant review and will
|
||||
// change from time to time.
|
||||
Optimizer& RegisterVulkanToWebGPUPasses();
|
||||
|
||||
// Registers passes that have been prescribed for converting from WebGPU to
|
||||
// Vulkan. This sequence of passes is subject to constant review and will
|
||||
// change from time to time.
|
||||
Optimizer& RegisterWebGPUToVulkanPasses();
|
||||
|
||||
// Registers passes that attempt to legalize the generated code.
|
||||
//
|
||||
|
||||
@@ -220,7 +220,7 @@ Optimizer& Optimizer::RegisterSizePasses() {
|
||||
.RegisterPass(CreateAggressiveDCEPass());
|
||||
}
|
||||
|
||||
Optimizer& Optimizer::RegisterWebGPUPasses() {
|
||||
Optimizer& Optimizer::RegisterVulkanToWebGPUPasses() {
|
||||
return RegisterPass(CreateStripDebugInfoPass())
|
||||
.RegisterPass(CreateStripAtomicCounterMemoryPass())
|
||||
.RegisterPass(CreateGenerateWebGPUInitializersPass())
|
||||
@@ -230,6 +230,8 @@ Optimizer& Optimizer::RegisterWebGPUPasses() {
|
||||
.RegisterPass(CreateDeadBranchElimPass());
|
||||
}
|
||||
|
||||
Optimizer& Optimizer::RegisterWebGPUToVulkanPasses() { return *this; }
|
||||
|
||||
bool Optimizer::RegisterPassesFromFlags(const std::vector<std::string>& flags) {
|
||||
for (const auto& flag : flags) {
|
||||
if (!RegisterPassFromFlag(flag)) {
|
||||
|
||||
@@ -222,9 +222,9 @@ TEST(Optimizer, CanRegisterPassesFromFlags) {
|
||||
EXPECT_EQ(msg_level, SPV_MSG_ERROR);
|
||||
}
|
||||
|
||||
TEST(Optimizer, WebGPUModeSetsCorrectPasses) {
|
||||
TEST(Optimizer, VulkanToWebGPUModeSetsCorrectPasses) {
|
||||
Optimizer opt(SPV_ENV_WEBGPU_0);
|
||||
opt.RegisterWebGPUPasses();
|
||||
opt.RegisterVulkanToWebGPUPasses();
|
||||
std::vector<const char*> pass_names = opt.GetPassNames();
|
||||
|
||||
std::vector<std::string> registered_passes;
|
||||
@@ -246,7 +246,7 @@ TEST(Optimizer, WebGPUModeSetsCorrectPasses) {
|
||||
EXPECT_EQ(registered_passes[i], expected_passes[i]);
|
||||
}
|
||||
|
||||
struct WebGPUPassCase {
|
||||
struct VulkanToWebGPUPassCase {
|
||||
// Input SPIR-V
|
||||
std::string input;
|
||||
// Expected result SPIR-V
|
||||
@@ -255,15 +255,16 @@ struct WebGPUPassCase {
|
||||
std::string pass;
|
||||
};
|
||||
|
||||
using WebGPUPassTest = PassTest<::testing::TestWithParam<WebGPUPassCase>>;
|
||||
using VulkanToWebGPUPassTest =
|
||||
PassTest<::testing::TestWithParam<VulkanToWebGPUPassCase>>;
|
||||
|
||||
TEST_P(WebGPUPassTest, Ran) {
|
||||
TEST_P(VulkanToWebGPUPassTest, Ran) {
|
||||
SpirvTools tools(SPV_ENV_WEBGPU_0);
|
||||
std::vector<uint32_t> binary;
|
||||
tools.Assemble(GetParam().input, &binary);
|
||||
|
||||
Optimizer opt(SPV_ENV_WEBGPU_0);
|
||||
opt.RegisterWebGPUPasses();
|
||||
opt.RegisterVulkanToWebGPUPasses();
|
||||
|
||||
std::vector<uint32_t> optimized;
|
||||
class ValidatorOptions validator_options;
|
||||
@@ -277,8 +278,8 @@ TEST_P(WebGPUPassTest, Ran) {
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
Optimizer, WebGPUPassTest,
|
||||
::testing::ValuesIn(std::vector<WebGPUPassCase>{
|
||||
Optimizer, VulkanToWebGPUPassTest,
|
||||
::testing::ValuesIn(std::vector<VulkanToWebGPUPassCase>{
|
||||
// FlattenDecorations
|
||||
{// input
|
||||
"OpCapability Shader\n"
|
||||
|
||||
+200
-83
@@ -79,9 +79,15 @@ std::string GetSizePasses() {
|
||||
return GetListOfPassesAsString(optimizer);
|
||||
}
|
||||
|
||||
std::string GetWebGPUPasses() {
|
||||
std::string GetVulkanToWebGPUPasses() {
|
||||
spvtools::Optimizer optimizer(SPV_ENV_WEBGPU_0);
|
||||
optimizer.RegisterWebGPUPasses();
|
||||
optimizer.RegisterVulkanToWebGPUPasses();
|
||||
return GetListOfPassesAsString(optimizer);
|
||||
}
|
||||
|
||||
std::string GetWebGPUToVulkanPasses() {
|
||||
spvtools::Optimizer optimizer(SPV_ENV_VULKAN_1_1);
|
||||
optimizer.RegisterWebGPUToVulkanPasses();
|
||||
return GetListOfPassesAsString(optimizer);
|
||||
}
|
||||
|
||||
@@ -99,94 +105,119 @@ standard output.
|
||||
|
||||
NOTE: The optimizer is a work in progress.
|
||||
|
||||
Options (in lexicographical order):
|
||||
Options (in lexicographical order):)",
|
||||
program, program);
|
||||
printf(R"(
|
||||
--ccp
|
||||
Apply the conditional constant propagation transform. This will
|
||||
propagate constant values throughout the program, and simplify
|
||||
expressions and conditional jumps with known predicate
|
||||
values. Performed on entry point call tree functions and
|
||||
exported functions.
|
||||
exported functions.)");
|
||||
printf(R"(
|
||||
--cfg-cleanup
|
||||
Cleanup the control flow graph. This will remove any unnecessary
|
||||
code from the CFG like unreachable code. Performed on entry
|
||||
point call tree functions and exported functions.
|
||||
point call tree functions and exported functions.)");
|
||||
printf(R"(
|
||||
--combine-access-chains
|
||||
Combines chained access chains to produce a single instruction
|
||||
where possible.
|
||||
where possible.)");
|
||||
printf(R"(
|
||||
--compact-ids
|
||||
Remap result ids to a compact range starting from %%1 and without
|
||||
any gaps.
|
||||
any gaps.)");
|
||||
printf(R"(
|
||||
--convert-local-access-chains
|
||||
Convert constant index access chain loads/stores into
|
||||
equivalent load/stores with inserts and extracts. Performed
|
||||
on function scope variables referenced only with load, store,
|
||||
and constant index access chains in entry point call tree
|
||||
functions.
|
||||
functions.)");
|
||||
printf(R"(
|
||||
--copy-propagate-arrays
|
||||
Does propagation of memory references when an array is a copy of
|
||||
another. It will only propagate an array if the source is never
|
||||
written to, and the only store to the target is the copy.
|
||||
written to, and the only store to the target is the copy.)");
|
||||
printf(R"(
|
||||
--eliminate-common-uniform
|
||||
Perform load/load elimination for duplicate uniform values.
|
||||
Converts any constant index access chain uniform loads into
|
||||
its equivalent load and extract. Some loads will be moved
|
||||
to facilitate sharing. Performed only on entry point
|
||||
call tree functions.
|
||||
call tree functions.)");
|
||||
printf(R"(
|
||||
--eliminate-dead-branches
|
||||
Convert conditional branches with constant condition to the
|
||||
indicated unconditional brranch. Delete all resulting dead
|
||||
code. Performed only on entry point call tree functions.
|
||||
code. Performed only on entry point call tree functions.)");
|
||||
printf(R"(
|
||||
--eliminate-dead-code-aggressive
|
||||
Delete instructions which do not contribute to a function's
|
||||
output. Performed only on entry point call tree functions.
|
||||
output. Performed only on entry point call tree functions.)");
|
||||
printf(R"(
|
||||
--eliminate-dead-const
|
||||
Eliminate dead constants.
|
||||
Eliminate dead constants.)");
|
||||
printf(R"(
|
||||
--eliminate-dead-functions
|
||||
Deletes functions that cannot be reached from entry points or
|
||||
exported functions.
|
||||
exported functions.)");
|
||||
printf(R"(
|
||||
--eliminate-dead-inserts
|
||||
Deletes unreferenced inserts into composites, most notably
|
||||
unused stores to vector components, that are not removed by
|
||||
aggressive dead code elimination.
|
||||
aggressive dead code elimination.)");
|
||||
printf(R"(
|
||||
--eliminate-dead-variables
|
||||
Deletes module scope variables that are not referenced.
|
||||
Deletes module scope variables that are not referenced.)");
|
||||
printf(R"(
|
||||
--eliminate-insert-extract
|
||||
DEPRECATED. This pass has been replaced by the simplification
|
||||
pass, and that pass will be run instead.
|
||||
See --simplify-instructions.
|
||||
See --simplify-instructions.)");
|
||||
printf(R"(
|
||||
--eliminate-local-multi-store
|
||||
Replace stores and loads of function scope variables that are
|
||||
stored multiple times. Performed on variables referenceed only
|
||||
with loads and stores. Performed only on entry point call tree
|
||||
functions.
|
||||
functions.)");
|
||||
printf(R"(
|
||||
--eliminate-local-single-block
|
||||
Perform single-block store/load and load/load elimination.
|
||||
Performed only on function scope variables in entry point
|
||||
call tree functions.
|
||||
call tree functions.)");
|
||||
printf(R"(
|
||||
--eliminate-local-single-store
|
||||
Replace stores and loads of function scope variables that are
|
||||
only stored once. Performed on variables referenceed only with
|
||||
loads and stores. Performed only on entry point call tree
|
||||
functions.
|
||||
functions.)");
|
||||
printf(R"(
|
||||
--flatten-decorations
|
||||
Replace decoration groups with repeated OpDecorate and
|
||||
OpMemberDecorate instructions.
|
||||
OpMemberDecorate instructions.)");
|
||||
printf(R"(
|
||||
--fold-spec-const-op-composite
|
||||
Fold the spec constants defined by OpSpecConstantOp or
|
||||
OpSpecConstantComposite instructions to front-end constants
|
||||
when possible.
|
||||
when possible.)");
|
||||
printf(R"(
|
||||
--freeze-spec-const
|
||||
Freeze the values of specialization constants to their default
|
||||
values.
|
||||
values.)");
|
||||
printf(R"(
|
||||
--generate-webgpu-initializers
|
||||
Adds initial values to OpVariable instructions that are missing
|
||||
them, due to their storage type requiring them for WebGPU.
|
||||
them, due to their storage type requiring them for WebGPU.)");
|
||||
printf(R"(
|
||||
--if-conversion
|
||||
Convert if-then-else like assignments into OpSelect.
|
||||
Convert if-then-else like assignments into OpSelect.)");
|
||||
printf(R"(
|
||||
--inline-entry-points-exhaustive
|
||||
Exhaustively inline all function calls in entry point call tree
|
||||
functions. Currently does not inline calls to functions with
|
||||
early return in a loop.
|
||||
early return in a loop.)");
|
||||
printf(R"(
|
||||
--legalize-hlsl
|
||||
Runs a series of optimizations that attempts to take SPIR-V
|
||||
generated by an HLSL front-end and generates legal Vulkan SPIR-V.
|
||||
@@ -194,46 +225,58 @@ Options (in lexicographical order):
|
||||
%s
|
||||
|
||||
Note this does not guarantee legal code. This option passes the
|
||||
option --relax-logical-pointer to the validator.
|
||||
option --relax-logical-pointer to the validator.)",
|
||||
GetLegalizationPasses().c_str());
|
||||
printf(R"(
|
||||
--local-redundancy-elimination
|
||||
Looks for instructions in the same basic block that compute the
|
||||
same value, and deletes the redundant ones.
|
||||
same value, and deletes the redundant ones.)");
|
||||
printf(R"(
|
||||
--loop-fission
|
||||
Splits any top level loops in which the register pressure has
|
||||
exceeded a given threshold. The threshold must follow the use of
|
||||
this flag and must be a positive integer value.
|
||||
this flag and must be a positive integer value.)");
|
||||
printf(R"(
|
||||
--loop-fusion
|
||||
Identifies adjacent loops with the same lower and upper bound.
|
||||
If this is legal, then merge the loops into a single loop.
|
||||
Includes heuristics to ensure it does not increase number of
|
||||
registers too much, while reducing the number of loads from
|
||||
memory. Takes an additional positive integer argument to set
|
||||
the maximum number of registers.
|
||||
the maximum number of registers.)");
|
||||
printf(R"(
|
||||
--loop-invariant-code-motion
|
||||
Identifies code in loops that has the same value for every
|
||||
iteration of the loop, and move it to the loop pre-header.
|
||||
iteration of the loop, and move it to the loop pre-header.)");
|
||||
printf(R"(
|
||||
--loop-unroll
|
||||
Fully unrolls loops marked with the Unroll flag
|
||||
Fully unrolls loops marked with the Unroll flag)");
|
||||
printf(R"(
|
||||
--loop-unroll-partial
|
||||
Partially unrolls loops marked with the Unroll flag. Takes an
|
||||
additional non-0 integer argument to set the unroll factor, or
|
||||
how many times a loop body should be duplicated
|
||||
how many times a loop body should be duplicated)");
|
||||
printf(R"(
|
||||
--loop-peeling
|
||||
Execute few first (respectively last) iterations before
|
||||
(respectively after) the loop if it can elide some branches.
|
||||
(respectively after) the loop if it can elide some branches.)");
|
||||
printf(R"(
|
||||
--loop-peeling-threshold
|
||||
Takes a non-0 integer argument to set the loop peeling code size
|
||||
growth threshold. The threshold prevents the loop peeling
|
||||
from happening if the code size increase created by
|
||||
the optimization is above the threshold.
|
||||
the optimization is above the threshold.)");
|
||||
printf(R"(
|
||||
--max-id-bound=<n>
|
||||
Sets the maximum value for the id bound for the moudle. The
|
||||
default is the minimum value for this limit, 0x3FFFFF. See
|
||||
section 2.17 of the Spir-V specification.
|
||||
section 2.17 of the Spir-V specification.)");
|
||||
printf(R"(
|
||||
--merge-blocks
|
||||
Join two blocks into a single block if the second has the
|
||||
first as its only predecessor. Performed only on entry point
|
||||
call tree functions.
|
||||
call tree functions.)");
|
||||
printf(R"(
|
||||
--merge-return
|
||||
Changes functions that have multiple return statements so they
|
||||
have a single return statement.
|
||||
@@ -247,17 +290,21 @@ Options (in lexicographical order):
|
||||
label and an OpBranch to the header, nothing else.
|
||||
|
||||
These conditions are guaranteed to be met after running
|
||||
dead-branch elimination.
|
||||
dead-branch elimination.)");
|
||||
printf(R"(
|
||||
--loop-unswitch
|
||||
Hoists loop-invariant conditionals out of loops by duplicating
|
||||
the loop on each branch of the conditional and adjusting each
|
||||
copy of the loop.
|
||||
copy of the loop.)");
|
||||
printf(R"(
|
||||
-O
|
||||
Optimize for performance. Apply a sequence of transformations
|
||||
in an attempt to improve the performance of the generated
|
||||
code. For this version of the optimizer, this flag is equivalent
|
||||
to specifying the following optimization code names:
|
||||
%s
|
||||
%s)",
|
||||
GetOptimizationPasses().c_str());
|
||||
printf(R"(
|
||||
-Os
|
||||
Optimize for size. Apply a sequence of transformations in an
|
||||
attempt to minimize the size of the generated code. For this
|
||||
@@ -266,7 +313,9 @@ Options (in lexicographical order):
|
||||
%s
|
||||
|
||||
NOTE: The specific transformations done by -O and -Os change
|
||||
from release to release.
|
||||
from release to release.)",
|
||||
GetSizePasses().c_str());
|
||||
printf(R"(
|
||||
-Oconfig=<file>
|
||||
Apply the sequence of transformations indicated in <file>.
|
||||
This file contains a sequence of strings separated by whitespace
|
||||
@@ -294,109 +343,148 @@ Options (in lexicographical order):
|
||||
that position in the command line. For example, the invocation
|
||||
'spirv-opt --merge-blocks -O ...' applies the transformation
|
||||
--merge-blocks followed by all the transformations implied by
|
||||
-O.
|
||||
-O.)");
|
||||
printf(R"(
|
||||
--print-all
|
||||
Print SPIR-V assembly to standard error output before each pass
|
||||
and after the last pass.
|
||||
and after the last pass.)");
|
||||
printf(R"(
|
||||
--private-to-local
|
||||
Change the scope of private variables that are used in a single
|
||||
function to that function.
|
||||
function to that function.)");
|
||||
printf(R"(
|
||||
--reduce-load-size
|
||||
Replaces loads of composite objects where not every component is
|
||||
used by loads of just the elements that are used.
|
||||
used by loads of just the elements that are used.)");
|
||||
printf(R"(
|
||||
--redundancy-elimination
|
||||
Looks for instructions in the same function that compute the
|
||||
same value, and deletes the redundant ones.
|
||||
same value, and deletes the redundant ones.)");
|
||||
printf(R"(
|
||||
--relax-struct-store
|
||||
Allow store from one struct type to a different type with
|
||||
compatible layout and members. This option is forwarded to the
|
||||
validator.
|
||||
validator.)");
|
||||
printf(R"(
|
||||
--remove-duplicates
|
||||
Removes duplicate types, decorations, capabilities and extension
|
||||
instructions.
|
||||
instructions.)");
|
||||
printf(R"(
|
||||
--replace-invalid-opcode
|
||||
Replaces instructions whose opcode is valid for shader modules,
|
||||
but not for the current shader stage. To have an effect, all
|
||||
entry points must have the same execution model.
|
||||
entry points must have the same execution model.)");
|
||||
printf(R"(
|
||||
--ssa-rewrite
|
||||
Replace loads and stores to function local variables with
|
||||
operations on SSA IDs.
|
||||
operations on SSA IDs.)");
|
||||
printf(R"(
|
||||
--scalar-replacement[=<n>]
|
||||
Replace aggregate function scope variables that are only accessed
|
||||
via their elements with new function variables representing each
|
||||
element. <n> is a limit on the size of the aggragates that will
|
||||
be replaced. 0 means there is no limit. The default value is
|
||||
100.
|
||||
100.)");
|
||||
printf(R"(
|
||||
--set-spec-const-default-value "<spec id>:<default value> ..."
|
||||
Set the default values of the specialization constants with
|
||||
<spec id>:<default value> pairs specified in a double-quoted
|
||||
string. <spec id>:<default value> pairs must be separated by
|
||||
blank spaces, and in each pair, spec id and default value must
|
||||
be separated with colon ':' without any blank spaces in between.
|
||||
e.g.: --set-spec-const-default-value "1:100 2:400"
|
||||
e.g.: --set-spec-const-default-value "1:100 2:400")");
|
||||
printf(R"(
|
||||
--simplify-instructions
|
||||
Will simplify all instructions in the function as much as
|
||||
possible.
|
||||
possible.)");
|
||||
printf(R"(
|
||||
--skip-validation
|
||||
Will not validate the SPIR-V before optimizing. If the SPIR-V
|
||||
is invalid, the optimizer may fail or generate incorrect code.
|
||||
This options should be used rarely, and with caution.
|
||||
This options should be used rarely, and with caution.)");
|
||||
printf(R"(
|
||||
--strength-reduction
|
||||
Replaces instructions with equivalent and less expensive ones.
|
||||
Replaces instructions with equivalent and less expensive ones.)");
|
||||
printf(R"(
|
||||
--strip-atomic-counter-memory
|
||||
Removes AtomicCountMemory bit from memory semantics values.
|
||||
Removes AtomicCountMemory bit from memory semantics values.)");
|
||||
printf(R"(
|
||||
--strip-debug
|
||||
Remove all debug instructions.
|
||||
Remove all debug instructions.)");
|
||||
printf(R"(
|
||||
--strip-reflect
|
||||
Remove all reflection information. For now, this covers
|
||||
reflection information defined by SPV_GOOGLE_hlsl_functionality1.
|
||||
reflection information defined by SPV_GOOGLE_hlsl_functionality1.)");
|
||||
printf(R"(
|
||||
--target-env=<env>
|
||||
Set the target environment. Without this flag the target
|
||||
enviroment defaults to spv1.3.
|
||||
<env> must be one of vulkan1.0, vulkan1.1, opencl2.2, spv1.0,
|
||||
spv1.1, spv1.2, spv1.3, or webgpu0.
|
||||
spv1.1, spv1.2, spv1.3, or webgpu0.)");
|
||||
printf(R"(
|
||||
--time-report
|
||||
Print the resource utilization of each pass (e.g., CPU time,
|
||||
RSS) to standard error output. Currently it supports only Unix
|
||||
systems. This option is the same as -ftime-report in GCC. It
|
||||
prints CPU/WALL/USR/SYS time (and RSS if possible), but note that
|
||||
USR/SYS time are returned by getrusage() and can have a small
|
||||
error.
|
||||
error.)");
|
||||
printf(R"(
|
||||
--upgrade-memory-model
|
||||
Upgrades the Logical GLSL450 memory model to Logical VulkanKHR.
|
||||
Transforms memory, image, atomic and barrier operations to conform
|
||||
to that model's requirements.
|
||||
to that model's requirements.)");
|
||||
printf(R"(
|
||||
--vector-dce
|
||||
This pass looks for components of vectors that are unused, and
|
||||
removes them from the vector. Note this would still leave around
|
||||
lots of dead code that a pass of ADCE will be able to remove.
|
||||
--webgpu-mode
|
||||
Turns on the prescribed passes for WebGPU and sets the target
|
||||
environmet to webgpu0. Other passes may be turned on via
|
||||
additional flags, but such combinations are not tested.
|
||||
lots of dead code that a pass of ADCE will be able to remove.)");
|
||||
printf(R"(
|
||||
--vulkan-to-webgpu
|
||||
Turns on the prescribed passes for converting from Vulkan to
|
||||
WebGPU and sets the target environment to webgpu0. Other passes
|
||||
may be turned on via additional flags, but such combinations are
|
||||
not tested.
|
||||
Using --target-env with this flag is not allowed.
|
||||
|
||||
This flag is the equivalent of passing in --target-env=webgpu0
|
||||
and specifying the following optimization code names:
|
||||
%s
|
||||
|
||||
NOTE: This flag is a WIP and its behaviour is subject to change.
|
||||
NOTE: This flag is a WIP and its behaviour is subject to change.)",
|
||||
GetVulkanToWebGPUPasses().c_str());
|
||||
printf(R"(
|
||||
--webgpu-to-vulkan
|
||||
Turns on the prescribed passes for converting from WebGPU to
|
||||
Vulkan and sets the target environment to vulkan1.1. Other passes
|
||||
may be turned on via additional flags, but such combinations are
|
||||
not tested.
|
||||
Using --target-env with this flag is not allowed.
|
||||
|
||||
This flag is the equivalent of passing in --target-env=vulkan1.1
|
||||
and specifying the following optimization code names:
|
||||
%s
|
||||
|
||||
NOTE: This flag is a WIP and its behaviour is subject to change.)",
|
||||
GetWebGPUToVulkanPasses().c_str());
|
||||
printf(R"(
|
||||
--workaround-1209
|
||||
Rewrites instructions for which there are known driver bugs to
|
||||
avoid triggering those bugs.
|
||||
Current workarounds: Avoid OpUnreachable in loops.
|
||||
Current workarounds: Avoid OpUnreachable in loops.)");
|
||||
printf(R"(
|
||||
--unify-const
|
||||
Remove the duplicated constants.
|
||||
Remove the duplicated constants.)");
|
||||
printf(R"(
|
||||
--validate-after-all
|
||||
Validate the module after each pass is performed.
|
||||
Validate the module after each pass is performed.)");
|
||||
printf(R"(
|
||||
-h, --help
|
||||
Print this help.
|
||||
Print this help.)");
|
||||
printf(R"(
|
||||
--version
|
||||
Display optimizer version information.
|
||||
)",
|
||||
program, program, GetLegalizationPasses().c_str(),
|
||||
GetOptimizationPasses().c_str(), GetSizePasses().c_str(),
|
||||
GetWebGPUPasses().c_str());
|
||||
)");
|
||||
}
|
||||
|
||||
// Reads command-line flags the file specified in |oconfig_flag|. This string
|
||||
@@ -547,7 +635,8 @@ OptStatus ParseFlags(int argc, const char** argv,
|
||||
spvtools::OptimizerOptions* optimizer_options) {
|
||||
std::vector<std::string> pass_flags;
|
||||
bool target_env_set = false;
|
||||
bool webgpu_mode_set = false;
|
||||
bool vulkan_to_webgpu_set = false;
|
||||
bool webgpu_to_vulkan_set = false;
|
||||
for (int argi = 1; argi < argc; ++argi) {
|
||||
const char* cur_arg = argv[argi];
|
||||
if ('-' == cur_arg[0]) {
|
||||
@@ -608,10 +697,16 @@ OptStatus ParseFlags(int argc, const char** argv,
|
||||
max_id_bound);
|
||||
} else if (0 == strncmp(cur_arg,
|
||||
"--target-env=", sizeof("--target-env=") - 1)) {
|
||||
if (webgpu_mode_set) {
|
||||
if (vulkan_to_webgpu_set) {
|
||||
spvtools::Error(opt_diagnostic, nullptr, {},
|
||||
"Cannot use both --webgpu-mode and --target-env at "
|
||||
"the same time");
|
||||
"Cannot use both --vulkan-to-webgpu and --target-env "
|
||||
"at the same time");
|
||||
return {OPT_STOP, 1};
|
||||
}
|
||||
if (webgpu_to_vulkan_set) {
|
||||
spvtools::Error(opt_diagnostic, nullptr, {},
|
||||
"Cannot use both --webgpu-to-vulkan and --target-env "
|
||||
"at the same time");
|
||||
return {OPT_STOP, 1};
|
||||
}
|
||||
const auto split_flag = spvtools::utils::SplitFlagArgs(cur_arg);
|
||||
@@ -623,16 +718,38 @@ OptStatus ParseFlags(int argc, const char** argv,
|
||||
return {OPT_STOP, 1};
|
||||
}
|
||||
optimizer->SetTargetEnv(target_env);
|
||||
} else if (0 == strcmp(cur_arg, "--webgpu-mode")) {
|
||||
} else if (0 == strcmp(cur_arg, "--vulkan-to-webgpu")) {
|
||||
if (target_env_set) {
|
||||
spvtools::Error(opt_diagnostic, nullptr, {},
|
||||
"Cannot use both --webgpu-mode and --target-env at "
|
||||
"the same time");
|
||||
"Cannot use both --vulkan-to-webgpu and --target-env "
|
||||
"at the same time");
|
||||
return {OPT_STOP, 1};
|
||||
}
|
||||
if (webgpu_to_vulkan_set) {
|
||||
spvtools::Error(opt_diagnostic, nullptr, {},
|
||||
"Cannot use both --vulkan-to-webgpu and "
|
||||
"--webgpu-to-vulkan at the same time");
|
||||
return {OPT_STOP, 1};
|
||||
}
|
||||
|
||||
optimizer->SetTargetEnv(SPV_ENV_WEBGPU_0);
|
||||
optimizer->RegisterWebGPUPasses();
|
||||
optimizer->RegisterVulkanToWebGPUPasses();
|
||||
} else if (0 == strcmp(cur_arg, "--webgpu-to-vulkan")) {
|
||||
if (target_env_set) {
|
||||
spvtools::Error(opt_diagnostic, nullptr, {},
|
||||
"Cannot use both --webgpu-to-vulkan and --target-env "
|
||||
"at the same time");
|
||||
return {OPT_STOP, 1};
|
||||
}
|
||||
if (vulkan_to_webgpu_set) {
|
||||
spvtools::Error(opt_diagnostic, nullptr, {},
|
||||
"Cannot use both --webgpu-to-vulkan and "
|
||||
"--vulkan-to-webgpu at the same time");
|
||||
return {OPT_STOP, 1};
|
||||
}
|
||||
|
||||
optimizer->SetTargetEnv(SPV_ENV_VULKAN_1_1);
|
||||
optimizer->RegisterWebGPUToVulkanPasses();
|
||||
} else if (0 == strcmp(cur_arg, "--validate-after-all")) {
|
||||
optimizer->SetValidateAfterAll(true);
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user