| 83 | Shrinker::~Shrinker() = default; |
| 84 | |
| 85 | Shrinker::ShrinkerResult Shrinker::Run() { |
| 86 | // Check compatibility between the library version being linked with and the |
| 87 | // header files being used. |
| 88 | GOOGLE_PROTOBUF_VERIFY_VERSION; |
| 89 | |
| 90 | SpirvTools tools(target_env_); |
| 91 | if (!tools.IsValid()) { |
| 92 | consumer_(SPV_MSG_ERROR, nullptr, {}, |
| 93 | "Failed to create SPIRV-Tools interface; stopping."); |
| 94 | return {Shrinker::ShrinkerResultStatus::kFailedToCreateSpirvToolsInterface, |
| 95 | std::vector<uint32_t>(), protobufs::TransformationSequence()}; |
| 96 | } |
| 97 | |
| 98 | // Initial binary should be valid. |
| 99 | if (!tools.Validate(&binary_in_[0], binary_in_.size(), validator_options_)) { |
| 100 | consumer_(SPV_MSG_INFO, nullptr, {}, |
| 101 | "Initial binary is invalid; stopping."); |
| 102 | return {Shrinker::ShrinkerResultStatus::kInitialBinaryInvalid, |
| 103 | std::vector<uint32_t>(), protobufs::TransformationSequence()}; |
| 104 | } |
| 105 | |
| 106 | // Run a replay of the initial transformation sequence to check that it |
| 107 | // succeeds. |
| 108 | auto initial_replay_result = |
| 109 | Replayer(target_env_, consumer_, binary_in_, initial_facts_, |
| 110 | transformation_sequence_in_, |
| 111 | static_cast<uint32_t>( |
| 112 | transformation_sequence_in_.transformation_size()), |
| 113 | validate_during_replay_, validator_options_) |
| 114 | .Run(); |
| 115 | if (initial_replay_result.status != |
| 116 | Replayer::ReplayerResultStatus::kComplete) { |
| 117 | return {ShrinkerResultStatus::kReplayFailed, std::vector<uint32_t>(), |
| 118 | protobufs::TransformationSequence()}; |
| 119 | } |
| 120 | // Get the binary that results from running these transformations, and the |
| 121 | // subsequence of the initial transformations that actually apply (in |
| 122 | // principle this could be a strict subsequence). |
| 123 | std::vector<uint32_t> current_best_binary; |
| 124 | initial_replay_result.transformed_module->module()->ToBinary( |
| 125 | ¤t_best_binary, false); |
| 126 | protobufs::TransformationSequence current_best_transformations = |
| 127 | std::move(initial_replay_result.applied_transformations); |
| 128 | |
| 129 | // Check that the binary produced by applying the initial transformations is |
| 130 | // indeed interesting. |
| 131 | if (!interestingness_function_(current_best_binary, 0)) { |
| 132 | consumer_(SPV_MSG_INFO, nullptr, {}, |
| 133 | "Initial binary is not interesting; stopping."); |
| 134 | return {ShrinkerResultStatus::kInitialBinaryNotInteresting, |
| 135 | std::vector<uint32_t>(), protobufs::TransformationSequence()}; |
| 136 | } |
| 137 | |
| 138 | uint32_t attempt = 0; // Keeps track of the number of shrink attempts that |
| 139 | // have been tried, whether successful or not. |
| 140 | |
| 141 | uint32_t chunk_size = |
| 142 | std::max(1u, NumRemainingTransformations(current_best_transformations) / |
nothing calls this directly
no test coverage detected