-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Track a list of dependent instructions created within a generic (#4092)
When checking a declaration or definition of a generic, track a list of created instructions that depend on the generic's parameters in some way, along with information on how they depend on the parameters. This will eventually be used to determine what information we need to compute when creating instances of the generic, but for now we're just building the list. Information is tracked separately for the declaration region and the definition region of the generic, because in general these may be first provided in separate declarations, and they should be substituted into at different times.
- Loading branch information
Showing
12 changed files
with
225 additions
and
45 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
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,32 @@ | ||
// 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/check/generic_region_stack.h" | ||
|
||
namespace Carbon::Check { | ||
|
||
auto GenericRegionStack::Push() -> void { | ||
regions_.push_back( | ||
{.first_dependent_inst = static_cast<int32_t>(dependent_insts_.size())}); | ||
} | ||
|
||
auto GenericRegionStack::Pop() -> void { | ||
auto region = regions_.pop_back_val(); | ||
dependent_insts_.truncate(region.first_dependent_inst); | ||
} | ||
|
||
auto GenericRegionStack::AddDependentInst(DependentInst inst) -> void { | ||
CARBON_CHECK(!regions_.empty()) | ||
<< "Formed a dependent instruction while not in a generic region."; | ||
CARBON_CHECK(inst.kind != DependencyKind::None); | ||
dependent_insts_.push_back(inst); | ||
} | ||
|
||
auto GenericRegionStack::PeekDependentInsts() -> llvm::ArrayRef<DependentInst> { | ||
CARBON_CHECK(!regions_.empty()); | ||
return llvm::ArrayRef(dependent_insts_) | ||
.slice(regions_.back().first_dependent_inst); | ||
} | ||
|
||
} // namespace Carbon::Check |
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,81 @@ | ||
// 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_TOOLCHAIN_CHECK_GENERIC_REGION_STACK_H_ | ||
#define CARBON_TOOLCHAIN_CHECK_GENERIC_REGION_STACK_H_ | ||
|
||
#include "llvm/ADT/BitmaskEnum.h" | ||
#include "toolchain/sem_ir/ids.h" | ||
|
||
namespace Carbon::Check { | ||
|
||
LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); | ||
|
||
// A stack of enclosing regions that might be declaring or defining a generic | ||
// entity. In such a region, we track the generic constructs that are used, such | ||
// as symbolic constants and types, and instructions that depend on a template | ||
// parameter. | ||
// | ||
// TODO: For now we're just tracking symbolic constants. | ||
// | ||
// We split a generic into two regions -- declaration and definition -- because | ||
// these are in general introduced separately, and substituted into separately. | ||
// For example, for `class C(T:! type, N:! T) { var x: T; }`, a use such as | ||
// `C(i32, 0)*` substitutes into just the declaration, whereas a use such as | ||
// `var x: C(i32, 0) = {.x = 0};` also substitutes into the definition. | ||
class GenericRegionStack { | ||
public: | ||
// Ways in which an instruction can depend on a generic parameter. | ||
enum class DependencyKind : int8_t { | ||
None = 0x0, | ||
// The type of the instruction depends on a checked generic parameter. | ||
SymbolicType = 0x1, | ||
// The constant value of the instruction depends on a checked generic | ||
// parameter. | ||
SymbolicConstant = 0x2, | ||
Template = 0x4, | ||
LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Template) | ||
}; | ||
|
||
// An instruction that depends on a generic parameter in some way. | ||
struct DependentInst { | ||
SemIR::InstId inst_id; | ||
DependencyKind kind; | ||
}; | ||
|
||
// Pushes a region that might be declaring or defining a generic. | ||
auto Push() -> void; | ||
|
||
// Pops a generic region. | ||
auto Pop() -> void; | ||
|
||
// Adds an instruction to the list of instructions in the current region that | ||
// in some way depend on a generic parameter. | ||
auto AddDependentInst(DependentInst inst) -> void; | ||
|
||
// Returns the list of dependent instructions in the current generic region. | ||
auto PeekDependentInsts() -> llvm::ArrayRef<DependentInst>; | ||
|
||
private: | ||
// Information about an enclosing generic region that has been pushed onto the | ||
// stack. | ||
struct RegionInfo { | ||
// The size of `dependent_insts_` at the start of this region. Equivalently, | ||
// this is the first index within `dependent_insts_` that belongs to this | ||
// region or a region nested within it. | ||
int32_t first_dependent_inst; | ||
}; | ||
|
||
// The current set of enclosing generic regions. | ||
llvm::SmallVector<RegionInfo> regions_; | ||
|
||
// List of symbolic constants used in any of the enclosing generic regions. We | ||
// keep a single vector rather than one vector per region in order to minimize | ||
// heap allocations. | ||
llvm::SmallVector<DependentInst> dependent_insts_; | ||
}; | ||
|
||
} // namespace Carbon::Check | ||
|
||
#endif // CARBON_TOOLCHAIN_CHECK_GENERIC_REGION_STACK_H_ |
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
Oops, something went wrong.