reducer.h 4.6 KB

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