Skip to content

Commit 47545bf

Browse files
committed
Temporarily merge Michael's change for PR testing, and flip the feature flag
1 parent fbd6961 commit 47545bf

File tree

13 files changed

+75
-1
lines changed

13 files changed

+75
-1
lines changed

include/swift/AST/Builtins.def

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -844,6 +844,11 @@ BUILTIN_MISC_OPERATION_WITH_SILGEN(BuildDefaultActorExecutorRef,
844844
BUILTIN_MISC_OPERATION_WITH_SILGEN(BuildMainActorExecutorRef,
845845
"buildMainActorExecutorRef", "n", Special)
846846

847+
/// isOnStack : (Builtin.NativeObject) -> Builtin.Int1
848+
///
849+
/// Returns true if the optimizer successfully moved this object from the stack onto the heap.
850+
BUILTIN_MISC_OPERATION_WITH_SILGEN(IsOnStack, "isOnStack", "n", Special)
851+
847852
#undef BUILTIN_MISC_OPERATION_WITH_SILGEN
848853

849854
#undef BUILTIN_MISC_OPERATION

include/swift/IRGen/IRGenSILPasses.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ class SILTransform;
1616

1717
namespace irgen {
1818

19-
/// Create a pass to hoist alloc_stack instructions with non-fixed size.
2019
SILTransform *createAllocStackHoisting();
2120
SILTransform *createLoadableByAddress();
21+
SILTransform *createStackSizeLimitTransform();
2222

2323
} // end namespace irgen
2424
} // end namespace swift

include/swift/SIL/SILBuilder.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,14 @@ class SILBuilder {
407407
Var, hasDynamicLifetime));
408408
}
409409

410+
/// Helper method for creating alloc_box from an instance value.
411+
AllocBoxInst *createAllocBox(SILLocation Loc, SILType InstanceType,
412+
Optional<SILDebugVariable> Var = None,
413+
bool hasDynamicLifetime = false) {
414+
auto BoxType = SILBoxType::get(InstanceType.getASTType());
415+
return createAllocBox(Loc, BoxType, Var, hasDynamicLifetime);
416+
}
417+
410418
AllocExistentialBoxInst *
411419
createAllocExistentialBox(SILLocation Loc, SILType ExistentialType,
412420
CanType ConcreteType,
@@ -603,6 +611,15 @@ class SILBuilder {
603611
getModule()));
604612
}
605613

614+
/// Returns integer_literal Builtin.Int1, 1
615+
IntegerLiteralInst *createIntegerLiteralBool(SILLocation Loc, bool Value) {
616+
auto builtinType =
617+
SILType::getBuiltinIntegerType(1, getModule().getASTContext());
618+
619+
return insert(IntegerLiteralInst::create(getSILDebugLocation(Loc),
620+
builtinType, Value, getModule()));
621+
}
622+
606623
FloatLiteralInst *createFloatLiteral(FloatLiteralExpr *E);
607624

