Adds a virtual method, GetFreshIds(), to Transformation. Every
transformation uses this to indicate which ids in its protobuf message
are fresh ids. This means that when replaying a sequence of
transformations the replayer can obtain a smallest id that is not in
use by the module already and that will not be used by any
transformation by necessity. Ids greater than or equal to this id
can be used as overflow ids.
Fixes#3851.
Before this change, the replayer would return a SPIR-V binary. This
did not allow further transforming the resulting module: it would need
to be re-parsed, and the transformation context arising from the
replayed transformations was not available. This change makes it so
that after replay an IR context and transformation context are
returned instead; the IR context can subsequently be turned into a
binary if desired.
This change paves the way for an upcoming PR to integrate spirv-reduce
with the spirv-fuzz shrinker.
In preparation for some upcoming work on the shrinker, this PR changes
the interfaces of Fuzzer, Replayer and Shrinker so that all data
relevant to each class is provided on construction, meaning that the
"Run" method can become a zero-argument method that returns a status,
transformed binary and sequence of applied transformations via a
struct.
This makes greater use of fields, so that -- especially in Fuzzer --
there is a lot less parameter passing.
There's no real need for Fuzzer, Replayer and Shrinker to use the
opaque pointer design pattern. This change removes it, paving the way
for making some upcoming changes to Fuzzer easier.
This change adds the notion of "overflow ids", which can be used
during shrinking to facilitate applying transformations that would
otherwise have become inapplicable due to earlier transformations
being removed.
Fixes an issue with the shrinker, where the message consumer set for
the shrinker was not being passed on to the replay object that the
shrinker creates. This meant that messages generated during replay
would cause an exception to be thrown.
To aid in debugging issues in spirv-fuzz, this change adds an option whereby the SPIR-V module is validated after each transformation is applied during replay. This can assist in finding a transformation that erroneously makes the module invalid, so that said transformation can be debugged.
Adds to spirv-fuzz the option to shrink a sequence of transformations
that lead to an interesting binary to be generated, to find a smaller
sub-sequence of transformations that still lead to an interesting (but
hopefully simpler) binary being generated. The notion of what counts
as "interesting" comes from a user-provided script, the
"interestingness function", similar to the way the spirv-reduce tool
works. The shrinking process will give up after a maximum number of
steps, which can be configured on the command line.
Tests for the combination of fuzzing and shrinking are included, using
a variety of interestingness functions.