constant.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #ifndef CARBON_TOOLCHAIN_SEM_IR_CONSTANT_H_
  5. #define CARBON_TOOLCHAIN_SEM_IR_CONSTANT_H_
  6. #include "llvm/ADT/FoldingSet.h"
  7. #include "toolchain/sem_ir/ids.h"
  8. #include "toolchain/sem_ir/inst.h"
  9. namespace Carbon::SemIR {
  10. // Provides a ValueStore wrapper for tracking the constant values of
  11. // instructions.
  12. class ConstantValueStore {
  13. public:
  14. explicit ConstantValueStore(ConstantId default_value)
  15. : default_(default_value) {}
  16. // Returns the constant value of the requested instruction, which is default_
  17. // if unallocated.
  18. auto Get(InstId inst_id) const -> ConstantId {
  19. CARBON_CHECK(inst_id.index >= 0);
  20. return static_cast<size_t>(inst_id.index) >= values_.size()
  21. ? default_
  22. : values_[inst_id.index];
  23. }
  24. // Sets the constant value of the given instruction, or sets that it is known
  25. // to not be a constant.
  26. auto Set(InstId inst_id, ConstantId const_id) -> void {
  27. CARBON_CHECK(inst_id.index >= 0);
  28. if (static_cast<size_t>(inst_id.index) >= values_.size()) {
  29. values_.resize(inst_id.index + 1, default_);
  30. }
  31. values_[inst_id.index] = const_id;
  32. }
  33. // Gets the instruction ID that defines the value of the given constant.
  34. // Returns Invalid if the constant ID is non-constant. Requires is_valid.
  35. auto GetInstId(ConstantId const_id) const -> InstId {
  36. return const_id.inst_id();
  37. }
  38. // Gets the instruction ID that defines the value of the given constant.
  39. // Returns Invalid if the constant ID is non-constant or invalid.
  40. auto GetInstIdIfValid(ConstantId const_id) const -> InstId {
  41. return const_id.is_valid() ? GetInstId(const_id) : InstId::Invalid;
  42. }
  43. // Given an instruction, returns the unique constant instruction that is
  44. // equivalent to it. Returns Invalid for a non-constant instruction.
  45. auto GetConstantInstId(InstId inst_id) const -> InstId {
  46. return GetInstId(Get(inst_id));
  47. }
  48. // Returns the constant values mapping as an ArrayRef whose keys are
  49. // instruction indexes. Some of the elements in this mapping may be Invalid or
  50. // NotConstant.
  51. auto array_ref() const -> llvm::ArrayRef<ConstantId> { return values_; }
  52. private:
  53. const ConstantId default_;
  54. // A mapping from `InstId::index` to the corresponding constant value. This is
  55. // expected to be sparse, and may be smaller than the list of instructions if
  56. // there are trailing non-constant instructions.
  57. //
  58. // Set inline size to 0 because these will typically be too large for the
  59. // stack, while this does make File smaller.
  60. llvm::SmallVector<ConstantId, 0> values_;
  61. };
  62. // Provides storage for instructions representing deduplicated global constants.
  63. class ConstantStore {
  64. public:
  65. explicit ConstantStore(File& sem_ir, llvm::BumpPtrAllocator& /*allocator*/)
  66. : sem_ir_(sem_ir) {}
  67. // Adds a new constant instruction, or gets the existing constant with this
  68. // value. Returns the ID of the constant.
  69. //
  70. // This updates `sem_ir.insts()` and `sem_ir.constant_values()` if the
  71. // constant is new.
  72. auto GetOrAdd(Inst inst, bool is_symbolic) -> ConstantId;
  73. // Returns a copy of the constant IDs as a vector, in an arbitrary but
  74. // stable order. This should not be used anywhere performance-sensitive.
  75. auto array_ref() const -> llvm::ArrayRef<InstId> { return constants_; }
  76. auto size() const -> int { return constants_.size(); }
  77. private:
  78. File& sem_ir_;
  79. llvm::DenseMap<Inst, ConstantId> map_;
  80. llvm::SmallVector<InstId, 0> constants_;
  81. };
  82. } // namespace Carbon::SemIR
  83. #endif // CARBON_TOOLCHAIN_SEM_IR_CONSTANT_H_