@@ -141,6 +141,24 @@ class SILPrintContext;
141141
142142template <typename ImplClass> class SILClonerWithScopes ;
143143
144+ // / An enum that describes whether or not a stack allocation may violate the
145+ // / stack discipline of swift.
146+ // /
147+ // / DISCUSSION: In swift, we require that all allocations on the stack be
148+ // / strictly allocated in a LIFO order... that is the last stack allocation
149+ // / created must be the first stack allocation destroyed. In some cases, we
150+ // / cannot guarantee that behavior. In such cases we may need to use other
151+ // / strategies that do not involve stack memory (e.x.: using heap memory
152+ // / although we do not require heap memory to be used).
153+ enum StackAllocationIsNested_t : bool {
154+ // / The instruction may not obey the LIFO rule of stack allocation.
155+ StackAllocationIsNotNested = false ,
156+
157+ // / The instruction obeys the LIFO rule of stack allocation and can allocate
158+ // / memory on the stack normally.
159+ StackAllocationIsNested = true ,
160+ };
161+
144162enum class MemoryBehavior {
145163 None,
146164 // / The instruction may read memory.
@@ -858,6 +876,15 @@ class SILInstruction : public llvm::ilist_node<SILInstruction> {
858876 // / The stack allocation produced by the instruction, if any.
859877 SILValue getStackAllocation () const ;
860878
879+ // / Returns the kind of stack memory that should be allocated. There are
880+ // / certain (unfortunate) situations in which "stack" allocations may become
881+ // / unnested and must use alternative allocation strategies. Rather than
882+ // / requiring all of these to explicitly use heap allocation, which may be
883+ // / to be significantly less efficient (e.g. )
884+ StackAllocationIsNested_t isStackAllocationNested () const ;
885+
886+ void setStackAllocationIsNested (StackAllocationIsNested_t isNested);
887+
861888 // / Returns true if this is the deallocation of a stack allocating instruction.
862889 // / The first operand must be the allocating instruction.
863890 bool isDeallocatingStack () const ;
@@ -2055,6 +2082,24 @@ class AllocStackInst final
20552082 }
20562083 }
20572084
2085+ StackAllocationIsNested_t isStackAllocationNested () const {
2086+ if (sharedUInt8 ().AllocStackInst .isNested ) {
2087+ return StackAllocationIsNested;
2088+ }
2089+ return StackAllocationIsNotNested;
2090+ }
2091+
2092+ void setStackAllocationIsNested (StackAllocationIsNested_t isNested) {
2093+ switch (isNested) {
2094+ case StackAllocationIsNotNested:
2095+ sharedUInt8 ().AllocStackInst .isNested = false ;
2096+ break ;
2097+ case StackAllocationIsNested:
2098+ sharedUInt8 ().AllocStackInst .isNested = true ;
2099+ break ;
2100+ }
2101+ }
2102+
20582103 void markUsesMoveableValueDebugInfo () {
20592104 sharedUInt8 ().AllocStackInst .usesMoveableValueDebugInfo =
20602105 (bool )UsesMoveableValueDebugInfo;
0 commit comments