eval.cpp 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269
  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/check/eval.h"
  5. #include "toolchain/base/kind_switch.h"
  6. #include "toolchain/check/diagnostic_helpers.h"
  7. #include "toolchain/diagnostics/diagnostic_emitter.h"
  8. #include "toolchain/sem_ir/builtin_function_kind.h"
  9. #include "toolchain/sem_ir/function.h"
  10. #include "toolchain/sem_ir/ids.h"
  11. #include "toolchain/sem_ir/inst_kind.h"
  12. #include "toolchain/sem_ir/typed_insts.h"
  13. namespace Carbon::Check {
  14. static auto MakeGenericInstance(Context& context, SemIR::GenericId generic_id,
  15. SemIR::InstBlockId args_id)
  16. -> SemIR::GenericInstanceId {
  17. auto instance_id = context.generic_instances().GetOrAdd(generic_id, args_id);
  18. // TODO: Perform substitution into the generic declaration if needed.
  19. return instance_id;
  20. }
  21. namespace {
  22. // The evaluation phase for an expression, computed by evaluation. These are
  23. // ordered so that the phase of an expression is the numerically highest phase
  24. // of its constituent evaluations. Note that an expression with any runtime
  25. // component is known to have Runtime phase even if it involves an evaluation
  26. // with UnknownDueToError phase.
  27. enum class Phase : uint8_t {
  28. // Value could be entirely and concretely computed.
  29. Template,
  30. // Evaluation phase is symbolic because the expression involves a reference to
  31. // a symbolic binding.
  32. Symbolic,
  33. // The evaluation phase is unknown because evaluation encountered an
  34. // already-diagnosed semantic or syntax error. This is treated as being
  35. // potentially constant, but with an unknown phase.
  36. UnknownDueToError,
  37. // The expression has runtime phase because of a non-constant subexpression.
  38. Runtime,
  39. };
  40. } // namespace
  41. // Gets the phase in which the value of a constant will become available.
  42. static auto GetPhase(SemIR::ConstantId constant_id) -> Phase {
  43. if (!constant_id.is_constant()) {
  44. return Phase::Runtime;
  45. } else if (constant_id == SemIR::ConstantId::Error) {
  46. return Phase::UnknownDueToError;
  47. } else if (constant_id.is_template()) {
  48. return Phase::Template;
  49. } else {
  50. CARBON_CHECK(constant_id.is_symbolic());
  51. return Phase::Symbolic;
  52. }
  53. }
  54. // Gets the earliest possible phase for a constant whose type is `type_id`. The
  55. // type of a constant is effectively treated as an operand of that constant when
  56. // determining its phase. For example, an empty struct with a symbolic type is a
  57. // symbolic constant, not a template constant.
  58. static auto GetTypePhase(Context& context, SemIR::TypeId type_id) -> Phase {
  59. CARBON_CHECK(type_id.is_valid());
  60. return GetPhase(context.types().GetConstantId(type_id));
  61. }
  62. // Returns the later of two phases.
  63. static auto LatestPhase(Phase a, Phase b) -> Phase {
  64. return static_cast<Phase>(
  65. std::max(static_cast<uint8_t>(a), static_cast<uint8_t>(b)));
  66. }
  67. // Forms a `constant_id` describing a given evaluation result.
  68. static auto MakeConstantResult(Context& context, SemIR::Inst inst, Phase phase)
  69. -> SemIR::ConstantId {
  70. switch (phase) {
  71. case Phase::Template:
  72. return context.AddConstant(inst, /*is_symbolic=*/false);
  73. case Phase::Symbolic:
  74. return context.AddConstant(inst, /*is_symbolic=*/true);
  75. case Phase::UnknownDueToError:
  76. return SemIR::ConstantId::Error;
  77. case Phase::Runtime:
  78. return SemIR::ConstantId::NotConstant;
  79. }
  80. }
  81. // Forms a `constant_id` describing why an evaluation was not constant.
  82. static auto MakeNonConstantResult(Phase phase) -> SemIR::ConstantId {
  83. return phase == Phase::UnknownDueToError ? SemIR::ConstantId::Error
  84. : SemIR::ConstantId::NotConstant;
  85. }
  86. // Converts a bool value into a ConstantId.
  87. static auto MakeBoolResult(Context& context, SemIR::TypeId bool_type_id,
  88. bool result) -> SemIR::ConstantId {
  89. return MakeConstantResult(
  90. context,
  91. SemIR::BoolLiteral{.type_id = bool_type_id,
  92. .value = SemIR::BoolValue::From(result)},
  93. Phase::Template);
  94. }
  95. // Converts an APInt value into a ConstantId.
  96. static auto MakeIntResult(Context& context, SemIR::TypeId type_id,
  97. llvm::APInt value) -> SemIR::ConstantId {
  98. auto result = context.ints().Add(std::move(value));
  99. return MakeConstantResult(
  100. context, SemIR::IntLiteral{.type_id = type_id, .int_id = result},
  101. Phase::Template);
  102. }
  103. // Converts an APFloat value into a ConstantId.
  104. static auto MakeFloatResult(Context& context, SemIR::TypeId type_id,
  105. llvm::APFloat value) -> SemIR::ConstantId {
  106. auto result = context.floats().Add(std::move(value));
  107. return MakeConstantResult(
  108. context, SemIR::FloatLiteral{.type_id = type_id, .float_id = result},
  109. Phase::Template);
  110. }
  111. // `GetConstantValue` checks to see whether the provided ID describes a value
  112. // with constant phase, and if so, returns the corresponding constant value.
  113. // Overloads are provided for different kinds of ID.
  114. // If the given instruction is constant, returns its constant value.
  115. static auto GetConstantValue(Context& context, SemIR::InstId inst_id,
  116. Phase* phase) -> SemIR::InstId {
  117. auto const_id = context.constant_values().Get(inst_id);
  118. *phase = LatestPhase(*phase, GetPhase(const_id));
  119. return context.constant_values().GetInstId(const_id);
  120. }
  121. // A type is always constant, but we still need to extract its phase.
  122. static auto GetConstantValue(Context& context, SemIR::TypeId type_id,
  123. Phase* phase) -> SemIR::TypeId {
  124. auto const_id = context.types().GetConstantId(type_id);
  125. *phase = LatestPhase(*phase, GetPhase(const_id));
  126. return type_id;
  127. }
  128. // If the given instruction block contains only constants, returns a
  129. // corresponding block of those values.
  130. static auto GetConstantValue(Context& context, SemIR::InstBlockId inst_block_id,
  131. Phase* phase) -> SemIR::InstBlockId {
  132. if (!inst_block_id.is_valid()) {
  133. return SemIR::InstBlockId::Invalid;
  134. }
  135. auto insts = context.inst_blocks().Get(inst_block_id);
  136. llvm::SmallVector<SemIR::InstId> const_insts;
  137. for (auto inst_id : insts) {
  138. auto const_inst_id = GetConstantValue(context, inst_id, phase);
  139. if (!const_inst_id.is_valid()) {
  140. return SemIR::InstBlockId::Invalid;
  141. }
  142. // Once we leave the small buffer, we know the first few elements are all
  143. // constant, so it's likely that the entire block is constant. Resize to the
  144. // target size given that we're going to allocate memory now anyway.
  145. if (const_insts.size() == const_insts.capacity()) {
  146. const_insts.reserve(insts.size());
  147. }
  148. const_insts.push_back(const_inst_id);
  149. }
  150. // TODO: If the new block is identical to the original block, and we know the
  151. // old ID was canonical, return the original ID.
  152. return context.inst_blocks().AddCanonical(const_insts);
  153. }
  154. // The constant value of a type block is that type block, but we still need to
  155. // extract its phase.
  156. static auto GetConstantValue(Context& context, SemIR::TypeBlockId type_block_id,
  157. Phase* phase) -> SemIR::TypeBlockId {
  158. if (!type_block_id.is_valid()) {
  159. return SemIR::TypeBlockId::Invalid;
  160. }
  161. auto types = context.type_blocks().Get(type_block_id);
  162. for (auto type_id : types) {
  163. GetConstantValue(context, type_id, phase);
  164. }
  165. return type_block_id;
  166. }
  167. // The constant value of a generic instance is the generic instance with the
  168. // corresponding constant values for its arguments.
  169. static auto GetConstantValue(Context& context,
  170. SemIR::GenericInstanceId instance_id, Phase* phase)
  171. -> SemIR::GenericInstanceId {
  172. if (!instance_id.is_valid()) {
  173. return SemIR::GenericInstanceId::Invalid;
  174. }
  175. const auto& instance = context.generic_instances().Get(instance_id);
  176. auto args_id = GetConstantValue(context, instance.args_id, phase);
  177. if (!args_id.is_valid()) {
  178. return SemIR::GenericInstanceId::Invalid;
  179. }
  180. if (args_id == instance.args_id) {
  181. return instance_id;
  182. }
  183. return MakeGenericInstance(context, instance.generic_id, args_id);
  184. }
  185. // Replaces the specified field of the given typed instruction with its constant
  186. // value, if it has constant phase. Returns true on success, false if the value
  187. // has runtime phase.
  188. template <typename InstT, typename FieldIdT>
  189. static auto ReplaceFieldWithConstantValue(Context& context, InstT* inst,
  190. FieldIdT InstT::*field, Phase* phase)
  191. -> bool {
  192. auto unwrapped = GetConstantValue(context, inst->*field, phase);
  193. if (!unwrapped.is_valid() && (inst->*field).is_valid()) {
  194. return false;
  195. }
  196. inst->*field = unwrapped;
  197. return true;
  198. }
  199. // If the specified fields of the given typed instruction have constant values,
  200. // replaces the fields with their constant values and builds a corresponding
  201. // constant value. Otherwise returns `ConstantId::NotConstant`. Returns
  202. // `ConstantId::Error` if any subexpression is an error.
  203. //
  204. // The constant value is then checked by calling `validate_fn(typed_inst)`,
  205. // which should return a `bool` indicating whether the new constant is valid. If
  206. // validation passes, a corresponding ConstantId for the new constant is
  207. // returned. If validation fails, it should produce a suitable error message.
  208. // `ConstantId::Error` is returned.
  209. template <typename InstT, typename ValidateFn, typename... EachFieldIdT>
  210. static auto RebuildAndValidateIfFieldsAreConstant(
  211. Context& context, SemIR::Inst inst, ValidateFn validate_fn,
  212. EachFieldIdT InstT::*... each_field_id) -> SemIR::ConstantId {
  213. // Build a constant instruction by replacing each non-constant operand with
  214. // its constant value.
  215. auto typed_inst = inst.As<InstT>();
  216. // Some instruction kinds don't have a `type_id` field. For those that do, the
  217. // type contributes to the phase.
  218. Phase phase = inst.type_id().is_valid()
  219. ? GetTypePhase(context, inst.type_id())
  220. : Phase::Template;
  221. if ((ReplaceFieldWithConstantValue(context, &typed_inst, each_field_id,
  222. &phase) &&
  223. ...)) {
  224. if (phase == Phase::UnknownDueToError || !validate_fn(typed_inst)) {
  225. return SemIR::ConstantId::Error;
  226. }
  227. return MakeConstantResult(context, typed_inst, phase);
  228. }
  229. return MakeNonConstantResult(phase);
  230. }
  231. // Same as above but with no validation step.
  232. template <typename InstT, typename... EachFieldIdT>
  233. static auto RebuildIfFieldsAreConstant(Context& context, SemIR::Inst inst,
  234. EachFieldIdT InstT::*... each_field_id)
  235. -> SemIR::ConstantId {
  236. return RebuildAndValidateIfFieldsAreConstant(
  237. context, inst, [](...) { return true; }, each_field_id...);
  238. }
  239. // Rebuilds the given aggregate initialization instruction as a corresponding
  240. // constant aggregate value, if its elements are all constants.
  241. static auto RebuildInitAsValue(Context& context, SemIR::Inst inst,
  242. SemIR::InstKind value_kind)
  243. -> SemIR::ConstantId {
  244. auto init_inst = inst.As<SemIR::AnyAggregateInit>();
  245. Phase phase = GetTypePhase(context, init_inst.type_id);
  246. auto elements_id = GetConstantValue(context, init_inst.elements_id, &phase);
  247. return MakeConstantResult(
  248. context,
  249. SemIR::AnyAggregateValue{.kind = value_kind,
  250. .type_id = init_inst.type_id,
  251. .elements_id = elements_id},
  252. phase);
  253. }
  254. // Performs an access into an aggregate, retrieving the specified element.
  255. static auto PerformAggregateAccess(Context& context, SemIR::Inst inst)
  256. -> SemIR::ConstantId {
  257. auto access_inst = inst.As<SemIR::AnyAggregateAccess>();
  258. Phase phase = Phase::Template;
  259. if (auto aggregate_id =
  260. GetConstantValue(context, access_inst.aggregate_id, &phase);
  261. aggregate_id.is_valid()) {
  262. if (auto aggregate =
  263. context.insts().TryGetAs<SemIR::AnyAggregateValue>(aggregate_id)) {
  264. auto elements = context.inst_blocks().Get(aggregate->elements_id);
  265. auto index = static_cast<size_t>(access_inst.index.index);
  266. CARBON_CHECK(index < elements.size()) << "Access out of bounds.";
  267. // `Phase` is not used here. If this element is a template constant, then
  268. // so is the result of indexing, even if the aggregate also contains a
  269. // symbolic context.
  270. return context.constant_values().Get(elements[index]);
  271. } else {
  272. CARBON_CHECK(phase != Phase::Template)
  273. << "Failed to evaluate template constant " << inst;
  274. }
  275. }
  276. return MakeNonConstantResult(phase);
  277. }
  278. // Performs an index into a homogeneous aggregate, retrieving the specified
  279. // element.
  280. static auto PerformAggregateIndex(Context& context, SemIR::Inst inst)
  281. -> SemIR::ConstantId {
  282. auto index_inst = inst.As<SemIR::AnyAggregateIndex>();
  283. Phase phase = Phase::Template;
  284. auto aggregate_id =
  285. GetConstantValue(context, index_inst.aggregate_id, &phase);
  286. auto index_id = GetConstantValue(context, index_inst.index_id, &phase);
  287. if (!index_id.is_valid()) {
  288. return MakeNonConstantResult(phase);
  289. }
  290. auto index = context.insts().TryGetAs<SemIR::IntLiteral>(index_id);
  291. if (!index) {
  292. CARBON_CHECK(phase != Phase::Template)
  293. << "Template constant integer should be a literal";
  294. return MakeNonConstantResult(phase);
  295. }
  296. // Array indexing is invalid if the index is constant and out of range.
  297. auto aggregate_type_id =
  298. context.insts().Get(index_inst.aggregate_id).type_id();
  299. const auto& index_val = context.ints().Get(index->int_id);
  300. if (auto array_type =
  301. context.types().TryGetAs<SemIR::ArrayType>(aggregate_type_id)) {
  302. if (auto bound =
  303. context.insts().TryGetAs<SemIR::IntLiteral>(array_type->bound_id)) {
  304. // This awkward call to `getZExtValue` is a workaround for APInt not
  305. // supporting comparisons between integers of different bit widths.
  306. if (index_val.getActiveBits() > 64 ||
  307. context.ints().Get(bound->int_id).ule(index_val.getZExtValue())) {
  308. CARBON_DIAGNOSTIC(ArrayIndexOutOfBounds, Error,
  309. "Array index `{0}` is past the end of type `{1}`.",
  310. TypedInt, SemIR::TypeId);
  311. context.emitter().Emit(index_inst.index_id, ArrayIndexOutOfBounds,
  312. {.type = index->type_id, .value = index_val},
  313. aggregate_type_id);
  314. return SemIR::ConstantId::Error;
  315. }
  316. }
  317. }
  318. if (!aggregate_id.is_valid()) {
  319. return MakeNonConstantResult(phase);
  320. }
  321. auto aggregate =
  322. context.insts().TryGetAs<SemIR::AnyAggregateValue>(aggregate_id);
  323. if (!aggregate) {
  324. CARBON_CHECK(phase != Phase::Template)
  325. << "Unexpected representation for template constant aggregate";
  326. return MakeNonConstantResult(phase);
  327. }
  328. auto elements = context.inst_blocks().Get(aggregate->elements_id);
  329. // We checked this for the array case above.
  330. CARBON_CHECK(index_val.ult(elements.size()))
  331. << "Index out of bounds in tuple indexing";
  332. return context.constant_values().Get(elements[index_val.getZExtValue()]);
  333. }
  334. // Enforces that an integer type has a valid bit width.
  335. static auto ValidateIntType(Context& context, SemIRLoc loc,
  336. SemIR::IntType result) -> bool {
  337. auto bit_width =
  338. context.insts().TryGetAs<SemIR::IntLiteral>(result.bit_width_id);
  339. if (!bit_width) {
  340. // Symbolic bit width.
  341. return true;
  342. }
  343. const auto& bit_width_val = context.ints().Get(bit_width->int_id);
  344. if (bit_width_val.isZero() ||
  345. (context.types().IsSignedInt(bit_width->type_id) &&
  346. bit_width_val.isNegative())) {
  347. CARBON_DIAGNOSTIC(IntWidthNotPositive, Error,
  348. "Integer type width of {0} is not positive.", TypedInt);
  349. context.emitter().Emit(
  350. loc, IntWidthNotPositive,
  351. {.type = bit_width->type_id, .value = bit_width_val});
  352. return false;
  353. }
  354. // TODO: Pick a maximum size and document it in the design. For now
  355. // we use 2^^23, because that's the largest size that LLVM supports.
  356. constexpr int MaxIntWidth = 1 << 23;
  357. if (bit_width_val.ugt(MaxIntWidth)) {
  358. CARBON_DIAGNOSTIC(IntWidthTooLarge, Error,
  359. "Integer type width of {0} is greater than the "
  360. "maximum supported width of {1}.",
  361. TypedInt, int);
  362. context.emitter().Emit(loc, IntWidthTooLarge,
  363. {.type = bit_width->type_id, .value = bit_width_val},
  364. MaxIntWidth);
  365. return false;
  366. }
  367. return true;
  368. }
  369. // Forms a constant int type as an evaluation result. Requires that width_id is
  370. // constant.
  371. auto MakeIntTypeResult(Context& context, SemIRLoc loc, SemIR::IntKind int_kind,
  372. SemIR::InstId width_id, Phase phase)
  373. -> SemIR::ConstantId {
  374. auto result = SemIR::IntType{
  375. .type_id = context.GetBuiltinType(SemIR::BuiltinKind::TypeType),
  376. .int_kind = int_kind,
  377. .bit_width_id = width_id};
  378. if (!ValidateIntType(context, loc, result)) {
  379. return SemIR::ConstantId::Error;
  380. }
  381. return MakeConstantResult(context, result, phase);
  382. }
  383. // Enforces that the bit width is 64 for a float.
  384. static auto ValidateFloatBitWidth(Context& context, SemIRLoc loc,
  385. SemIR::InstId inst_id) -> bool {
  386. auto inst = context.insts().GetAs<SemIR::IntLiteral>(inst_id);
  387. if (context.ints().Get(inst.int_id) == 64) {
  388. return true;
  389. }
  390. CARBON_DIAGNOSTIC(CompileTimeFloatBitWidth, Error, "Bit width must be 64.");
  391. context.emitter().Emit(loc, CompileTimeFloatBitWidth);
  392. return false;
  393. }
  394. // Enforces that a float type has a valid bit width.
  395. static auto ValidateFloatType(Context& context, SemIRLoc loc,
  396. SemIR::FloatType result) -> bool {
  397. auto bit_width =
  398. context.insts().TryGetAs<SemIR::IntLiteral>(result.bit_width_id);
  399. if (!bit_width) {
  400. // Symbolic bit width.
  401. return true;
  402. }
  403. return ValidateFloatBitWidth(context, loc, result.bit_width_id);
  404. }
  405. // Issues a diagnostic for a compile-time division by zero.
  406. static auto DiagnoseDivisionByZero(Context& context, SemIRLoc loc) -> void {
  407. CARBON_DIAGNOSTIC(CompileTimeDivisionByZero, Error, "Division by zero.");
  408. context.emitter().Emit(loc, CompileTimeDivisionByZero);
  409. }
  410. // Performs a builtin unary integer -> integer operation.
  411. static auto PerformBuiltinUnaryIntOp(Context& context, SemIRLoc loc,
  412. SemIR::BuiltinFunctionKind builtin_kind,
  413. SemIR::InstId arg_id)
  414. -> SemIR::ConstantId {
  415. auto op = context.insts().GetAs<SemIR::IntLiteral>(arg_id);
  416. auto op_val = context.ints().Get(op.int_id);
  417. switch (builtin_kind) {
  418. case SemIR::BuiltinFunctionKind::IntSNegate:
  419. if (context.types().IsSignedInt(op.type_id) &&
  420. op_val.isMinSignedValue()) {
  421. CARBON_DIAGNOSTIC(CompileTimeIntegerNegateOverflow, Error,
  422. "Integer overflow in negation of {0}.", TypedInt);
  423. context.emitter().Emit(loc, CompileTimeIntegerNegateOverflow,
  424. {.type = op.type_id, .value = op_val});
  425. }
  426. op_val.negate();
  427. break;
  428. case SemIR::BuiltinFunctionKind::IntUNegate:
  429. op_val.negate();
  430. break;
  431. case SemIR::BuiltinFunctionKind::IntComplement:
  432. op_val.flipAllBits();
  433. break;
  434. default:
  435. CARBON_FATAL() << "Unexpected builtin kind";
  436. }
  437. return MakeIntResult(context, op.type_id, std::move(op_val));
  438. }
  439. // Performs a builtin binary integer -> integer operation.
  440. static auto PerformBuiltinBinaryIntOp(Context& context, SemIRLoc loc,
  441. SemIR::BuiltinFunctionKind builtin_kind,
  442. SemIR::InstId lhs_id,
  443. SemIR::InstId rhs_id)
  444. -> SemIR::ConstantId {
  445. auto lhs = context.insts().GetAs<SemIR::IntLiteral>(lhs_id);
  446. auto rhs = context.insts().GetAs<SemIR::IntLiteral>(rhs_id);
  447. const auto& lhs_val = context.ints().Get(lhs.int_id);
  448. const auto& rhs_val = context.ints().Get(rhs.int_id);
  449. // Check for division by zero.
  450. switch (builtin_kind) {
  451. case SemIR::BuiltinFunctionKind::IntSDiv:
  452. case SemIR::BuiltinFunctionKind::IntSMod:
  453. case SemIR::BuiltinFunctionKind::IntUDiv:
  454. case SemIR::BuiltinFunctionKind::IntUMod:
  455. if (rhs_val.isZero()) {
  456. DiagnoseDivisionByZero(context, loc);
  457. return SemIR::ConstantId::Error;
  458. }
  459. break;
  460. default:
  461. break;
  462. }
  463. bool overflow = false;
  464. llvm::APInt result_val;
  465. llvm::StringLiteral op_str = "<error>";
  466. switch (builtin_kind) {
  467. // Arithmetic.
  468. case SemIR::BuiltinFunctionKind::IntSAdd:
  469. result_val = lhs_val.sadd_ov(rhs_val, overflow);
  470. op_str = "+";
  471. break;
  472. case SemIR::BuiltinFunctionKind::IntSSub:
  473. result_val = lhs_val.ssub_ov(rhs_val, overflow);
  474. op_str = "-";
  475. break;
  476. case SemIR::BuiltinFunctionKind::IntSMul:
  477. result_val = lhs_val.smul_ov(rhs_val, overflow);
  478. op_str = "*";
  479. break;
  480. case SemIR::BuiltinFunctionKind::IntSDiv:
  481. result_val = lhs_val.sdiv_ov(rhs_val, overflow);
  482. op_str = "/";
  483. break;
  484. case SemIR::BuiltinFunctionKind::IntSMod:
  485. result_val = lhs_val.srem(rhs_val);
  486. // LLVM weirdly lacks `srem_ov`, so we work it out for ourselves:
  487. // <signed min> % -1 overflows because <signed min> / -1 overflows.
  488. overflow = lhs_val.isMinSignedValue() && rhs_val.isAllOnes();
  489. op_str = "%";
  490. break;
  491. case SemIR::BuiltinFunctionKind::IntUAdd:
  492. result_val = lhs_val + rhs_val;
  493. op_str = "+";
  494. break;
  495. case SemIR::BuiltinFunctionKind::IntUSub:
  496. result_val = lhs_val - rhs_val;
  497. op_str = "-";
  498. break;
  499. case SemIR::BuiltinFunctionKind::IntUMul:
  500. result_val = lhs_val * rhs_val;
  501. op_str = "*";
  502. break;
  503. case SemIR::BuiltinFunctionKind::IntUDiv:
  504. result_val = lhs_val.udiv(rhs_val);
  505. op_str = "/";
  506. break;
  507. case SemIR::BuiltinFunctionKind::IntUMod:
  508. result_val = lhs_val.urem(rhs_val);
  509. op_str = "%";
  510. break;
  511. // Bitwise.
  512. case SemIR::BuiltinFunctionKind::IntAnd:
  513. result_val = lhs_val & rhs_val;
  514. op_str = "&";
  515. break;
  516. case SemIR::BuiltinFunctionKind::IntOr:
  517. result_val = lhs_val | rhs_val;
  518. op_str = "|";
  519. break;
  520. case SemIR::BuiltinFunctionKind::IntXor:
  521. result_val = lhs_val ^ rhs_val;
  522. op_str = "^";
  523. break;
  524. // Bit shift.
  525. case SemIR::BuiltinFunctionKind::IntLeftShift:
  526. case SemIR::BuiltinFunctionKind::IntRightShift:
  527. op_str = (builtin_kind == SemIR::BuiltinFunctionKind::IntLeftShift)
  528. ? llvm::StringLiteral("<<")
  529. : llvm::StringLiteral(">>");
  530. if (rhs_val.uge(lhs_val.getBitWidth()) ||
  531. (rhs_val.isNegative() && context.types().IsSignedInt(rhs.type_id))) {
  532. CARBON_DIAGNOSTIC(
  533. CompileTimeShiftOutOfRange, Error,
  534. "Shift distance not in range [0, {0}) in {1} {2} {3}.", unsigned,
  535. TypedInt, llvm::StringLiteral, TypedInt);
  536. context.emitter().Emit(loc, CompileTimeShiftOutOfRange,
  537. lhs_val.getBitWidth(),
  538. {.type = lhs.type_id, .value = lhs_val}, op_str,
  539. {.type = rhs.type_id, .value = rhs_val});
  540. // TODO: Is it useful to recover by returning 0 or -1?
  541. return SemIR::ConstantId::Error;
  542. }
  543. if (builtin_kind == SemIR::BuiltinFunctionKind::IntLeftShift) {
  544. result_val = lhs_val.shl(rhs_val);
  545. } else if (context.types().IsSignedInt(lhs.type_id)) {
  546. result_val = lhs_val.ashr(rhs_val);
  547. } else {
  548. result_val = lhs_val.lshr(rhs_val);
  549. }
  550. break;
  551. default:
  552. CARBON_FATAL() << "Unexpected operation kind.";
  553. }
  554. if (overflow) {
  555. CARBON_DIAGNOSTIC(CompileTimeIntegerOverflow, Error,
  556. "Integer overflow in calculation {0} {1} {2}.", TypedInt,
  557. llvm::StringLiteral, TypedInt);
  558. context.emitter().Emit(loc, CompileTimeIntegerOverflow,
  559. {.type = lhs.type_id, .value = lhs_val}, op_str,
  560. {.type = rhs.type_id, .value = rhs_val});
  561. }
  562. return MakeIntResult(context, lhs.type_id, std::move(result_val));
  563. }
  564. // Performs a builtin integer comparison.
  565. static auto PerformBuiltinIntComparison(Context& context,
  566. SemIR::BuiltinFunctionKind builtin_kind,
  567. SemIR::InstId lhs_id,
  568. SemIR::InstId rhs_id,
  569. SemIR::TypeId bool_type_id)
  570. -> SemIR::ConstantId {
  571. auto lhs = context.insts().GetAs<SemIR::IntLiteral>(lhs_id);
  572. const auto& lhs_val = context.ints().Get(lhs.int_id);
  573. const auto& rhs_val = context.ints().Get(
  574. context.insts().GetAs<SemIR::IntLiteral>(rhs_id).int_id);
  575. bool is_signed = context.types().IsSignedInt(lhs.type_id);
  576. bool result;
  577. switch (builtin_kind) {
  578. case SemIR::BuiltinFunctionKind::IntEq:
  579. result = (lhs_val == rhs_val);
  580. break;
  581. case SemIR::BuiltinFunctionKind::IntNeq:
  582. result = (lhs_val != rhs_val);
  583. break;
  584. case SemIR::BuiltinFunctionKind::IntLess:
  585. result = is_signed ? lhs_val.slt(rhs_val) : lhs_val.ult(rhs_val);
  586. break;
  587. case SemIR::BuiltinFunctionKind::IntLessEq:
  588. result = is_signed ? lhs_val.sle(rhs_val) : lhs_val.ule(rhs_val);
  589. break;
  590. case SemIR::BuiltinFunctionKind::IntGreater:
  591. result = is_signed ? lhs_val.sgt(rhs_val) : lhs_val.sgt(rhs_val);
  592. break;
  593. case SemIR::BuiltinFunctionKind::IntGreaterEq:
  594. result = is_signed ? lhs_val.sge(rhs_val) : lhs_val.sge(rhs_val);
  595. break;
  596. default:
  597. CARBON_FATAL() << "Unexpected operation kind.";
  598. }
  599. return MakeBoolResult(context, bool_type_id, result);
  600. }
  601. // Performs a builtin unary float -> float operation.
  602. static auto PerformBuiltinUnaryFloatOp(Context& context,
  603. SemIR::BuiltinFunctionKind builtin_kind,
  604. SemIR::InstId arg_id)
  605. -> SemIR::ConstantId {
  606. auto op = context.insts().GetAs<SemIR::FloatLiteral>(arg_id);
  607. auto op_val = context.floats().Get(op.float_id);
  608. switch (builtin_kind) {
  609. case SemIR::BuiltinFunctionKind::FloatNegate:
  610. op_val.changeSign();
  611. break;
  612. default:
  613. CARBON_FATAL() << "Unexpected builtin kind";
  614. }
  615. return MakeFloatResult(context, op.type_id, std::move(op_val));
  616. }
  617. // Performs a builtin binary float -> float operation.
  618. static auto PerformBuiltinBinaryFloatOp(Context& context,
  619. SemIR::BuiltinFunctionKind builtin_kind,
  620. SemIR::InstId lhs_id,
  621. SemIR::InstId rhs_id)
  622. -> SemIR::ConstantId {
  623. auto lhs = context.insts().GetAs<SemIR::FloatLiteral>(lhs_id);
  624. auto rhs = context.insts().GetAs<SemIR::FloatLiteral>(rhs_id);
  625. auto lhs_val = context.floats().Get(lhs.float_id);
  626. auto rhs_val = context.floats().Get(rhs.float_id);
  627. llvm::APFloat result_val(lhs_val.getSemantics());
  628. switch (builtin_kind) {
  629. case SemIR::BuiltinFunctionKind::FloatAdd:
  630. result_val = lhs_val + rhs_val;
  631. break;
  632. case SemIR::BuiltinFunctionKind::FloatSub:
  633. result_val = lhs_val - rhs_val;
  634. break;
  635. case SemIR::BuiltinFunctionKind::FloatMul:
  636. result_val = lhs_val * rhs_val;
  637. break;
  638. case SemIR::BuiltinFunctionKind::FloatDiv:
  639. result_val = lhs_val / rhs_val;
  640. break;
  641. default:
  642. CARBON_FATAL() << "Unexpected operation kind.";
  643. }
  644. return MakeFloatResult(context, lhs.type_id, std::move(result_val));
  645. }
  646. // Performs a builtin float comparison.
  647. static auto PerformBuiltinFloatComparison(
  648. Context& context, SemIR::BuiltinFunctionKind builtin_kind,
  649. SemIR::InstId lhs_id, SemIR::InstId rhs_id, SemIR::TypeId bool_type_id)
  650. -> SemIR::ConstantId {
  651. auto lhs = context.insts().GetAs<SemIR::FloatLiteral>(lhs_id);
  652. auto rhs = context.insts().GetAs<SemIR::FloatLiteral>(rhs_id);
  653. const auto& lhs_val = context.floats().Get(lhs.float_id);
  654. const auto& rhs_val = context.floats().Get(rhs.float_id);
  655. bool result;
  656. switch (builtin_kind) {
  657. case SemIR::BuiltinFunctionKind::FloatEq:
  658. result = (lhs_val == rhs_val);
  659. break;
  660. case SemIR::BuiltinFunctionKind::FloatNeq:
  661. result = (lhs_val != rhs_val);
  662. break;
  663. case SemIR::BuiltinFunctionKind::FloatLess:
  664. result = lhs_val < rhs_val;
  665. break;
  666. case SemIR::BuiltinFunctionKind::FloatLessEq:
  667. result = lhs_val <= rhs_val;
  668. break;
  669. case SemIR::BuiltinFunctionKind::FloatGreater:
  670. result = lhs_val > rhs_val;
  671. break;
  672. case SemIR::BuiltinFunctionKind::FloatGreaterEq:
  673. result = lhs_val >= rhs_val;
  674. break;
  675. default:
  676. CARBON_FATAL() << "Unexpected operation kind.";
  677. }
  678. return MakeBoolResult(context, bool_type_id, result);
  679. }
  680. // Returns a constant for a call to a builtin function.
  681. static auto MakeConstantForBuiltinCall(Context& context, SemIRLoc loc,
  682. SemIR::Call call,
  683. SemIR::BuiltinFunctionKind builtin_kind,
  684. llvm::ArrayRef<SemIR::InstId> arg_ids,
  685. Phase phase) -> SemIR::ConstantId {
  686. switch (builtin_kind) {
  687. case SemIR::BuiltinFunctionKind::None:
  688. CARBON_FATAL() << "Not a builtin function.";
  689. case SemIR::BuiltinFunctionKind::PrintInt: {
  690. // Providing a constant result would allow eliding the function call.
  691. return SemIR::ConstantId::NotConstant;
  692. }
  693. case SemIR::BuiltinFunctionKind::IntMakeType32: {
  694. return context.constant_values().Get(SemIR::InstId::BuiltinIntType);
  695. }
  696. case SemIR::BuiltinFunctionKind::IntMakeTypeSigned: {
  697. return MakeIntTypeResult(context, loc, SemIR::IntKind::Signed, arg_ids[0],
  698. phase);
  699. }
  700. case SemIR::BuiltinFunctionKind::IntMakeTypeUnsigned: {
  701. return MakeIntTypeResult(context, loc, SemIR::IntKind::Unsigned,
  702. arg_ids[0], phase);
  703. }
  704. case SemIR::BuiltinFunctionKind::FloatMakeType: {
  705. // TODO: Support a symbolic constant width.
  706. if (phase != Phase::Template) {
  707. break;
  708. }
  709. if (!ValidateFloatBitWidth(context, loc, arg_ids[0])) {
  710. return SemIR::ConstantId::Error;
  711. }
  712. return context.constant_values().Get(SemIR::InstId::BuiltinFloatType);
  713. }
  714. case SemIR::BuiltinFunctionKind::BoolMakeType: {
  715. return context.constant_values().Get(SemIR::InstId::BuiltinBoolType);
  716. }
  717. // Unary integer -> integer operations.
  718. case SemIR::BuiltinFunctionKind::IntSNegate:
  719. case SemIR::BuiltinFunctionKind::IntUNegate:
  720. case SemIR::BuiltinFunctionKind::IntComplement: {
  721. if (phase != Phase::Template) {
  722. break;
  723. }
  724. return PerformBuiltinUnaryIntOp(context, loc, builtin_kind, arg_ids[0]);
  725. }
  726. // Binary integer -> integer operations.
  727. case SemIR::BuiltinFunctionKind::IntSAdd:
  728. case SemIR::BuiltinFunctionKind::IntSSub:
  729. case SemIR::BuiltinFunctionKind::IntSMul:
  730. case SemIR::BuiltinFunctionKind::IntSDiv:
  731. case SemIR::BuiltinFunctionKind::IntSMod:
  732. case SemIR::BuiltinFunctionKind::IntUAdd:
  733. case SemIR::BuiltinFunctionKind::IntUSub:
  734. case SemIR::BuiltinFunctionKind::IntUMul:
  735. case SemIR::BuiltinFunctionKind::IntUDiv:
  736. case SemIR::BuiltinFunctionKind::IntUMod:
  737. case SemIR::BuiltinFunctionKind::IntAnd:
  738. case SemIR::BuiltinFunctionKind::IntOr:
  739. case SemIR::BuiltinFunctionKind::IntXor:
  740. case SemIR::BuiltinFunctionKind::IntLeftShift:
  741. case SemIR::BuiltinFunctionKind::IntRightShift: {
  742. if (phase != Phase::Template) {
  743. break;
  744. }
  745. return PerformBuiltinBinaryIntOp(context, loc, builtin_kind, arg_ids[0],
  746. arg_ids[1]);
  747. }
  748. // Integer comparisons.
  749. case SemIR::BuiltinFunctionKind::IntEq:
  750. case SemIR::BuiltinFunctionKind::IntNeq:
  751. case SemIR::BuiltinFunctionKind::IntLess:
  752. case SemIR::BuiltinFunctionKind::IntLessEq:
  753. case SemIR::BuiltinFunctionKind::IntGreater:
  754. case SemIR::BuiltinFunctionKind::IntGreaterEq: {
  755. if (phase != Phase::Template) {
  756. break;
  757. }
  758. return PerformBuiltinIntComparison(context, builtin_kind, arg_ids[0],
  759. arg_ids[1], call.type_id);
  760. }
  761. // Unary float -> float operations.
  762. case SemIR::BuiltinFunctionKind::FloatNegate: {
  763. if (phase != Phase::Template) {
  764. break;
  765. }
  766. return PerformBuiltinUnaryFloatOp(context, builtin_kind, arg_ids[0]);
  767. }
  768. // Binary float -> float operations.
  769. case SemIR::BuiltinFunctionKind::FloatAdd:
  770. case SemIR::BuiltinFunctionKind::FloatSub:
  771. case SemIR::BuiltinFunctionKind::FloatMul:
  772. case SemIR::BuiltinFunctionKind::FloatDiv: {
  773. if (phase != Phase::Template) {
  774. break;
  775. }
  776. return PerformBuiltinBinaryFloatOp(context, builtin_kind, arg_ids[0],
  777. arg_ids[1]);
  778. }
  779. // Float comparisons.
  780. case SemIR::BuiltinFunctionKind::FloatEq:
  781. case SemIR::BuiltinFunctionKind::FloatNeq:
  782. case SemIR::BuiltinFunctionKind::FloatLess:
  783. case SemIR::BuiltinFunctionKind::FloatLessEq:
  784. case SemIR::BuiltinFunctionKind::FloatGreater:
  785. case SemIR::BuiltinFunctionKind::FloatGreaterEq: {
  786. if (phase != Phase::Template) {
  787. break;
  788. }
  789. return PerformBuiltinFloatComparison(context, builtin_kind, arg_ids[0],
  790. arg_ids[1], call.type_id);
  791. }
  792. }
  793. return SemIR::ConstantId::NotConstant;
  794. }
  795. // Makes a constant for a call instruction.
  796. static auto MakeConstantForCall(Context& context, SemIRLoc loc,
  797. SemIR::Call call) -> SemIR::ConstantId {
  798. Phase phase = Phase::Template;
  799. // A call with an invalid argument list is used to represent an erroneous
  800. // call.
  801. //
  802. // TODO: Use a better representation for this.
  803. if (call.args_id == SemIR::InstBlockId::Invalid) {
  804. return SemIR::ConstantId::Error;
  805. }
  806. // If the callee isn't constant, this is not a constant call.
  807. if (!ReplaceFieldWithConstantValue(context, &call, &SemIR::Call::callee_id,
  808. &phase)) {
  809. return SemIR::ConstantId::NotConstant;
  810. }
  811. auto callee_function =
  812. SemIR::GetCalleeFunction(context.sem_ir(), call.callee_id);
  813. auto builtin_kind = SemIR::BuiltinFunctionKind::None;
  814. if (callee_function.function_id.is_valid()) {
  815. // Calls to builtins might be constant.
  816. builtin_kind =
  817. context.functions().Get(callee_function.function_id).builtin_kind;
  818. if (builtin_kind == SemIR::BuiltinFunctionKind::None) {
  819. // TODO: Eventually we'll want to treat some kinds of non-builtin
  820. // functions as producing constants.
  821. return SemIR::ConstantId::NotConstant;
  822. }
  823. } else {
  824. // Calls to non-functions, such as calls to generic entity names, might be
  825. // constant.
  826. }
  827. // If the arguments aren't constant, this is not a constant call.
  828. if (!ReplaceFieldWithConstantValue(context, &call, &SemIR::Call::args_id,
  829. &phase)) {
  830. return SemIR::ConstantId::NotConstant;
  831. }
  832. if (phase == Phase::UnknownDueToError) {
  833. return SemIR::ConstantId::Error;
  834. }
  835. // Handle calls to builtins.
  836. if (builtin_kind != SemIR::BuiltinFunctionKind::None) {
  837. return MakeConstantForBuiltinCall(context, loc, call, builtin_kind,
  838. context.inst_blocks().Get(call.args_id),
  839. phase);
  840. }
  841. // Look at the type of the callee for special cases: calls to generic class
  842. // and generic interface types.
  843. auto type_inst =
  844. context.types().GetAsInst(context.insts().Get(call.callee_id).type_id());
  845. CARBON_KIND_SWITCH(type_inst) {
  846. case CARBON_KIND(SemIR::GenericClassType generic_class): {
  847. auto instance_id = MakeGenericInstance(
  848. context, context.classes().Get(generic_class.class_id).generic_id,
  849. call.args_id);
  850. return MakeConstantResult(
  851. context,
  852. SemIR::ClassType{.type_id = call.type_id,
  853. .class_id = generic_class.class_id,
  854. .instance_id = instance_id},
  855. phase);
  856. }
  857. case CARBON_KIND(SemIR::GenericInterfaceType generic_interface): {
  858. auto instance_id = MakeGenericInstance(
  859. context,
  860. context.interfaces().Get(generic_interface.interface_id).generic_id,
  861. call.args_id);
  862. return MakeConstantResult(
  863. context,
  864. SemIR::InterfaceType{.type_id = call.type_id,
  865. .interface_id = generic_interface.interface_id,
  866. .instance_id = instance_id},
  867. phase);
  868. }
  869. default: {
  870. return SemIR::ConstantId::NotConstant;
  871. }
  872. }
  873. }
  874. auto TryEvalInst(Context& context, SemIR::InstId inst_id, SemIR::Inst inst)
  875. -> SemIR::ConstantId {
  876. // TODO: Ensure we have test coverage for each of these cases that can result
  877. // in a constant, once those situations are all reachable.
  878. CARBON_KIND_SWITCH(inst) {
  879. // These cases are constants if their operands are.
  880. case SemIR::AddrOf::Kind:
  881. return RebuildIfFieldsAreConstant(context, inst,
  882. &SemIR::AddrOf::lvalue_id);
  883. case CARBON_KIND(SemIR::ArrayType array_type): {
  884. return RebuildAndValidateIfFieldsAreConstant(
  885. context, inst,
  886. [&](SemIR::ArrayType result) {
  887. auto bound_id = array_type.bound_id;
  888. auto int_bound =
  889. context.insts().TryGetAs<SemIR::IntLiteral>(result.bound_id);
  890. if (!int_bound) {
  891. // TODO: Permit symbolic array bounds. This will require fixing
  892. // callers of `GetArrayBoundValue`.
  893. context.TODO(bound_id, "symbolic array bound");
  894. return false;
  895. }
  896. // TODO: We should check that the size of the resulting array type
  897. // fits in 64 bits, not just that the bound does. Should we use a
  898. // 32-bit limit for 32-bit targets?
  899. const auto& bound_val = context.ints().Get(int_bound->int_id);
  900. if (context.types().IsSignedInt(int_bound->type_id) &&
  901. bound_val.isNegative()) {
  902. CARBON_DIAGNOSTIC(ArrayBoundNegative, Error,
  903. "Array bound of {0} is negative.", TypedInt);
  904. context.emitter().Emit(
  905. bound_id, ArrayBoundNegative,
  906. {.type = int_bound->type_id, .value = bound_val});
  907. return false;
  908. }
  909. if (bound_val.getActiveBits() > 64) {
  910. CARBON_DIAGNOSTIC(ArrayBoundTooLarge, Error,
  911. "Array bound of {0} is too large.", TypedInt);
  912. context.emitter().Emit(
  913. bound_id, ArrayBoundTooLarge,
  914. {.type = int_bound->type_id, .value = bound_val});
  915. return false;
  916. }
  917. return true;
  918. },
  919. &SemIR::ArrayType::bound_id, &SemIR::ArrayType::element_type_id);
  920. }
  921. case SemIR::AssociatedEntityType::Kind:
  922. return RebuildIfFieldsAreConstant(
  923. context, inst, &SemIR::AssociatedEntityType::entity_type_id);
  924. case SemIR::BoundMethod::Kind:
  925. return RebuildIfFieldsAreConstant(context, inst,
  926. &SemIR::BoundMethod::object_id,
  927. &SemIR::BoundMethod::function_id);
  928. case SemIR::ClassType::Kind:
  929. return RebuildIfFieldsAreConstant(context, inst,
  930. &SemIR::ClassType::instance_id);
  931. case SemIR::InterfaceType::Kind:
  932. return RebuildIfFieldsAreConstant(context, inst,
  933. &SemIR::InterfaceType::instance_id);
  934. case SemIR::InterfaceWitness::Kind:
  935. return RebuildIfFieldsAreConstant(context, inst,
  936. &SemIR::InterfaceWitness::elements_id);
  937. case CARBON_KIND(SemIR::IntType int_type): {
  938. return RebuildAndValidateIfFieldsAreConstant(
  939. context, inst,
  940. [&](SemIR::IntType result) {
  941. return ValidateIntType(context, int_type.bit_width_id, result);
  942. },
  943. &SemIR::IntType::bit_width_id);
  944. }
  945. case SemIR::PointerType::Kind:
  946. return RebuildIfFieldsAreConstant(context, inst,
  947. &SemIR::PointerType::pointee_id);
  948. case CARBON_KIND(SemIR::FloatType float_type): {
  949. return RebuildAndValidateIfFieldsAreConstant(
  950. context, inst,
  951. [&](SemIR::FloatType result) {
  952. return ValidateFloatType(context, float_type.bit_width_id, result);
  953. },
  954. &SemIR::FloatType::bit_width_id);
  955. }
  956. case SemIR::StructType::Kind:
  957. return RebuildIfFieldsAreConstant(context, inst,
  958. &SemIR::StructType::fields_id);
  959. case SemIR::StructTypeField::Kind:
  960. return RebuildIfFieldsAreConstant(context, inst,
  961. &SemIR::StructTypeField::field_type_id);
  962. case SemIR::StructValue::Kind:
  963. return RebuildIfFieldsAreConstant(context, inst,
  964. &SemIR::StructValue::elements_id);
  965. case SemIR::TupleType::Kind:
  966. return RebuildIfFieldsAreConstant(context, inst,
  967. &SemIR::TupleType::elements_id);
  968. case SemIR::TupleValue::Kind:
  969. return RebuildIfFieldsAreConstant(context, inst,
  970. &SemIR::TupleValue::elements_id);
  971. case SemIR::UnboundElementType::Kind:
  972. return RebuildIfFieldsAreConstant(
  973. context, inst, &SemIR::UnboundElementType::class_type_id,
  974. &SemIR::UnboundElementType::element_type_id);
  975. // Initializers evaluate to a value of the object representation.
  976. case SemIR::ArrayInit::Kind:
  977. // TODO: Add an `ArrayValue` to represent a constant array object
  978. // representation instead of using a `TupleValue`.
  979. return RebuildInitAsValue(context, inst, SemIR::TupleValue::Kind);
  980. case SemIR::ClassInit::Kind:
  981. // TODO: Add a `ClassValue` to represent a constant class object
  982. // representation instead of using a `StructValue`.
  983. return RebuildInitAsValue(context, inst, SemIR::StructValue::Kind);
  984. case SemIR::StructInit::Kind:
  985. return RebuildInitAsValue(context, inst, SemIR::StructValue::Kind);
  986. case SemIR::TupleInit::Kind:
  987. return RebuildInitAsValue(context, inst, SemIR::TupleValue::Kind);
  988. case SemIR::AssociatedEntity::Kind:
  989. case SemIR::Builtin::Kind:
  990. case SemIR::FunctionType::Kind:
  991. case SemIR::GenericClassType::Kind:
  992. case SemIR::GenericInterfaceType::Kind:
  993. // Builtins are always template constants.
  994. return MakeConstantResult(context, inst, Phase::Template);
  995. case CARBON_KIND(SemIR::FunctionDecl fn_decl): {
  996. return MakeConstantResult(
  997. context,
  998. SemIR::StructValue{.type_id = fn_decl.type_id,
  999. .elements_id = SemIR::InstBlockId::Empty},
  1000. GetTypePhase(context, fn_decl.type_id));
  1001. }
  1002. case CARBON_KIND(SemIR::ClassDecl class_decl): {
  1003. // If the class has generic parameters, we don't produce a class type, but
  1004. // a callable whose return value is a class type.
  1005. if (context.classes().Get(class_decl.class_id).is_generic()) {
  1006. return MakeConstantResult(
  1007. context,
  1008. SemIR::StructValue{.type_id = class_decl.type_id,
  1009. .elements_id = SemIR::InstBlockId::Empty},
  1010. GetTypePhase(context, class_decl.type_id));
  1011. }
  1012. // A non-generic class declaration evaluates to the class type.
  1013. return MakeConstantResult(
  1014. context,
  1015. SemIR::ClassType{.type_id = SemIR::TypeId::TypeType,
  1016. .class_id = class_decl.class_id,
  1017. .instance_id = SemIR::GenericInstanceId::Invalid},
  1018. Phase::Template);
  1019. }
  1020. case CARBON_KIND(SemIR::InterfaceDecl interface_decl): {
  1021. // If the interface has generic parameters, we don't produce an interface
  1022. // type, but a callable whose return value is an interface type.
  1023. if (context.interfaces().Get(interface_decl.interface_id).is_generic()) {
  1024. return MakeConstantResult(
  1025. context,
  1026. SemIR::StructValue{.type_id = interface_decl.type_id,
  1027. .elements_id = SemIR::InstBlockId::Empty},
  1028. GetTypePhase(context, interface_decl.type_id));
  1029. }
  1030. // A non-generic interface declaration evaluates to the interface type.
  1031. return MakeConstantResult(
  1032. context,
  1033. SemIR::InterfaceType{
  1034. .type_id = SemIR::TypeId::TypeType,
  1035. .interface_id = interface_decl.interface_id,
  1036. .instance_id = SemIR::GenericInstanceId::Invalid},
  1037. Phase::Template);
  1038. }
  1039. // These cases are treated as being the unique canonical definition of the
  1040. // corresponding constant value.
  1041. // TODO: This doesn't properly handle redeclarations. Consider adding a
  1042. // corresponding `Value` inst for each of these cases.
  1043. case SemIR::AssociatedConstantDecl::Kind:
  1044. case SemIR::BaseDecl::Kind:
  1045. case SemIR::FieldDecl::Kind:
  1046. case SemIR::Namespace::Kind:
  1047. return SemIR::ConstantId::ForTemplateConstant(inst_id);
  1048. case SemIR::BoolLiteral::Kind:
  1049. case SemIR::FloatLiteral::Kind:
  1050. case SemIR::IntLiteral::Kind:
  1051. case SemIR::RealLiteral::Kind:
  1052. case SemIR::StringLiteral::Kind:
  1053. // Promote literals to the constant block.
  1054. // TODO: Convert literals into a canonical form. Currently we can form two
  1055. // different `i32` constants with the same value if they are represented
  1056. // by `APInt`s with different bit widths.
  1057. return MakeConstantResult(context, inst, Phase::Template);
  1058. // The elements of a constant aggregate can be accessed.
  1059. case SemIR::ClassElementAccess::Kind:
  1060. case SemIR::InterfaceWitnessAccess::Kind:
  1061. case SemIR::StructAccess::Kind:
  1062. case SemIR::TupleAccess::Kind:
  1063. return PerformAggregateAccess(context, inst);
  1064. case SemIR::ArrayIndex::Kind:
  1065. case SemIR::TupleIndex::Kind:
  1066. return PerformAggregateIndex(context, inst);
  1067. case CARBON_KIND(SemIR::Call call): {
  1068. return MakeConstantForCall(context, inst_id, call);
  1069. }
  1070. // TODO: These need special handling.
  1071. case SemIR::BindValue::Kind:
  1072. case SemIR::Deref::Kind:
  1073. case SemIR::ImportRefLoaded::Kind:
  1074. case SemIR::Temporary::Kind:
  1075. case SemIR::TemporaryStorage::Kind:
  1076. case SemIR::ValueAsRef::Kind:
  1077. break;
  1078. case CARBON_KIND(SemIR::BindSymbolicName bind): {
  1079. // The constant form of a symbolic binding is an idealized form of the
  1080. // original, with no equivalent value.
  1081. bind.bind_name_id = context.bind_names().MakeCanonical(bind.bind_name_id);
  1082. bind.value_id = SemIR::InstId::Invalid;
  1083. return MakeConstantResult(context, bind, Phase::Symbolic);
  1084. }
  1085. // These semantic wrappers don't change the constant value.
  1086. case CARBON_KIND(SemIR::AsCompatible inst): {
  1087. return context.constant_values().Get(inst.source_id);
  1088. }
  1089. case CARBON_KIND(SemIR::BindAlias typed_inst): {
  1090. return context.constant_values().Get(typed_inst.value_id);
  1091. }
  1092. case CARBON_KIND(SemIR::ExportDecl typed_inst): {
  1093. return context.constant_values().Get(typed_inst.value_id);
  1094. }
  1095. case CARBON_KIND(SemIR::NameRef typed_inst): {
  1096. return context.constant_values().Get(typed_inst.value_id);
  1097. }
  1098. case CARBON_KIND(SemIR::Converted typed_inst): {
  1099. return context.constant_values().Get(typed_inst.result_id);
  1100. }
  1101. case CARBON_KIND(SemIR::InitializeFrom typed_inst): {
  1102. return context.constant_values().Get(typed_inst.src_id);
  1103. }
  1104. case CARBON_KIND(SemIR::SpliceBlock typed_inst): {
  1105. return context.constant_values().Get(typed_inst.result_id);
  1106. }
  1107. case CARBON_KIND(SemIR::ValueOfInitializer typed_inst): {
  1108. return context.constant_values().Get(typed_inst.init_id);
  1109. }
  1110. case CARBON_KIND(SemIR::FacetTypeAccess typed_inst): {
  1111. // TODO: Once we start tracking the witness in the facet value, remove it
  1112. // here. For now, we model a facet value as just a type.
  1113. return context.constant_values().Get(typed_inst.facet_id);
  1114. }
  1115. // `not true` -> `false`, `not false` -> `true`.
  1116. // All other uses of unary `not` are non-constant.
  1117. case CARBON_KIND(SemIR::UnaryOperatorNot typed_inst): {
  1118. auto const_id = context.constant_values().Get(typed_inst.operand_id);
  1119. auto phase = GetPhase(const_id);
  1120. if (phase == Phase::Template) {
  1121. auto value = context.insts().GetAs<SemIR::BoolLiteral>(
  1122. context.constant_values().GetInstId(const_id));
  1123. return MakeBoolResult(context, value.type_id, !value.value.ToBool());
  1124. }
  1125. if (phase == Phase::UnknownDueToError) {
  1126. return SemIR::ConstantId::Error;
  1127. }
  1128. break;
  1129. }
  1130. // `const (const T)` evaluates to `const T`. Otherwise, `const T` evaluates
  1131. // to itself.
  1132. case CARBON_KIND(SemIR::ConstType typed_inst): {
  1133. auto inner_id = context.constant_values().Get(
  1134. context.types().GetInstId(typed_inst.inner_id));
  1135. if (inner_id.is_constant() &&
  1136. context.insts()
  1137. .Get(context.constant_values().GetInstId(inner_id))
  1138. .Is<SemIR::ConstType>()) {
  1139. return inner_id;
  1140. }
  1141. return MakeConstantResult(context, inst, GetPhase(inner_id));
  1142. }
  1143. // These cases are either not expressions or not constant.
  1144. case SemIR::AdaptDecl::Kind:
  1145. case SemIR::AddrPattern::Kind:
  1146. case SemIR::Assign::Kind:
  1147. case SemIR::BindName::Kind:
  1148. case SemIR::BlockArg::Kind:
  1149. case SemIR::Branch::Kind:
  1150. case SemIR::BranchIf::Kind:
  1151. case SemIR::BranchWithArg::Kind:
  1152. case SemIR::ImplDecl::Kind:
  1153. case SemIR::Param::Kind:
  1154. case SemIR::ReturnExpr::Kind:
  1155. case SemIR::Return::Kind:
  1156. case SemIR::StructLiteral::Kind:
  1157. case SemIR::TupleLiteral::Kind:
  1158. case SemIR::VarStorage::Kind:
  1159. break;
  1160. case SemIR::ImportRefUnloaded::Kind:
  1161. CARBON_FATAL()
  1162. << "ImportRefUnloaded should be loaded before TryEvalInst.";
  1163. }
  1164. return SemIR::ConstantId::NotConstant;
  1165. }
  1166. } // namespace Carbon::Check