mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Create an array stack type for a shared use-case (#4100)
Based on discussion around the region handling in generic_region_stack, create a generic structure for the stack-of-vectors support. I also want to add this to InstBlockStack, but that's a little more complex due to GlobalInit, so cutting a PR here to check with review. My work here is how I noticed #4099; I want to be sure that I'm correct about the issue, but it's the difference between being able to use PeekArray or not. Note in scope_stack.h, I believe we could remove next_compile_time_index and make it just based on elements_size(). However, I want to verify with you before I make further changes there. --------- Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
This commit is contained in:
co-authored by
Chandler Carruth
parent
e71e6ca07f
commit
d437e4bffe
@@ -0,0 +1,74 @@
|
||||
// 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
|
||||
|
||||
#ifndef CARBON_COMMON_ARRAY_STACK_H_
|
||||
#define CARBON_COMMON_ARRAY_STACK_H_
|
||||
|
||||
#include "common/check.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
|
||||
namespace Carbon {
|
||||
|
||||
// Provides a stack of arrays. Only the array at the top of the stack can have
|
||||
// elements added.
|
||||
//
|
||||
// Example usage:
|
||||
// // Push to start.
|
||||
// PushArray();
|
||||
// // Add values.
|
||||
// AppendToTop(3);
|
||||
// // Look at values.
|
||||
// PeekArray();
|
||||
// // Pop when done.
|
||||
// PopArray();
|
||||
//
|
||||
// By using a single vector for elements, the intent is that as arrays are
|
||||
// pushed and popped, the same storage will be reused. This should yield
|
||||
// efficiencies for heap allocations. For example, in the toolchain we
|
||||
// frequently have an array per scope, and only add to the current scope's
|
||||
// array; this allows better reuse when entering and leaving scopes.
|
||||
template <typename ValueT>
|
||||
class ArrayStack {
|
||||
public:
|
||||
// Pushes a new array onto the stack.
|
||||
auto PushArray() -> void { array_offsets_.push_back(values_.size()); }
|
||||
|
||||
// Pops the top array from the stack.
|
||||
auto PopArray() -> void {
|
||||
auto region = array_offsets_.pop_back_val();
|
||||
values_.truncate(region);
|
||||
}
|
||||
|
||||
// Returns the top array from the stack.
|
||||
auto PeekArray() const -> llvm::ArrayRef<ValueT> {
|
||||
CARBON_CHECK(!array_offsets_.empty());
|
||||
return llvm::ArrayRef(values_).slice(array_offsets_.back());
|
||||
}
|
||||
|
||||
// Returns the full set of values on the stack, regardless of whether any
|
||||
// arrays are pushed.
|
||||
auto PeekAllValues() const -> llvm::ArrayRef<ValueT> { return values_; }
|
||||
|
||||
// Appends a value to the top array on the stack.
|
||||
auto AppendToTop(ValueT value) -> void {
|
||||
CARBON_CHECK(!array_offsets_.empty())
|
||||
<< "Must call PushArray before PushValue.";
|
||||
values_.push_back(value);
|
||||
}
|
||||
|
||||
// Returns the current number of values in all arrays.
|
||||
auto all_values_size() const -> size_t { return values_.size(); }
|
||||
|
||||
private:
|
||||
// For each pushed array, the start index in elements_.
|
||||
llvm::SmallVector<int32_t> array_offsets_;
|
||||
|
||||
// The full set of elements in all arrays.
|
||||
llvm::SmallVector<ValueT> values_;
|
||||
};
|
||||
|
||||
} // namespace Carbon
|
||||
|
||||
#endif // CARBON_COMMON_ARRAY_STACK_H_
|
||||
Reference in New Issue
Block a user