[sil] Add basic SIL support for alloc_stack [non_nested].

This means I just added the flag and added support for
cloning/printing/serializing the bit on alloc_stack.
This commit is contained in:
Michael Gottesman
2025-11-18 14:27:43 -08:00
parent a1b41acf8d
commit 29229a9410
13 changed files with 120 additions and 10 deletions

View File

@@ -1062,6 +1062,7 @@ SILCloner<ImplClass>::visitAllocStackInst(AllocStackInst *Inst) {
true
#endif
);
NewInst->setStackAllocationIsNested(Inst->isStackAllocationNested());
recordClonedInstruction(Inst, NewInst);
}

View File

@@ -141,6 +141,24 @@ class SILPrintContext;
template <typename ImplClass> class SILClonerWithScopes;
/// An enum that describes whether or not a stack allocation may violate the
/// stack discipline of swift.
///
/// DISCUSSION: In swift, we require that all allocations on the stack be
/// strictly allocated in a LIFO order... that is the last stack allocation
/// created must be the first stack allocation destroyed. In some cases, we
/// cannot guarantee that behavior. In such cases we may need to use other
/// strategies that do not involve stack memory (e.x.: using heap memory
/// although we do not require heap memory to be used).
enum StackAllocationIsNested_t : bool {
/// The instruction may not obey the LIFO rule of stack allocation.
StackAllocationIsNotNested = false,
/// The instruction obeys the LIFO rule of stack allocation and can allocate
/// memory on the stack normally.
StackAllocationIsNested = true,
};
enum class MemoryBehavior {
None,
/// The instruction may read memory.
@@ -858,6 +876,15 @@ public:
/// The stack allocation produced by the instruction, if any.
SILValue getStackAllocation() const;
/// Returns the kind of stack memory that should be allocated. There are
/// certain (unfortunate) situations in which "stack" allocations may become
/// unnested and must use alternative allocation strategies. Rather than
/// requiring all of these to explicitly use heap allocation, which may be
/// to be significantly less efficient (e.g. )
StackAllocationIsNested_t isStackAllocationNested() const;
void setStackAllocationIsNested(StackAllocationIsNested_t isNested);
/// Returns true if this is the deallocation of a stack allocating instruction.
/// The first operand must be the allocating instruction.
bool isDeallocatingStack() const;
@@ -2055,6 +2082,24 @@ public:
}
}
StackAllocationIsNested_t isStackAllocationNested() const {
if (sharedUInt8().AllocStackInst.isNested) {
return StackAllocationIsNested;
}
return StackAllocationIsNotNested;
}
void setStackAllocationIsNested(StackAllocationIsNested_t isNested) {
switch (isNested) {
case StackAllocationIsNotNested:
sharedUInt8().AllocStackInst.isNested = false;
break;
case StackAllocationIsNested:
sharedUInt8().AllocStackInst.isNested = true;
break;
}
}
void markUsesMoveableValueDebugInfo() {
sharedUInt8().AllocStackInst.usesMoveableValueDebugInfo =
(bool)UsesMoveableValueDebugInfo;

View File

@@ -229,7 +229,8 @@ protected:
lexical : 1,
fromVarDecl : 1,
usesMoveableValueDebugInfo : 1,
hasInvalidatedVarInfo : 1);
hasInvalidatedVarInfo : 1,
isNested : 1);
SHARED_FIELD(AllocBoxInst, uint8_t
dynamicLifetime : 1,