[AllocBoxToStack] Lexical borrowees get lexical alloc_stacks.

Previously, whenever an alloc_box that was promoted to an alloc_stack,
the new alloc_stack would be lexical.  The result was that alloc_boxes
which didn't need (or explicitly didn't want, in the case of eager move
vars) received lexical alloc_stacks.

Here, only add the lexical flag to the new alloc_stack instruction if
any of the box's uses are `begin_borrow [lexical]`.  That way,
alloc_boxes end up having lexical alloc_stacks only if they were
"lexical alloc_boxes".
This commit is contained in:
Nate Chandler
2022-08-08 17:36:44 -07:00
parent 80ba5b588b
commit 896a464ced
2 changed files with 58 additions and 14 deletions

View File

@@ -13,12 +13,13 @@
#define DEBUG_TYPE "allocbox-to-stack"
#include "swift/AST/DiagnosticsSIL.h"
#include "swift/Basic/BlotMapVector.h"
#include "swift/Basic/GraphNodeWorklist.h"
#include "swift/SIL/ApplySite.h"
#include "swift/SIL/BasicBlockDatastructures.h"
#include "swift/SIL/Dominance.h"
#include "swift/SIL/SILArgument.h"
#include "swift/SIL/SILBuilder.h"
#include "swift/SIL/SILCloner.h"
#include "swift/SIL/BasicBlockDatastructures.h"
#include "swift/SILOptimizer/PassManager/Passes.h"
#include "swift/SILOptimizer/PassManager/Transforms.h"
#include "swift/SILOptimizer/Utils/InstOptUtils.h"
@@ -27,6 +28,7 @@
#include "swift/SILOptimizer/Utils/StackNesting.h"
#include "swift/SILOptimizer/Utils/ValueLifetime.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
@@ -538,13 +540,35 @@ static bool rewriteAllocBoxAsAllocStack(AllocBoxInst *ABI) {
SILBuilderWithScope Builder(ABI);
assert(ABI->getBoxType()->getLayout()->getFields().size() == 1
&& "rewriting multi-field box not implemented");
auto &mod = ABI->getFunction()->getModule();
bool isLexical = mod.getASTContext().SILOpts.supportsLexicalLifetimes(mod);
auto *ASI = Builder.createAllocStack(
ABI->getLoc(),
getSILBoxFieldType(TypeExpansionContext(*ABI->getFunction()),
ABI->getBoxType(), ABI->getModule().Types, 0),
ABI->getVarInfo(), ABI->hasDynamicLifetime(), isLexical);
auto ty = getSILBoxFieldType(TypeExpansionContext(*ABI->getFunction()),
ABI->getBoxType(), ABI->getModule().Types, 0);
auto isLexical = [&]() -> bool {
auto &mod = ABI->getFunction()->getModule();
bool lexicalLifetimesEnabled =
mod.getASTContext().SILOpts.supportsLexicalLifetimes(mod);
if (!lexicalLifetimesEnabled)
return false;
// Look for lexical borrows of the alloc_box.
GraphNodeWorklist<Operand *, 4> worklist;
worklist.initializeRange(ABI->getUses());
while (auto *use = worklist.pop()) {
// See through mark_uninitialized and non-lexical begin_borrow
// instructions. It's verified that lexical begin_borrows of SILBoxType
// values originate either from AllocBoxInsts or SILFunctionArguments.
if (auto *mui = dyn_cast<MarkUninitializedInst>(use->getUser())) {
for (auto *use : mui->getUses())
worklist.insert(use);
} else if (auto *bbi = dyn_cast<BeginBorrowInst>(use->getUser())) {
if (bbi->isLexical())
return true;
for (auto *use : bbi->getUses())
worklist.insert(use);
}
}
return false;
};
auto *ASI = Builder.createAllocStack(ABI->getLoc(), ty, ABI->getVarInfo(),
ABI->hasDynamicLifetime(), isLexical());
// Transfer a mark_uninitialized if we have one.
SILValue StackBox = ASI;