spirv-fuzz: Do not add too many dead blocks (#4217)

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.
This commit is contained in:
Alastair Donaldson 2021-03-27 10:30:23 +00:00 committed by GitHub
parent d0c73fcee1
commit 22eb528f17
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -14,12 +14,20 @@
#include "source/fuzz/fuzzer_pass_add_dead_blocks.h"
#include <algorithm>
#include "source/fuzz/fuzzer_util.h"
#include "source/fuzz/transformation_add_dead_block.h"
namespace spvtools {
namespace fuzz {
namespace {
const size_t kMaxTransformationsInOnePass = 100U;
} // namespace
FuzzerPassAddDeadBlocks::FuzzerPassAddDeadBlocks(
opt::IRContext* ir_context, TransformationContext* transformation_context,
FuzzerContext* fuzzer_context,
@ -55,9 +63,18 @@ void FuzzerPassAddDeadBlocks::Apply() {
GetFuzzerContext()->GetFreshId(), block.id(), condition_value));
}
}
// Apply all those transformations that are in fact applicable.
for (auto& transformation : candidate_transformations) {
MaybeApplyTransformation(transformation);
// Applying transformations can be expensive as each transformation requires
// dominator information and also invalidates dominator information. We thus
// limit the number of transformations that one application of this fuzzer
// pass can apply. We choose to do this after identifying all the
// transformations that we *might* want to apply, rather than breaking the
// above loops once the limit is reached, to avoid biasing towards
// transformations that target early parts of the module.
GetFuzzerContext()->Shuffle(&candidate_transformations);
for (size_t i = 0; i < std::min(kMaxTransformationsInOnePass,
candidate_transformations.size());
i++) {
MaybeApplyTransformation(candidate_transformations[i]);
}
}