mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-11-10 12:28:25 +00:00
Make tag application and removal a compile time property (#8042)
For stores with untagged ID types, `Apply` and `Remove` still did (some) of the work, despite the fact that it could never be needed. Because both depend on runtime parts of the class, we need to explicitly check whether the store's IDs are tagged at compile time with `if constexpr`. This is important because the hottest value stores aren't tagged, and we get significant performance uplift in lexing and parsing. Benchmark results (./scripts/bench_runner.py --runs=12, -march=x86-64-v3): - BM_CompileApiFileDenseDecls<Lang::Carbon, Phase::Lex>/65536: CPU Time: -4.713% - BM_CompileApiFileDenseDecls<Lang::Carbon, Phase::Parse>/65536: CPU Time: -7.251% - BM_CompileImplFile<Lang::Carbon, Phase::Lex>/65536: CPU Time: -8.016% - BM_CompileImplFile<Lang::Carbon, Phase::Parse>/65536: CPU Time: -9.477% Assisted-by: Antigravity with various models --------- Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com>
This commit is contained in:
1 parent
5f1dd4941a
commit
4c5734a8cc
1 file changed
+26
-14
+26
-14
@@ -68,28 +68,40 @@ struct IdTag {
|
||||
|
||||
auto Apply(int32_t index) const -> IdT {
|
||||
CARBON_DCHECK(index >= 0, "{0}", index);
|
||||
if (index < initial_reserved_ids_) {
|
||||
if constexpr (IdTagIsUntagged<IdTag>) {
|
||||
// Untagged ids are the index itself, so return directly with no tag
|
||||
// computation.
|
||||
return IdT(index);
|
||||
} else {
|
||||
if (index < initial_reserved_ids_) {
|
||||
return IdT(index);
|
||||
}
|
||||
// TODO: Assert that tag_ doesn't have the second highest bit set.
|
||||
auto tagged_index = index ^ tag_;
|
||||
CARBON_DCHECK(tagged_index >= 0, "{0}", tagged_index);
|
||||
return IdT(tagged_index);
|
||||
}
|
||||
// TODO: Assert that tag_ doesn't have the second highest bit set.
|
||||
auto tagged_index = index ^ tag_;
|
||||
CARBON_DCHECK(tagged_index >= 0, "{0}", tagged_index);
|
||||
return IdT(tagged_index);
|
||||
}
|
||||
|
||||
auto Remove(IdT id) const -> int32_t {
|
||||
CARBON_DCHECK(id.index >= 0, "{0}", id);
|
||||
if (!HasTag(id.index)) {
|
||||
CARBON_DCHECK(id.index < initial_reserved_ids_,
|
||||
"This untagged index is outside the initial reserved ids "
|
||||
"and should have been tagged.");
|
||||
if constexpr (IdTagIsUntagged<IdTag>) {
|
||||
// Untagged ids are the index itself, so return directly with no tag
|
||||
// computation.
|
||||
return id.index;
|
||||
} else {
|
||||
if (!HasTag(id.index)) {
|
||||
CARBON_DCHECK(id.index < initial_reserved_ids_,
|
||||
"This untagged index is outside the initial reserved ids "
|
||||
"and should have been tagged.");
|
||||
return id.index;
|
||||
}
|
||||
auto untagged_index = id.index ^ tag_;
|
||||
CARBON_DCHECK(untagged_index >= initial_reserved_ids_,
|
||||
"When removing tagging bits, found an index that "
|
||||
"shouldn't've been tagged in the first place.");
|
||||
return untagged_index;
|
||||
}
|
||||
auto untagged_index = id.index ^ tag_;
|
||||
CARBON_DCHECK(untagged_index >= initial_reserved_ids_,
|
||||
"When removing tagging bits, found an index that "
|
||||
"shouldn't've been tagged in the first place.");
|
||||
return untagged_index;
|
||||
}
|
||||
|
||||
// Gets the value unique to this IdTag instance that is added to indices in
|
||||
|
||||
Reference in new issue
Block a user