1 // Copyright (c) 2020 Google LLC
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 #include "source/fuzz/pass_management/repeated_pass_manager_looped_with_recommendations.h"
20 RepeatedPassManagerLoopedWithRecommendations::
21 RepeatedPassManagerLoopedWithRecommendations(
22 FuzzerContext
* fuzzer_context
, RepeatedPassInstances
* pass_instances
,
23 RepeatedPassRecommender
* pass_recommender
)
24 : RepeatedPassManager(fuzzer_context
, pass_instances
),
25 num_transformations_applied_before_last_pass_choice_(0),
27 auto& passes
= GetPassInstances()->GetPasses();
29 FuzzerPass
* current_pass
=
30 passes
[GetFuzzerContext()->RandomIndex(passes
)].get();
31 pass_loop_
.push_back(current_pass
);
32 for (auto future_pass
:
33 pass_recommender
->GetFuturePassRecommendations(*current_pass
)) {
34 recommended_pass_indices_
.insert(
35 static_cast<uint32_t>(pass_loop_
.size()));
36 pass_loop_
.push_back(future_pass
);
38 } while (fuzzer_context
->ChoosePercentage(
39 fuzzer_context
->GetChanceOfAddingAnotherPassToPassLoop()));
42 RepeatedPassManagerLoopedWithRecommendations::
43 ~RepeatedPassManagerLoopedWithRecommendations() = default;
45 FuzzerPass
* RepeatedPassManagerLoopedWithRecommendations::ChoosePass(
46 const protobufs::TransformationSequence
& applied_transformations
) {
47 assert((next_pass_index_
> 0 ||
48 recommended_pass_indices_
.count(next_pass_index_
) == 0) &&
49 "The first pass in the loop should not be a recommendation.");
50 assert(static_cast<uint32_t>(applied_transformations
.transformation_size()) >=
51 num_transformations_applied_before_last_pass_choice_
&&
52 "The number of applied transformations should not decrease.");
53 if (num_transformations_applied_before_last_pass_choice_
==
54 static_cast<uint32_t>(applied_transformations
.transformation_size())) {
55 // The last pass that was applied did not lead to any new transformations.
56 // We thus do not want to apply recommendations based on it, so we skip on
57 // to the next non-recommended pass.
58 while (recommended_pass_indices_
.count(next_pass_index_
)) {
60 (next_pass_index_
+ 1) % static_cast<uint32_t>(pass_loop_
.size());
63 auto result
= pass_loop_
[next_pass_index_
];
65 (next_pass_index_
+ 1) % static_cast<uint32_t>(pass_loop_
.size());
70 } // namespace spvtools