Sometimes, you need to change these functions during debugging (e.g.,
figure out why the transformation is inapplicable). When that happens,
you need to recompile the whole fuzzer just because these functions
are in the header file. This PR fixes the situation.
There are some edge cases where adding livesafe functions does not
succeed, due to loop limiter edges breaking SPIR-V dominance rules. As
these edge cases are rare it does not seem worth implementing complex
additional logic to handle all cases. This change accepts that trying
to add a function in a livesafe manner may not succeed.
FuzzerPassConstructComposites is adapted to use AvailableInstructions
to manage available instructions, and to use zero constants when
trying to construct a composite for which not all fields can otherwise
be constructed. The change uncovered some cases where we create
structs and arrays with struct fields or components that are
block-decorated; these possibilities have been eliminated.
It is easy to avoid the need to invalidate the def-use analysis and
instruction to block mapping when splitting blocks, and profiling has
revealed that invalidation of def-use in particular is expensive when
splitting many blocks. This change avoids these invalidations.
Profiling has shown that adding large numbers of dead block
transformations can be expensive because each on requires dominator
analysis information, and each one invalidates this information. There
is currently no obvious mechanism for incrementally updating the
dominator analysis. This change restricts the number of these
transformations that a single fuzzer pass will apply, to restrict this
performance bottleneck.
Types should only be added to the module by spirv-fuzz via
transformations, so this change removes the AddType methods from
fuzzerutil, which were only called once each from the appropriate
transformation.
The transformations have been adapted so that they avoid redundantly
invalidating all analyses - they now update the def-use manager and
invalidate only the type manager.
Avoids redundantly searching the whome module when locating an
instruction from its descriptor - instead, only the block containing
the instruction needs to be searched.
The performance of spirv-fuzz is sometimes poor due to analyses being
conservatively invalidated. This can lead to quadratic time algorithms
when a fuzzer pass applies O(N) transformations, and where every
transformation e.g. depends on def-use analysis and invalidates
def-use analysis (because building def-use analysis is O(N)).
This change avoids invalidating analyses for certain transformations.
The fuzzer library depended on CLIMessageConsumer, due to its explicit
use in a function. This change removes that dependency so that,
instead, a message consumer parameter is passed.
Avoid generating OpPhi on void types, and allow the transformation to
take place on regions that produce pointer and sampled image result
ids if such ids are not used after the region.
Fixes#3787.
Adds some functions that allow a fuzzer pass to check whether it is
spiralling out of control and exit early. The fuzzer pass for adding
bit instruction synonyms now uses this. Also make many methods in
FuzzerContext const.
This PR fixes a bug related to the transformation applicability.
When the OpNot case was implemented, its opcode was not
added to the list of supported bit instructions in IsApplicable.
So, the changes made are the following.
- Add OpNot to the list of supported bit instructions.
- Update the tests.
If enabled the following targets will be created:
* `${SPIRV_TOOLS}-static` - `STATIC` library. Has full public symbol visibility.
* `${SPIRV_TOOLS}-shared` - `SHARED` library. Has default-hidden symbol visibility.
* `${SPIRV_TOOLS}` - will alias to one of above, based on BUILD_SHARED_LIBS.
If disabled the following targets will be created:
* `${SPIRV_TOOLS}` - either `STATIC` or `SHARED` based on the new `SPIRV_TOOLS_LIBRARY_TYPE` flag. Has full public symbol visibility.
* `${SPIRV_TOOLS}-shared` - `SHARED` library. Has default-hidden symbol visibility.
Defaults to `ON`, matching existing build behavior.
This flag can be used by package maintainers to ensure that all libraries are built as shared objects.
The following implementations are introduced:
- Transformation and fuzzer pass for expanding vector reduction.
- Unit tests to cover the instructions with different vector sizes.
Fixes#3768.