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 "spirv-tools/libspirv.hpp" 22 23 #include "reduction_pass.h" 24 25 namespace spvtools { 26 namespace reduce { 27 28 // This class manages the process of applying a reduction -- parameterized by a 29 // number of reduction passes and an interestingness test, to a SPIR-V binary. 30 class Reducer { 31 public: 32 // Possible statuses that can result from running a reduction. 33 enum ReductionResultStatus { 34 kInitialStateNotInteresting, 35 kReachedStepLimit, 36 kComplete 37 }; 38 39 // The type for a function that will take a binary and return true if and 40 // only if the binary is deemed interesting. (The function also takes an 41 // integer argument that will be incremented each time the function is 42 // called; this is for debugging purposes). 43 // 44 // The notion of "interesting" depends on what properties of the binary or 45 // tools that process the binary we are trying to maintain during reduction. 46 using InterestingnessFunction = 47 std::function<bool(const std::vector<uint32_t>&, uint32_t)>; 48 49 // Constructs an instance with the given target |env|, which is used to 50 // decode the binary to be reduced later. 51 // 52 // The constructed instance will have an empty message consumer, which just 53 // ignores all messages from the library. Use SetMessageConsumer() to supply 54 // one if messages are of concern. 55 // 56 // The constructed instance also needs to have an interestingness function 57 // set and some reduction passes added to it in order to be useful. 58 explicit Reducer(spv_target_env env); 59 60 // Disables copy/move constructor/assignment operations. 61 Reducer(const Reducer&) = delete; 62 Reducer(Reducer&&) = delete; 63 Reducer& operator=(const Reducer&) = delete; 64 Reducer& operator=(Reducer&&) = delete; 65 66 // Destructs this instance. 67 ~Reducer(); 68 69 // Sets the message consumer to the given |consumer|. The |consumer| will be 70 // invoked once for each message communicated from the library. 71 void SetMessageConsumer(MessageConsumer consumer); 72 73 // Sets the function that will be used to decide whether a reduced binary 74 // turned out to be interesting. 75 void SetInterestingnessFunction( 76 InterestingnessFunction interestingness_function); 77 78 // Adds a reduction pass to the sequence of passes that will be iterated 79 // over. 80 void AddReductionPass(std::unique_ptr<ReductionPass>&& reduction_pass); 81 82 // Reduces the given SPIR-V module |binary_out|. 83 // The reduced binary ends up in |binary_out|. 84 // A status is returned. 85 ReductionResultStatus Run(std::vector<uint32_t>&& binary_in, 86 std::vector<uint32_t>* binary_out, 87 spv_const_reducer_options options) const; 88 89 private: 90 struct Impl; // Opaque struct for holding internal data. 91 std::unique_ptr<Impl> impl_; // Unique pointer to internal data. 92 }; 93 94 } // namespace reduce 95 } // namespace spvtools 96 97 #endif // SOURCE_REDUCE_REDUCER_H_ 98