Просмотр исходного кода

Factor out `GetInstWithConstantValue` and use it from another place that duplicates the same logic. (#5388)

Richard Smith 1 год назад
Родитель
Сommit
5226f3d14a

+ 0 - 29
toolchain/check/import_ref.cpp

@@ -152,35 +152,6 @@ auto VerifySameCanonicalImportIRInst(Context& context, SemIR::NameId name_id,
                         SemIR::LocId(prev_id));
 }
 
-// Returns an instruction that has the specified constant value.
-static auto GetInstWithConstantValue(const SemIR::File& file,
-                                     SemIR::ConstantId const_id)
-    -> SemIR::InstId {
-  if (!const_id.has_value()) {
-    return SemIR::InstId::None;
-  }
-
-  // For concrete constants, the corresponding instruction has the desired
-  // constant value.
-  if (!const_id.is_symbolic()) {
-    return file.constant_values().GetInstId(const_id);
-  }
-
-  // For abstract symbolic constants, the corresponding instruction has the
-  // desired constant value.
-  const auto& symbolic_const =
-      file.constant_values().GetSymbolicConstant(const_id);
-  if (!symbolic_const.generic_id.has_value()) {
-    return file.constant_values().GetInstId(const_id);
-  }
-
-  // For a symbolic constant in a generic, pick the corresponding instruction
-  // out of the eval block for the generic.
-  const auto& generic = file.generics().Get(symbolic_const.generic_id);
-  auto block = generic.GetEvalBlock(symbolic_const.index.region());
-  return file.inst_blocks().Get(block)[symbolic_const.index.index()];
-}
-
 namespace {
 class ImportRefResolver;
 

+ 27 - 0
toolchain/sem_ir/constant.cpp

@@ -36,4 +36,31 @@ auto ConstantStore::GetOrAdd(Inst inst, ConstantDependence dependence)
   return result.value();
 }
 
+auto GetInstWithConstantValue(const SemIR::File& file,
+                              SemIR::ConstantId const_id) -> SemIR::InstId {
+  if (!const_id.has_value() || !const_id.is_constant()) {
+    return SemIR::InstId::None;
+  }
+
+  // For concrete constants, the corresponding instruction has the desired
+  // constant value.
+  if (!const_id.is_symbolic()) {
+    return file.constant_values().GetInstId(const_id);
+  }
+
+  // For unattached symbolic constants, the corresponding instruction has the
+  // desired constant value.
+  const auto& symbolic_const =
+      file.constant_values().GetSymbolicConstant(const_id);
+  if (!symbolic_const.generic_id.has_value()) {
+    return file.constant_values().GetInstId(const_id);
+  }
+
+  // For attached symbolic constants, pick the corresponding instruction out of
+  // the eval block for the generic.
+  const auto& generic = file.generics().Get(symbolic_const.generic_id);
+  auto block = generic.GetEvalBlock(symbolic_const.index.region());
+  return file.inst_blocks().Get(block)[symbolic_const.index.index()];
+}
+
 }  // namespace Carbon::SemIR

+ 9 - 0
toolchain/sem_ir/constant.h

@@ -187,6 +187,15 @@ class ConstantValueStore {
   llvm::SmallVector<SymbolicConstant, 0> symbolic_constants_;
 };
 
+// Given a constant ID, returns an instruction that has that constant value.
+// For an unattached constant, the returned instruction is the instruction that
+// defines the constant; for an attached constant, this is the instruction in
+// the eval block that computes the constant value in each specific.
+//
+// Returns InstId::None if the ConstantId is None or NotConstant.
+auto GetInstWithConstantValue(const SemIR::File& file,
+                              SemIR::ConstantId const_id) -> SemIR::InstId;
+
 // Provides storage for instructions representing deduplicated global constants.
 class ConstantStore {
  public:

+ 12 - 17
toolchain/sem_ir/formatter.cpp

@@ -1271,24 +1271,19 @@ auto Formatter::FormatConstant(ConstantId id) -> void {
     return;
   }
 
-  // For a symbolic constant in a generic, list the constant value in the
-  // generic first, and the canonical constant second.
-  if (id.is_symbolic()) {
-    const auto& symbolic_constant =
-        sem_ir_->constant_values().GetSymbolicConstant(id);
-    if (symbolic_constant.generic_id.has_value()) {
-      const auto& generic =
-          sem_ir_->generics().Get(symbolic_constant.generic_id);
-      FormatName(sem_ir_->inst_blocks().Get(generic.GetEvalBlock(
-          symbolic_constant.index.region()))[symbolic_constant.index.index()]);
-      out_ << " (";
-      FormatName(sem_ir_->constant_values().GetInstId(id));
-      out_ << ")";
-      return;
-    }
-  }
+  auto inst_id = GetInstWithConstantValue(*sem_ir_, id);
+  FormatName(inst_id);
 
-  FormatName(sem_ir_->constant_values().GetInstId(id));
+  // For an attached constant, also list the unattached constant.
+  if (id.is_symbolic() && sem_ir_->constant_values()
+                              .GetSymbolicConstant(id)
+                              .generic_id.has_value()) {
+    // TODO: Skip printing this if it's the same as `inst_id`.
+    auto unattached_inst_id = sem_ir_->constant_values().GetInstId(id);
+    out_ << " (";
+    FormatName(unattached_inst_id);
+    out_ << ")";
+  }
 }
 
 auto Formatter::FormatInstAsType(InstId id) -> void {