608625
FloatLiteralInst *createFloatLiteral(SILLocation Loc, SILType Ty,

include/swift/SILOptimizer/PassManager/Passes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,8 @@ PASS(LateReleaseHoisting, "late-release-hoisting",
296296
"Late SIL release Hoisting Preserving Epilogues")
297297
IRGEN_PASS(LoadableByAddress, "loadable-address",
298298
"SIL Large Loadable type by-address lowering.")
299+
IRGEN_PASS(StackSizeLimitTransform, "stack-size-limit",
300+
"Limit the amount of stack growth possible in a single SIL function by converting stack memory to heap memory")
299301
PASS(MandatorySILLinker, "mandatory-linker",
300302
"Deserialize all referenced SIL functions that are shared or transparent")
301303
PASS(PerformanceSILLinker, "performance-linker",

lib/AST/Builtins.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -963,6 +963,11 @@ static ValueDecl *getEndUnpairedAccessOperation(ASTContext &ctx,
963963
_void);
964964
}
965965

966+
static ValueDecl *getIsOnStackOperation(ASTContext &ctx, Identifier id) {
967+
return getBuiltinFunction(ctx, id, _thin, _parameters(_nativeObject),
968+
_int(1));
969+
}
970+
966971
static ValueDecl *getSizeOrAlignOfOperation(ASTContext &ctx,
967972
Identifier id) {
968973
return getBuiltinFunction(ctx, id, _thin,
@@ -2475,6 +2480,11 @@ ValueDecl *swift::getBuiltinValueDecl(ASTContext &Context, Identifier Id) {
24752480
if (!Types.empty()) return nullptr;
24762481
return getEndUnpairedAccessOperation(Context, Id);
24772482

2483+
case BuiltinValueKind::IsOnStack:
2484+
if (!Types.empty())
2485+
return nullptr;
2486+
return getIsOnStackOperation(Context, Id);
2487+
24782488
#define BUILTIN(id, name, Attrs)
24792489
#define BUILTIN_BINARY_OPERATION(id, name, attrs)
24802490
#define BUILTIN_BINARY_OPERATION_OVERLOADED_STATIC(id, name, attrs, overload) \

lib/IRGen/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ add_swift_host_library(swiftIRGen STATIC
5454
MetadataRequest.cpp
5555
Outlining.cpp
5656
StructLayout.cpp
57+
StackSizeLimitTransform.cpp
5758
SwiftTargetInfo.cpp
5859
TypeLayout.cpp
5960
TypeLayoutDumper.cpp

lib/IRGen/GenBuiltin.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin,
124124
ArrayRef<SILType> argTypes,
125125
Explosion &args, Explosion &out,
126126
SubstitutionMap substitutions) {
127+
assert(Builtin.ID != BuiltinValueKind::IsOnStack &&
128+
"Builtin should not exist at IRGen time");
129+
127130
if (Builtin.ID == BuiltinValueKind::COWBufferForReading) {
128131
// Just forward the incoming argument.
129132
assert(args.size() == 1 && "Expecting one incoming argument");

lib/SIL/IR/OperandOwnership.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,7 @@ BUILTIN_OPERAND_OWNERSHIP(DestroyingConsume, StartAsyncLet)
749749
BUILTIN_OPERAND_OWNERSHIP(DestroyingConsume, EndAsyncLet)
750750
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, CreateTaskGroup)
751751
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, DestroyTaskGroup)
752+
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, IsOnStack)
752753

753754
BUILTIN_OPERAND_OWNERSHIP(ForwardingConsume, COWBufferForReading)
754755
BUILTIN_OPERAND_OWNERSHIP(ForwardingConsume, UnsafeGuaranteed)

lib/SIL/IR/ValueOwnership.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,7 @@ CONSTANT_OWNERSHIP_BUILTIN(None, StartAsyncLet)
551551
CONSTANT_OWNERSHIP_BUILTIN(None, EndAsyncLet)
552552
CONSTANT_OWNERSHIP_BUILTIN(None, CreateTaskGroup)
553553
CONSTANT_OWNERSHIP_BUILTIN(None, DestroyTaskGroup)
554+
CONSTANT_OWNERSHIP_BUILTIN(None, IsOnStack)
554555

555556
#undef CONSTANT_OWNERSHIP_BUILTIN
556557

lib/SILGen/SILGenBuiltin.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1650,6 +1650,21 @@ static ManagedValue emitBuiltinBuildMainActorExecutorRef(
16501650
BuiltinValueKind::BuildMainActorExecutorRef);
16511651
}
16521652

1653+
static ManagedValue emitBuiltinIsOnStack(SILGenFunction &SGF, SILLocation loc,
1654+
SubstitutionMap substitutions,
1655+
ArrayRef<ManagedValue> args,
1656+
SGFContext C) {
1657+
auto &ctx = SGF.getASTContext();
1658+
auto id = ctx.getIdentifier(getBuiltinName(BuiltinValueKind::IsOnStack));
1659+
SmallVector<SILValue, 1> argValues;
1660+
if (!args.empty())
1661+
argValues.push_back(args[0].getValue());
1662+
auto builtinType = SILType::getBuiltinIntegerType(1, ctx);
1663+
auto builtin =
1664+
SGF.B.createBuiltin(loc, id, builtinType, substitutions, argValues);
1665+
return ManagedValue::forUnmanaged(builtin);
1666+
}
1667+
16531668
Optional<SpecializedEmitter>
16541669
SpecializedEmitter::forDecl(SILGenModule &SGM, SILDeclRef function) {
16551670
// Only consider standalone declarations in the Builtin module.

lib/SILOptimizer/Analysis/EscapeAnalysis.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2382,6 +2382,18 @@ void EscapeAnalysis::analyzeInstruction(SILInstruction *I,
23822382
}
23832383
return;
23842384
}
2385+
case SILInstructionKind::BuiltinInst: {
2386+
// Some builtins do not escape.
2387+
if (auto *bi = dyn_cast<BuiltinInst>(I))
2388+
if (auto kind = bi->getBuiltinKind())
2389+
// For now we only do is on stack.
2390+
if (*kind == BuiltinValueKind::IsOnStack)
2391+
return;
2392+
2393+
// If we don't have one of those, be conservative.
2394+
setAllEscaping(I, ConGraph);
2395+
return;
2396+
}
23852397
default:
23862398
// We handle all other instructions conservatively.
23872399
setAllEscaping(I, ConGraph);

lib/SILOptimizer/PassManager/PassPipeline.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,10 @@ SILPassPipelinePlan::getLoweringPassPipeline(const SILOptions &Options) {
754754
return P;
755755
}
756756

757+
static llvm::cl::opt<bool>
758+
EnableStackSizeLimitTransform("swift-irgen-enable-stack-size-limit",
759+
llvm::cl::init(true), llvm::cl::Hidden);
760+
757761
SILPassPipelinePlan
758762
SILPassPipelinePlan::getIRGenPreparePassPipeline(const SILOptions &Options) {
759763
SILPassPipelinePlan P(Options);
@@ -763,6 +767,8 @@ SILPassPipelinePlan::getIRGenPreparePassPipeline(const SILOptions &Options) {
763767
// llvm-ir generation for dynamic alloca instructions.
764768
P.addAllocStackHoisting();
765769
P.addLoadableByAddress();
770+
if (EnableStackSizeLimitTransform)
771+
P.addStackSizeLimitTransform();
766772

767773
return P;
768774
}

lib/SILOptimizer/Transforms/AccessEnforcementReleaseSinking.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ static bool isBarrier(SILInstruction *inst) {
113113
case BuiltinValueKind::Sizeof:
114114
case BuiltinValueKind::Strideof:
115115
case BuiltinValueKind::IsPOD:
116+
case BuiltinValueKind::IsOnStack:
116117
case BuiltinValueKind::IsConcrete:
117118
case BuiltinValueKind::IsBitwiseTakable:
118119
case BuiltinValueKind::IsSameMetatype:

0 commit comments

Comments
 (0)