Support for lowering templates (#7727)

Add basic support for lowering templates: we can now lower `SpliceInst`
in the case where the generic and specific are from the same file (and
we don't support importing templates from other files yet in general).
In order for this to work, lowering needs to be able to query the
expression category, and to handle instructions that appear to be
(template) constants in the generic but turn out to be non-constant in
the specific, so support for that is added.

Switch `type_of_inst` from being added as an action inst to being added
as a normal inst, since it's not an action and the old approach led to a
crash in lowering.
This commit is contained in:
Richard Smith
2026-09-08 18:39:57 +00:00
committed by GitHub
parent 3339dd85de
commit 5a07a14fe9
17 changed files with 1127 additions and 708 deletions
+8 -2
View File
@@ -119,7 +119,7 @@ static auto LowerInstHelper(FunctionContext& context, SemIR::InstId inst_id,
// in `requires`-style overloads.
auto FunctionContext::LowerInst(SemIR::InstId inst_id) -> void {
// Skip over constants. `FileContext::GetConstant` lowers them as needed.
if (sem_ir().constant_values().Get(inst_id).is_constant()) {
if (IsConstant(inst_id)) {
return;
}
@@ -168,6 +168,12 @@ auto FunctionContext::GetBlockArg(SemIR::InstBlockId block_id, TypeInFile type)
return phi;
}
auto FunctionContext::IsConstant(SemIR::InstId inst_id) -> bool {
return GetConstantValueInSpecific(specific_sem_ir(), specific_id_, sem_ir(),
inst_id)
.second.is_constant();
}
auto FunctionContext::GetValue(SemIR::InstId inst_id) -> llvm::Value* {
// All builtins are types, with the same empty lowered value.
if (SemIR::IsSingletonInstId(inst_id)) {
@@ -275,7 +281,7 @@ auto FunctionContext::InitializeStorage(TypeInFile type, SemIR::InstId dest_id,
case SemIR::InitRepr::None:
break;
case SemIR::InitRepr::InPlace:
if (sem_ir().constant_values().Get(source_id).is_constant()) {
if (IsConstant(source_id)) {
// When initializing from a constant, emission of the source doesn't
// initialize the destination. Copy the constant value instead.
// TODO: If the type is small, emit a store rather than a memcpy.