mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 19:01:07 +01:00
Add a fixed-size ValueStore (#5628)
Trying to build a type around the common idiom we have for types based on an Id range. The primary advantage of this is it makes clear the `Id` association, and drops the `.index` use. Lowering was motivating me because it has a few of these, and check probably has more (e.g. `tree_and_subtrees_getters`), but I'm just changing a handful of examples to show the concept and see if there's agreement. I wanted to inherit from ValueStoreTypes, but name lookup didn't seem to find the types without `using` statements, at which point there didn't seem to be much reason to use inheritance.
This commit is contained in:
@@ -7,15 +7,16 @@
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
#include "toolchain/base/fixed_size_value_store.h"
|
||||
#include "toolchain/lex/token_index.h"
|
||||
|
||||
namespace Carbon::Parse {
|
||||
|
||||
TreeAndSubtrees::TreeAndSubtrees(const Lex::TokenizedBuffer& tokens,
|
||||
const Tree& tree)
|
||||
: tokens_(&tokens), tree_(&tree) {
|
||||
subtree_sizes_.reserve(tree_->size());
|
||||
|
||||
: tokens_(&tokens),
|
||||
tree_(&tree),
|
||||
subtree_sizes_(SubtreeSizeStore::MakeForOverwrite(tree_->size())) {
|
||||
// A stack of nodes which haven't yet been used as children.
|
||||
llvm::SmallVector<NodeId> size_stack;
|
||||
for (auto n : tree.postorder()) {
|
||||
@@ -31,7 +32,7 @@ TreeAndSubtrees::TreeAndSubtrees(const Lex::TokenizedBuffer& tokens,
|
||||
for (auto i : llvm::seq(kind.child_count())) {
|
||||
auto child = size_stack.pop_back_val();
|
||||
CARBON_CHECK(static_cast<size_t>(child.index) < subtree_sizes_.size());
|
||||
size += subtree_sizes_[child.index];
|
||||
size += subtree_sizes_.Get(child);
|
||||
if (kind.has_bracket() && i == kind.child_count() - 1) {
|
||||
CARBON_CHECK(kind.bracket() == tree.node_kind(child),
|
||||
"Node {0} with child count {1} needs bracket {2}, found "
|
||||
@@ -45,28 +46,26 @@ TreeAndSubtrees::TreeAndSubtrees(const Lex::TokenizedBuffer& tokens,
|
||||
CARBON_CHECK(!size_stack.empty(), "Node {0} is missing bracket {1}",
|
||||
kind, kind.bracket());
|
||||
auto child = size_stack.pop_back_val();
|
||||
size += subtree_sizes_[child.index];
|
||||
size += subtree_sizes_.Get(child);
|
||||
if (kind.bracket() == tree.node_kind(child)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
size_stack.push_back(n);
|
||||
subtree_sizes_.push_back(size);
|
||||
subtree_sizes_.Set(n, size);
|
||||
}
|
||||
|
||||
CARBON_CHECK(static_cast<int>(subtree_sizes_.size()) == tree_->size());
|
||||
|
||||
// Remaining nodes should all be roots in the tree; make sure they line up.
|
||||
CARBON_CHECK(
|
||||
size_stack.back().index == static_cast<int32_t>(tree_->size()) - 1,
|
||||
"{0} {1}", size_stack.back(), tree_->size() - 1);
|
||||
int prev_index = -1;
|
||||
for (const auto& n : size_stack) {
|
||||
CARBON_CHECK(n.index - subtree_sizes_[n.index] == prev_index,
|
||||
CARBON_CHECK(n.index - subtree_sizes_.Get(n) == prev_index,
|
||||
"NodeId {0} is a root {1} with subtree_size {2}, but previous "
|
||||
"root was at {3}.",
|
||||
n, tree_->node_kind(n), subtree_sizes_[n.index], prev_index);
|
||||
n, tree_->node_kind(n), subtree_sizes_.Get(n), prev_index);
|
||||
prev_index = n.index;
|
||||
}
|
||||
}
|
||||
@@ -117,14 +116,14 @@ auto TreeAndSubtrees::postorder(NodeId n) const
|
||||
-> llvm::iterator_range<Tree::PostorderIterator> {
|
||||
// The postorder ends after this node, the root, and begins at the begin of
|
||||
// its subtree.
|
||||
int begin_index = n.index - subtree_sizes_[n.index] + 1;
|
||||
int begin_index = n.index - subtree_sizes_.Get(n) + 1;
|
||||
return Tree::PostorderIterator::MakeRange(NodeId(begin_index), n);
|
||||
}
|
||||
|
||||
auto TreeAndSubtrees::children(NodeId n) const
|
||||
-> llvm::iterator_range<SiblingIterator> {
|
||||
CARBON_CHECK(n.has_value());
|
||||
int end_index = n.index - subtree_sizes_[n.index];
|
||||
int end_index = n.index - subtree_sizes_.Get(n);
|
||||
return llvm::iterator_range<SiblingIterator>(
|
||||
SiblingIterator(*this, NodeId(n.index - 1)),
|
||||
SiblingIterator(*this, NodeId(end_index)));
|
||||
@@ -153,8 +152,8 @@ auto TreeAndSubtrees::PrintNode(llvm::raw_ostream& output, NodeId n, int depth,
|
||||
output << ", has_error: yes";
|
||||
}
|
||||
|
||||
if (subtree_sizes_[n.index] > 1) {
|
||||
output << ", subtree_size: " << subtree_sizes_[n.index];
|
||||
if (subtree_sizes_.Get(n) > 1) {
|
||||
output << ", subtree_size: " << subtree_sizes_.Get(n);
|
||||
if (preorder) {
|
||||
output << ", children: [\n";
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user