pass_manager.cpp 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. // Copyright (c) 2016 Google Inc.
  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. #include "source/opt/pass_manager.h"
  15. #include <iostream>
  16. #include <string>
  17. #include <vector>
  18. #include "source/opt/ir_context.h"
  19. #include "source/util/timer.h"
  20. #include "spirv-tools/libspirv.hpp"
  21. namespace spvtools {
  22. namespace opt {
  23. Pass::Status PassManager::Run(IRContext* context) {
  24. auto status = Pass::Status::SuccessWithoutChange;
  25. // If print_all_stream_ is not null, prints the disassembly of the module
  26. // to that stream, with the given preamble and optionally the pass name.
  27. auto print_disassembly = [&context, this](const char* preamble, Pass* pass) {
  28. if (print_all_stream_) {
  29. std::vector<uint32_t> binary;
  30. context->module()->ToBinary(&binary, false);
  31. SpirvTools t(SPV_ENV_UNIVERSAL_1_2);
  32. std::string disassembly;
  33. t.Disassemble(binary, &disassembly, 0);
  34. *print_all_stream_ << preamble << (pass ? pass->name() : "") << "\n"
  35. << disassembly << std::endl;
  36. }
  37. };
  38. SPIRV_TIMER_DESCRIPTION(time_report_stream_, /* measure_mem_usage = */ true);
  39. for (auto& pass : passes_) {
  40. print_disassembly("; IR before pass ", pass.get());
  41. SPIRV_TIMER_SCOPED(time_report_stream_, (pass ? pass->name() : ""), true);
  42. const auto one_status = pass->Run(context);
  43. if (one_status == Pass::Status::Failure) return one_status;
  44. if (one_status == Pass::Status::SuccessWithChange) status = one_status;
  45. // Reset the pass to free any memory used by the pass.
  46. pass.reset(nullptr);
  47. }
  48. print_disassembly("; IR after last pass", nullptr);
  49. // Set the Id bound in the header in case a pass forgot to do so.
  50. //
  51. // TODO(dnovillo): This should be unnecessary and automatically maintained by
  52. // the IRContext.
  53. if (status == Pass::Status::SuccessWithChange) {
  54. context->module()->SetIdBound(context->module()->ComputeIdBound());
  55. }
  56. passes_.clear();
  57. return status;
  58. }
  59. } // namespace opt
  60. } // namespace spvtools