inst_profile.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  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. #include "toolchain/sem_ir/inst_profile.h"
  5. #include "toolchain/sem_ir/file.h"
  6. #include "toolchain/sem_ir/ids.h"
  7. #include "toolchain/sem_ir/inst.h"
  8. namespace Carbon::SemIR {
  9. // A function to profile an argument of an instruction.
  10. using ProfileArgFunction = auto(llvm::FoldingSetNodeID&, const File& sem_ir,
  11. int32_t arg) -> void;
  12. // Profiling for unused arguments.
  13. static auto NullProfileArgFunction(llvm::FoldingSetNodeID& /*id*/,
  14. const File& /*sem_ir*/, int32_t arg)
  15. -> void {
  16. CARBON_CHECK(arg == IdBase::InvalidIndex)
  17. << "Unexpected value for unused argument.";
  18. }
  19. // Profiling for ID arguments that should participate in the instruction's
  20. // value.
  21. static auto DefaultProfileArgFunction(llvm::FoldingSetNodeID& id,
  22. const File& /*sem_ir*/, int32_t arg)
  23. -> void {
  24. id.AddInteger(arg);
  25. }
  26. // Profiling for block ID arguments for which the content of the block should be
  27. // included.
  28. static auto InstBlockProfileArgFunction(llvm::FoldingSetNodeID& id,
  29. const File& sem_ir, int32_t arg)
  30. -> void {
  31. auto inst_block_id = InstBlockId(arg);
  32. if (!inst_block_id.is_valid()) {
  33. id.AddInteger(-1);
  34. return;
  35. }
  36. auto inst_block = sem_ir.inst_blocks().Get(inst_block_id);
  37. id.AddInteger(inst_block.size());
  38. for (auto inst_id : inst_block) {
  39. id.AddInteger(inst_id.index);
  40. }
  41. }
  42. // Profiling for type block ID arguments for which the content of the block
  43. // should be included.
  44. static auto TypeBlockProfileArgFunction(llvm::FoldingSetNodeID& id,
  45. const File& sem_ir, int32_t arg)
  46. -> void {
  47. auto type_block_id = TypeBlockId(arg);
  48. if (!type_block_id.is_valid()) {
  49. id.AddInteger(-1);
  50. return;
  51. }
  52. auto type_block = sem_ir.type_blocks().Get(type_block_id);
  53. id.AddInteger(type_block.size());
  54. for (auto type_id : type_block) {
  55. id.AddInteger(type_id.index);
  56. }
  57. }
  58. // Profiling for integer IDs.
  59. static auto IntProfileArgFunction(llvm::FoldingSetNodeID& id,
  60. const File& sem_ir, int32_t arg) -> void {
  61. sem_ir.ints().Get(IntId(arg)).Profile(id);
  62. }
  63. // Profiling for real number IDs.
  64. static auto RealProfileArgFunction(llvm::FoldingSetNodeID& id,
  65. const File& sem_ir, int32_t arg) -> void {
  66. const auto& real = sem_ir.reals().Get(RealId(arg));
  67. // TODO: Profile the value rather than the syntactic form.
  68. real.mantissa.Profile(id);
  69. real.exponent.Profile(id);
  70. id.AddBoolean(real.is_decimal);
  71. }
  72. // Profiling for BindNameInfo.
  73. static auto BindNameIdProfileArgFunction(llvm::FoldingSetNodeID& id,
  74. const File& sem_ir, int32_t arg)
  75. -> void {
  76. const auto& [name_id, enclosing_scope_id, bind_index] =
  77. sem_ir.bind_names().Get(BindNameId(arg));
  78. id.AddInteger(name_id.index);
  79. id.AddInteger(enclosing_scope_id.index);
  80. id.AddInteger(bind_index.index);
  81. }
  82. // Profiles the given instruction argument, which is of the specified kind.
  83. static auto ProfileArg(llvm::FoldingSetNodeID& id, const File& sem_ir,
  84. IdKind arg_kind, int32_t arg) -> void {
  85. static constexpr std::array<ProfileArgFunction*, IdKind::NumValues>
  86. ProfileFunctions = [] {
  87. std::array<ProfileArgFunction*, IdKind::NumValues> array;
  88. array.fill(DefaultProfileArgFunction);
  89. array[IdKind::None.ToIndex()] = NullProfileArgFunction;
  90. array[IdKind::For<InstBlockId>.ToIndex()] = InstBlockProfileArgFunction;
  91. array[IdKind::For<TypeBlockId>.ToIndex()] = TypeBlockProfileArgFunction;
  92. array[IdKind::For<IntId>.ToIndex()] = IntProfileArgFunction;
  93. array[IdKind::For<RealId>.ToIndex()] = RealProfileArgFunction;
  94. array[IdKind::For<BindNameId>.ToIndex()] = BindNameIdProfileArgFunction;
  95. return array;
  96. }();
  97. ProfileFunctions[arg_kind.ToIndex()](id, sem_ir, arg);
  98. }
  99. auto ProfileConstant(llvm::FoldingSetNodeID& id, const File& sem_ir, Inst inst)
  100. -> void {
  101. inst.kind().Profile(id);
  102. id.AddInteger(inst.type_id().index);
  103. auto arg_kinds = inst.ArgKinds();
  104. ProfileArg(id, sem_ir, arg_kinds.first, inst.arg0());
  105. ProfileArg(id, sem_ir, arg_kinds.second, inst.arg1());
  106. }
  107. } // namespace Carbon::SemIR