Skip to content

Commit 3831ca6

Browse files
authored
Replace the desugared bit with an extra LocId range (#5592)
This is to reduce the space consumption of the bit which only applies to NodeId, and it also simplifies logic related to ImportIRInstId by removing the need for index_without_flags.
1 parent 493bea1 commit 3831ca6

File tree

2 files changed

+33
-36
lines changed

2 files changed

+33
-36
lines changed

toolchain/sem_ir/ids.h

Lines changed: 24 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -834,11 +834,9 @@ struct ImportIRInstId : public IdBase<ImportIRInstId> {
834834
static constexpr llvm::StringLiteral Label = "import_ir_inst";
835835
using ValueType = ImportIRInst;
836836

837-
// ImportIRInstId is restricted so that it can fit into LocId.
838-
static constexpr int BitsWithNodeId = 30;
839-
840-
// The maximum ID, non-inclusive.
841-
static constexpr int Max = (1 << BitsWithNodeId) - Parse::NodeId::Max - 2;
837+
// The maximum ID, non-inclusive. This is constrained to fit inside LocId.
838+
static constexpr int Max =
839+
-(std::numeric_limits<int32_t>::min() + 2 * Parse::NodeId::Max + 1);
842840

843841
constexpr explicit ImportIRInstId(int32_t index) : IdBase(index) {
844842
CARBON_DCHECK(index < Max, "Index out of range: {0}", index);
@@ -852,16 +850,15 @@ struct ImportIRInstId : public IdBase<ImportIRInstId> {
852850
//
853851
// The structure is:
854852
// - None: The standard NoneIndex for all Id types, -1.
855-
// - InstId: positive values including zero; a full 31 bits.
853+
// - InstId: Positive values including zero; a full 31 bits.
856854
// - [0, 1 << 31)
857-
// - NodeId: negative values starting after None; the 24 bit NodeId range.
855+
// - NodeId: Negative values starting after None; the 24 bit NodeId range.
858856
// - [-2, -2 - (1 << 24))
859-
// - ImportIRInstId: remaining negative values; after NodeId, fills out negative
860-
// values to 30 bits.
861-
// - [-2 - (1 << 24), -(1 << 30))
862-
//
863-
// In addition, one bit is used for flags: `DesugaredBit`.
864-
// Note that this can only be used with negative, non-`InstId` values.
857+
// - Desugared NodeId: Another 24 bit NodeId range.
858+
// - [-2 - (1 << 24), -2 - (1 << 25))
859+
// - ImportIRInstId: Remaining negative values; after NodeId, fills out negative
860+
// values.
861+
// - [-2 - (1 << 25), -(1 << 31)]
865862
//
866863
// For desugaring, use `InstStore::GetLocIdForDesugaring()`.
867864
struct LocId : public IdBase<LocId> {
@@ -897,10 +894,9 @@ struct LocId : public IdBase<LocId> {
897894
auto AsDesugared() const -> LocId {
898895
// This should only be called for NodeId or ImportIRInstId (i.e. canonical
899896
// locations), but we only set the flag for NodeId.
900-
CARBON_CHECK(kind() != Kind::InstId,
901-
"Use InstStore::GetLocIdForDesugaring");
902-
if (kind() == Kind::NodeId) {
903-
return LocId(index & ~DesugaredBit);
897+
CARBON_CHECK(kind() != Kind::InstId, "Use InstStore::GetDesugaredLocId");
898+
if (index <= FirstNodeId && index > FirstDesugaredNodeId) {
899+
return LocId(index - Parse::NodeId::Max);
904900
}
905901
return *this;
906902
}
@@ -913,7 +909,7 @@ struct LocId : public IdBase<LocId> {
913909
if (index >= 0) {
914910
return Kind::InstId;
915911
}
916-
if (index_without_flags() <= FirstImportIRInstId) {
912+
if (index <= FirstImportIRInstId) {
917913
return Kind::ImportIRInstId;
918914
}
919915
return Kind::NodeId;
@@ -922,7 +918,7 @@ struct LocId : public IdBase<LocId> {
922918
// Returns true if the location corresponds to desugared instructions.
923919
// Requires a non-`InstId` location.
924920
auto is_desugared() const -> bool {
925-
return (kind() == Kind::NodeId) && (index & DesugaredBit) == 0;
921+
return index <= FirstDesugaredNodeId && index > FirstImportIRInstId;
926922
}
927923

928924
// Returns the equivalent `ImportIRInstId` when `kind()` matches or is `None`.
@@ -934,7 +930,7 @@ struct LocId : public IdBase<LocId> {
934930
return ImportIRInstId::None;
935931
}
936932
CARBON_CHECK(kind() == Kind::ImportIRInstId, "{0}", index);
937-
return ImportIRInstId(FirstImportIRInstId - index_without_flags());
933+
return ImportIRInstId(FirstImportIRInstId - index);
938934
}
939935

940936
// Returns the equivalent `InstId` when `kind()` matches or is `None`.
@@ -949,25 +945,22 @@ struct LocId : public IdBase<LocId> {
949945
return Parse::NodeId::None;
950946
}
951947
CARBON_CHECK(kind() == Kind::NodeId, "{0}", index);
952-
return Parse::NodeId(FirstNodeId - index_without_flags());
948+
if (index <= FirstDesugaredNodeId) {
949+
return Parse::NodeId(FirstDesugaredNodeId - index);
950+
} else {
951+
return Parse::NodeId(FirstNodeId - index);
952+
}
953953
}
954954

955955
auto Print(llvm::raw_ostream& out) const -> void;
956956

957957
private:
958-
// Whether a location corresponds to desugared instructions. This only applies
959-
// for `NodeId`.
960-
static constexpr int32_t DesugaredBit = 1 << 30;
961-
962958
// The value of the 0 index for each of `NodeId` and `ImportIRInstId`.
963959
static constexpr int32_t FirstNodeId = NoneIndex - 1;
964-
static constexpr int32_t FirstImportIRInstId =
960+
static constexpr int32_t FirstDesugaredNodeId =
965961
FirstNodeId - Parse::NodeId::Max;
966-
967-
auto index_without_flags() const -> int32_t {
968-
CARBON_DCHECK(index < NoneIndex, "Only for NodeId and ImportIRInstId");
969-
return index | DesugaredBit;
970-
}
962+
static constexpr int32_t FirstImportIRInstId =
963+
FirstDesugaredNodeId - Parse::NodeId::Max;
971964
};
972965

973966
// Polymorphic id for fields in `Any[...]` typed instruction category. Used for

toolchain/sem_ir/ids_test.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,17 @@ TEST(IdsTest, LocIdValues) {
2424
static_cast<LocId>(InstId(std::numeric_limits<int32_t>::max())).index,
2525
Eq(std::numeric_limits<int32_t>::max()));
2626

27-
EXPECT_THAT(static_cast<LocId>(Parse::NodeId(0)).index, Eq(-2));
28-
EXPECT_THAT(static_cast<LocId>(Parse::NodeId(Parse::NodeId::Max - 1)).index,
29-
Eq(-2 - (1 << 24) + 1));
27+
auto min_node_id = static_cast<LocId>(Parse::NodeId(0));
28+
EXPECT_THAT(min_node_id.index, Eq(-2));
29+
EXPECT_THAT(min_node_id.AsDesugared().index, Eq(-2 - (1 << 24)));
3030

31-
EXPECT_THAT(static_cast<LocId>(ImportIRInstId(0)).index, Eq(-2 - (1 << 24)));
31+
auto max_node_id = static_cast<LocId>(Parse::NodeId(Parse::NodeId::Max - 1));
32+
EXPECT_THAT(max_node_id.index, Eq(-2 - (1 << 24) + 1));
33+
EXPECT_THAT(max_node_id.AsDesugared().index, Eq(-2 - (1 << 25) + 1));
34+
35+
EXPECT_THAT(static_cast<LocId>(ImportIRInstId(0)).index, Eq(-2 - (1 << 25)));
3236
EXPECT_THAT(static_cast<LocId>(ImportIRInstId(ImportIRInstId::Max - 1)).index,
33-
Eq(-(1 << 30) + 1));
37+
Eq(std::numeric_limits<int32_t>::min()));
3438
}
3539

3640
// A standard parameterized test for (is_desugared, index).

0 commit comments

Comments
 (0)