value_number_table.h 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. // Copyright (c) 2017 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. #ifndef SOURCE_OPT_VALUE_NUMBER_TABLE_H_
  15. #define SOURCE_OPT_VALUE_NUMBER_TABLE_H_
  16. #include <cstdint>
  17. #include <unordered_map>
  18. #include "source/opt/instruction.h"
  19. namespace spvtools {
  20. namespace opt {
  21. class IRContext;
  22. // Returns true if the two instructions compute the same value. Used by the
  23. // value number table to compare two instructions.
  24. class ComputeSameValue {
  25. public:
  26. bool operator()(const Instruction& lhs, const Instruction& rhs) const;
  27. };
  28. // The hash function used in the value number table.
  29. class ValueTableHash {
  30. public:
  31. std::size_t operator()(const Instruction& inst) const;
  32. };
  33. // This class implements the value number analysis. It is using a hash-based
  34. // approach to value numbering. It is essentially doing dominator-tree value
  35. // numbering described in
  36. //
  37. // Preston Briggs, Keith D. Cooper, and L. Taylor Simpson. 1997. Value
  38. // numbering. Softw. Pract. Exper. 27, 6 (June 1997), 701-724.
  39. // https://www.cs.rice.edu/~keith/Promo/CRPC-TR94517.pdf.gz
  40. //
  41. // The main difference is that because we do not perform redundancy elimination
  42. // as we build the value number table, we do not have to deal with cleaning up
  43. // the scope.
  44. class ValueNumberTable {
  45. public:
  46. ValueNumberTable(IRContext* ctx) : context_(ctx), next_value_number_(1) {
  47. BuildDominatorTreeValueNumberTable();
  48. }
  49. // Returns the value number of the value computed by |inst|. |inst| must have
  50. // a result id that will hold the computed value. If no value number has been
  51. // assigned to the result id, then the return value is 0.
  52. uint32_t GetValueNumber(Instruction* inst) const;
  53. // Returns the value number of the value contain in |id|. Returns 0 if it
  54. // has not been assigned a value number.
  55. uint32_t GetValueNumber(uint32_t id) const;
  56. IRContext* context() const { return context_; }
  57. private:
  58. // Assigns a value number to every result id in the module.
  59. void BuildDominatorTreeValueNumberTable();
  60. // Returns the new value number.
  61. uint32_t TakeNextValueNumber() { return next_value_number_++; }
  62. // Assigns a new value number to the result of |inst| if it does not already
  63. // have one. Return the value number for |inst|. |inst| must have a result
  64. // id.
  65. uint32_t AssignValueNumber(Instruction* inst);
  66. std::unordered_map<Instruction, uint32_t, ValueTableHash, ComputeSameValue>
  67. instruction_to_value_;
  68. std::unordered_map<uint32_t, uint32_t> id_to_value_;
  69. IRContext* context_;
  70. uint32_t next_value_number_;
  71. };
  72. } // namespace opt
  73. } // namespace spvtools
  74. #endif // SOURCE_OPT_VALUE_NUMBER_TABLE_H_