forked from carbon-language/carbon-lang
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add framework for singleton instructions. (carbon-language#4582)
Adds a singleton framework, and converts `File` and `InstId::Print` to demonstrate functionality. Moves various functions from `ids.h` to `ids.cpp` because `Inst::Print` needs the file if `singleton_insts.h` is split out, so the small bit of cleanup feels consistent. I added `Inst::MakeSingleton` because getting the type of the instruction to make from an `InstKind` felt too hard. Singleton instructions follow a basic structure, so I'm just putting that instruction structure into `Inst`. Previously we required macros to do this, and I'm trying to remove macro dependencies. I'm trying to remove builtin/singleton-related functionality from `InstId` in order to get a clearer boundary for the functionality. The other builtin functions should be removed as part of the bigger migration, but I'm trying to carefully scope changes to verify agreement on the singleton approach in use first. This provides `InstT::SingletonInstId` because that'll often be written as `SemIR::TypeType::SingletonInstId`. The alternative of something like `SemIR::SingletonInstId<SemIR::TypeType>` is just a little more verbose due to the repeated `SemIR`, and it's more consistent with `TypeType::Kind`. An alternative I considered was consolidating singleton information to `InstKind`. This felt challenging because of the `InstId::BuiltinTypeType` and similar values. Maintaining those would turn into something like `InstKind::IsSingleton()` and `InstId::Singleton<TypeType>`, which didn't feel like as good a split. `InstId::Print` remains aware of singletons, but I'm hoping to remove other builtin-related calls from `InstId`. Another thing I considered was adding `.is_singleton = true` to `InstKind::Definition`. I don't think we could rely on that to get `InstId::Singleton<TypeType>` set up as `constexpr`, though. At that point, I think it'd mainly be _just_ a comment-like annotation, maybe validated with `CHECK` but not having any effect on its own. So I decided not to do that, just adding comments instead. Sidenotes: - "singleton" naming was discussed [on #toolchain](https://discord.com/channels/655572317891461132/655578254970716160/1308870233729269781). - The TODO in file.h about possibly excluding other things than singletons seems moot. That's for raw IR, and we're much more focused on textual IR these days. --------- Co-authored-by: David Blaikie <[email protected]> Co-authored-by: Dana Jansens <[email protected]> Co-authored-by: Richard Smith <[email protected]> Co-authored-by: josh11b <[email protected]> Co-authored-by: Josh L <[email protected]> Co-authored-by: Chandler Carruth <[email protected]> Co-authored-by: Carbon Infra Bot <[email protected]> Co-authored-by: Boaz Brickner <[email protected]> Co-authored-by: Geoff Romer <[email protected]>
- Loading branch information
1 parent
d434828
commit f45cbc6
Showing
11 changed files
with
345 additions
and
233 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM | ||
// Exceptions. See /LICENSE for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
||
#include "toolchain/sem_ir/ids.h" | ||
|
||
#include "toolchain/sem_ir/singleton_insts.h" | ||
|
||
namespace Carbon::SemIR { | ||
|
||
auto InstId::Print(llvm::raw_ostream& out) const -> void { | ||
out << "inst"; | ||
if (!is_valid()) { | ||
IdBase::Print(out); | ||
} else if (is_builtin()) { | ||
out << builtin_inst_kind(); | ||
} else { | ||
// Use the `+` as a small reminder that this is a delta, rather than an | ||
// absolute index. | ||
out << "+" << index - SingletonInstKinds.size(); | ||
} | ||
} | ||
|
||
auto ConstantId::Print(llvm::raw_ostream& out, bool disambiguate) const | ||
-> void { | ||
if (!is_valid()) { | ||
IdBase::Print(out); | ||
} else if (is_template()) { | ||
if (disambiguate) { | ||
out << "templateConstant("; | ||
} | ||
out << template_inst_id(); | ||
if (disambiguate) { | ||
out << ")"; | ||
} | ||
} else if (is_symbolic()) { | ||
out << "symbolicConstant" << symbolic_index(); | ||
} else { | ||
out << "runtime"; | ||
} | ||
} | ||
|
||
auto RuntimeParamIndex::Print(llvm::raw_ostream& out) const -> void { | ||
out << "runtime_param"; | ||
if (*this == Unknown) { | ||
out << "<unknown>"; | ||
} else { | ||
IndexBase::Print(out); | ||
} | ||
} | ||
|
||
auto GenericInstIndex::Print(llvm::raw_ostream& out) const -> void { | ||
out << "genericInst"; | ||
if (is_valid()) { | ||
out << (region() == Declaration ? "InDecl" : "InDef") << index(); | ||
} else { | ||
out << "<invalid>"; | ||
} | ||
} | ||
|
||
auto BoolValue::Print(llvm::raw_ostream& out) const -> void { | ||
if (*this == False) { | ||
out << "false"; | ||
} else if (*this == True) { | ||
out << "true"; | ||
} else { | ||
CARBON_FATAL("Invalid bool value {0}", index); | ||
} | ||
} | ||
|
||
auto IntKind::Print(llvm::raw_ostream& out) const -> void { | ||
if (*this == Unsigned) { | ||
out << "unsigned"; | ||
} else if (*this == Signed) { | ||
out << "signed"; | ||
} else { | ||
CARBON_FATAL("Invalid int kind value {0}", index); | ||
} | ||
} | ||
|
||
auto NameId::ForIdentifier(IdentifierId id) -> NameId { | ||
if (id.index >= 0) { | ||
return NameId(id.index); | ||
} else if (!id.is_valid()) { | ||
return NameId::Invalid; | ||
} else { | ||
CARBON_FATAL("Unexpected identifier ID {0}", id); | ||
} | ||
} | ||
|
||
auto NameId::Print(llvm::raw_ostream& out) const -> void { | ||
out << "name"; | ||
if (*this == SelfValue) { | ||
out << "SelfValue"; | ||
} else if (*this == SelfType) { | ||
out << "SelfType"; | ||
} else if (*this == PeriodSelf) { | ||
out << "PeriodSelf"; | ||
} else if (*this == ReturnSlot) { | ||
out << "ReturnSlot"; | ||
} else if (*this == PackageNamespace) { | ||
out << "PackageNamespace"; | ||
} else if (*this == Base) { | ||
out << "Base"; | ||
} else { | ||
CARBON_CHECK(!is_valid() || index >= 0, "Unknown index {0}", index); | ||
IdBase::Print(out); | ||
} | ||
} | ||
|
||
auto InstBlockId::Print(llvm::raw_ostream& out) const -> void { | ||
if (*this == Unreachable) { | ||
out << "unreachable"; | ||
} else if (*this == Empty) { | ||
out << "empty"; | ||
} else if (*this == Exports) { | ||
out << "exports"; | ||
} else if (*this == ImportRefs) { | ||
out << "import_refs"; | ||
} else if (*this == GlobalInit) { | ||
out << "global_init"; | ||
} else { | ||
out << "block"; | ||
IdBase::Print(out); | ||
} | ||
} | ||
|
||
auto TypeId::Print(llvm::raw_ostream& out) const -> void { | ||
out << "type"; | ||
if (*this == TypeType) { | ||
out << "TypeType"; | ||
} else if (*this == AutoType) { | ||
out << "AutoType"; | ||
} else if (*this == Error) { | ||
out << "Error"; | ||
} else { | ||
out << "("; | ||
AsConstantId().Print(out, /*disambiguate=*/false); | ||
out << ")"; | ||
} | ||
} | ||
|
||
auto LibraryNameId::ForStringLiteralValueId(StringLiteralValueId id) | ||
-> LibraryNameId { | ||
CARBON_CHECK(id.index >= InvalidIndex, "Unexpected library name ID {0}", id); | ||
if (id == StringLiteralValueId::Invalid) { | ||
// Prior to SemIR, we use invalid to indicate `default`. | ||
return LibraryNameId::Default; | ||
} else { | ||
return LibraryNameId(id.index); | ||
} | ||
} | ||
|
||
auto LibraryNameId::Print(llvm::raw_ostream& out) const -> void { | ||
out << "libraryName"; | ||
if (*this == Default) { | ||
out << "Default"; | ||
} else if (*this == Error) { | ||
out << "<error>"; | ||
} else { | ||
IdBase::Print(out); | ||
} | ||
} | ||
|
||
auto LocId::Print(llvm::raw_ostream& out) const -> void { | ||
out << "loc_"; | ||
if (is_node_id() || !is_valid()) { | ||
out << node_id(); | ||
} else { | ||
out << import_ir_inst_id(); | ||
} | ||
} | ||
|
||
} // namespace Carbon::SemIR |
Oops, something went wrong.