inst_profile.cpp 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  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/inst.h"
  7. namespace Carbon::SemIR {
  8. // A function to profile an argument of an instruction.
  9. using ProfileArgFunction = auto(llvm::FoldingSetNodeID&, const File& sem_ir,
  10. int32_t arg) -> void;
  11. // Profiling for unused arguments.
  12. static auto NullProfileArgFunction(llvm::FoldingSetNodeID& /*id*/,
  13. const File& /*sem_ir*/, int32_t arg)
  14. -> void {
  15. CARBON_CHECK(arg == IdBase::InvalidIndex)
  16. << "Unexpected value for unused argument.";
  17. }
  18. // Profiling for ID arguments that should participate in the instruction's
  19. // value.
  20. static auto DefaultProfileArgFunction(llvm::FoldingSetNodeID& id,
  21. const File& /*sem_ir*/, int32_t arg)
  22. -> void {
  23. id.AddInteger(arg);
  24. }
  25. // Profiling for block ID arguments for which the content of the block should be
  26. // included.
  27. static auto InstBlockProfileArgFunction(llvm::FoldingSetNodeID& id,
  28. const File& sem_ir, int32_t arg)
  29. -> void {
  30. for (auto inst_id : sem_ir.inst_blocks().Get(InstBlockId(arg))) {
  31. id.AddInteger(inst_id.index);
  32. }
  33. }
  34. // Profiling for type block ID arguments for which the content of the block
  35. // should be included.
  36. static auto TypeBlockProfileArgFunction(llvm::FoldingSetNodeID& id,
  37. const File& sem_ir, int32_t arg)
  38. -> void {
  39. for (auto type_id : sem_ir.type_blocks().Get(TypeBlockId(arg))) {
  40. id.AddInteger(type_id.index);
  41. }
  42. }
  43. // Profiling for integer IDs.
  44. static auto IntProfileArgFunction(llvm::FoldingSetNodeID& id,
  45. const File& sem_ir, int32_t arg) -> void {
  46. sem_ir.ints().Get(IntId(arg)).Profile(id);
  47. }
  48. // Profiling for real number IDs.
  49. static auto RealProfileArgFunction(llvm::FoldingSetNodeID& id,
  50. const File& sem_ir, int32_t arg) -> void {
  51. const auto& real = sem_ir.reals().Get(RealId(arg));
  52. // TODO: Profile the value rather than the syntactic form.
  53. real.mantissa.Profile(id);
  54. real.exponent.Profile(id);
  55. id.AddBoolean(real.is_decimal);
  56. }
  57. // Profiles the given instruction argument, which is of the specified kind.
  58. static auto ProfileArg(llvm::FoldingSetNodeID& id, const File& sem_ir,
  59. IdKind arg_kind, int32_t arg) -> void {
  60. static constexpr std::array<ProfileArgFunction*, IdKind::NumValues>
  61. ProfileFunctions = [] {
  62. std::array<ProfileArgFunction*, IdKind::NumValues> array;
  63. array.fill(DefaultProfileArgFunction);
  64. array[IdKind::None.ToIndex()] = NullProfileArgFunction;
  65. array[IdKind::For<InstBlockId>.ToIndex()] = InstBlockProfileArgFunction;
  66. array[IdKind::For<TypeBlockId>.ToIndex()] = TypeBlockProfileArgFunction;
  67. array[IdKind::For<IntId>.ToIndex()] = IntProfileArgFunction;
  68. array[IdKind::For<RealId>.ToIndex()] = RealProfileArgFunction;
  69. return array;
  70. }();
  71. ProfileFunctions[arg_kind.ToIndex()](id, sem_ir, arg);
  72. }
  73. auto ProfileConstant(llvm::FoldingSetNodeID& id, const File& sem_ir, Inst inst)
  74. -> void {
  75. inst.kind().Profile(id);
  76. id.AddInteger(inst.type_id().index);
  77. auto arg_kinds = inst.ArgKinds();
  78. ProfileArg(id, sem_ir, arg_kinds.first, inst.arg0());
  79. ProfileArg(id, sem_ir, arg_kinds.second, inst.arg1());
  80. }
  81. } // namespace Carbon::SemIR