1 // Copyright (c) 2018 Google LLC 2 // 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 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 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. 14 15 #ifndef SOURCE_REDUCE_REDUCER_H_ 16 #define SOURCE_REDUCE_REDUCER_H_ 17 18 #include <functional> 19 #include <string> 20 21 #include "source/reduce/reduction_pass.h" 22 #include "spirv-tools/libspirv.hpp" 23 24 namespace spvtools { 25 namespace reduce { 26 27 // This class manages the process of applying a reduction -- parameterized by a 28 // number of reduction passes and an interestingness test, to a SPIR-V binary. 29 class Reducer { 30 public: 31 // Possible statuses that can result from running a reduction. 32 enum ReductionResultStatus { 33 kInitialStateNotInteresting, 34 kReachedStepLimit, 35 kComplete, 36 kInitialStateInvalid, 37 38 // Returned when the fail-on-validation-error option is set and a 39 // reduction step yields a state that fails validation. 40 kStateInvalid, 41 }; 42 43 // The type for a function that will take a binary and return true if and 44 // only if the binary is deemed interesting. (The function also takes an 45 // integer argument that will be incremented each time the function is 46 // called; this is for debugging purposes). 47 // 48 // The notion of "interesting" depends on what properties of the binary or 49 // tools that process the binary we are trying to maintain during reduction. 50 using InterestingnessFunction = 51 std::function<bool(const std::vector<uint32_t>&, uint32_t)>; 52 53 // Constructs an instance with the given target |target_env|, which is used to 54 // decode the binary to be reduced later. 55 // 56 // The constructed instance will have an empty message consumer, which just 57 // ignores all messages from the library. Use SetMessageConsumer() to supply 58 // one if messages are of concern. 59 // 60 // The constructed instance also needs to have an interestingness function 61 // set and some reduction passes added to it in order to be useful. 62 explicit Reducer(spv_target_env target_env); 63 64 // Disables copy/move constructor/assignment operations. 65 Reducer(const Reducer&) = delete; 66 Reducer(Reducer&&) = delete; 67 Reducer& operator=(const Reducer&) = delete; 68 Reducer& operator=(Reducer&&) = delete; 69 70 // Destructs this instance. 71 ~Reducer(); 72 73 // Sets the message consumer to the given |consumer|. The |consumer| will be 74 // invoked once for each message communicated from the library. 75 void SetMessageConsumer(MessageConsumer consumer); 76 77 // Sets the function that will be used to decide whether a reduced binary 78 // turned out to be interesting. 79 void SetInterestingnessFunction( 80 InterestingnessFunction interestingness_function); 81 82 // Adds all default reduction passes. 83 void AddDefaultReductionPasses(); 84 85 // Adds a reduction pass based on the given finder to the sequence of passes 86 // that will be iterated over. 87 void AddReductionPass(std::unique_ptr<ReductionOpportunityFinder> finder); 88 89 // Adds a cleanup reduction pass based on the given finder to the sequence of 90 // passes that will run after other passes. 91 void AddCleanupReductionPass( 92 std::unique_ptr<ReductionOpportunityFinder> finder); 93 94 // Reduces the given SPIR-V module |binary_out|. 95 // The reduced binary ends up in |binary_out|. 96 // A status is returned. 97 ReductionResultStatus Run(const std::vector<uint32_t>& binary_in, 98 std::vector<uint32_t>* binary_out, 99 spv_const_reducer_options options, 100 spv_validator_options validator_options); 101 102 private: 103 static bool ReachedStepLimit(uint32_t current_step, 104 spv_const_reducer_options options); 105 106 ReductionResultStatus RunPasses( 107 std::vector<std::unique_ptr<ReductionPass>>* passes, 108 spv_const_reducer_options options, 109 spv_validator_options validator_options, const SpirvTools& tools, 110 std::vector<uint32_t>* current_binary, uint32_t* reductions_applied); 111 112 const spv_target_env target_env_; 113 MessageConsumer consumer_; 114 InterestingnessFunction interestingness_function_; 115 std::vector<std::unique_ptr<ReductionPass>> passes_; 116 std::vector<std::unique_ptr<ReductionPass>> cleanup_passes_; 117 }; 118 119 } // namespace reduce 120 } // namespace spvtools 121 122 #endif // SOURCE_REDUCE_REDUCER_H_ 123