Skip to content

Try an experiment #36886

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions include/swift/AST/Builtins.def
Original file line number Diff line number Diff line change
Expand Up @@ -880,6 +880,11 @@ BUILTIN_MISC_OPERATION_WITH_SILGEN(BuildDefaultActorExecutorRef,
BUILTIN_MISC_OPERATION_WITH_SILGEN(BuildMainActorExecutorRef,
"buildMainActorExecutorRef", "n", Special)

/// isOnStack : (Builtin.NativeObject) -> Builtin.Int1
///
/// Returns true if the optimizer successfully moved this object from the stack onto the heap.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this comment backwards?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think so but you'll have to ask @gottesmm since it's from his PR that I merged into this one

BUILTIN_MISC_OPERATION_WITH_SILGEN(IsOnStack, "isOnStack", "n", Special)

#undef BUILTIN_MISC_OPERATION_WITH_SILGEN

#undef BUILTIN_MISC_OPERATION
Expand Down
2 changes: 1 addition & 1 deletion include/swift/IRGen/IRGenSILPasses.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ class SILTransform;

namespace irgen {

/// Create a pass to hoist alloc_stack instructions with non-fixed size.
SILTransform *createAllocStackHoisting();
SILTransform *createLoadableByAddress();
SILTransform *createStackSizeLimitTransform();

} // end namespace irgen
} // end namespace swift
17 changes: 17 additions & 0 deletions include/swift/SIL/SILBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,14 @@ class SILBuilder {
Var, hasDynamicLifetime));
}

/// Helper method for creating alloc_box from an instance value.
AllocBoxInst *createAllocBox(SILLocation Loc, SILType InstanceType,
Optional<SILDebugVariable> Var = None,
bool hasDynamicLifetime = false) {
auto BoxType = SILBoxType::get(InstanceType.getASTType());
return createAllocBox(Loc, BoxType, Var, hasDynamicLifetime);
}

AllocExistentialBoxInst *
createAllocExistentialBox(SILLocation Loc, SILType ExistentialType,
CanType ConcreteType,
Expand Down Expand Up @@ -610,6 +618,15 @@ class SILBuilder {
getModule()));
}

/// Returns integer_literal Builtin.Int1, 1
IntegerLiteralInst *createIntegerLiteralBool(SILLocation Loc, bool Value) {
auto builtinType =
SILType::getBuiltinIntegerType(1, getModule().getASTContext());

return insert(IntegerLiteralInst::create(getSILDebugLocation(Loc),
builtinType, Value, getModule()));
}

FloatLiteralInst *createFloatLiteral(FloatLiteralExpr *E);

FloatLiteralInst *createFloatLiteral(SILLocation Loc, SILType Ty,
Expand Down
2 changes: 2 additions & 0 deletions include/swift/SILOptimizer/PassManager/Passes.def
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,8 @@ PASS(LateReleaseHoisting, "late-release-hoisting",
"Late SIL release Hoisting Preserving Epilogues")
IRGEN_PASS(LoadableByAddress, "loadable-address",
"SIL Large Loadable type by-address lowering.")
IRGEN_PASS(StackSizeLimitTransform, "stack-size-limit",
"Limit the amount of stack growth possible in a single SIL function by converting stack memory to heap memory")
PASS(MandatorySILLinker, "mandatory-linker",
"Deserialize all referenced SIL functions that are shared or transparent")
PASS(PerformanceSILLinker, "performance-linker",
Expand Down
10 changes: 10 additions & 0 deletions lib/AST/Builtins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -963,6 +963,11 @@ static ValueDecl *getEndUnpairedAccessOperation(ASTContext &ctx,
_void);
}

static ValueDecl *getIsOnStackOperation(ASTContext &ctx, Identifier id) {
return getBuiltinFunction(ctx, id, _thin, _parameters(_nativeObject),
_int(1));
}

static ValueDecl *getSizeOrAlignOfOperation(ASTContext &ctx,
Identifier id) {
return getBuiltinFunction(ctx, id, _thin,
Expand Down Expand Up @@ -2492,6 +2497,11 @@ ValueDecl *swift::getBuiltinValueDecl(ASTContext &Context, Identifier Id) {
if (!Types.empty()) return nullptr;
return getEndUnpairedAccessOperation(Context, Id);

case BuiltinValueKind::IsOnStack:
if (!Types.empty())
return nullptr;
return getIsOnStackOperation(Context, Id);

#define BUILTIN(id, name, Attrs)
#define BUILTIN_BINARY_OPERATION(id, name, attrs)
#define BUILTIN_BINARY_OPERATION_OVERLOADED_STATIC(id, name, attrs, overload) \
Expand Down
1 change: 1 addition & 0 deletions lib/IRGen/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ add_swift_host_library(swiftIRGen STATIC
MetadataRequest.cpp
Outlining.cpp
StructLayout.cpp
StackSizeLimitTransform.cpp
SwiftTargetInfo.cpp
TypeLayout.cpp
TypeLayoutDumper.cpp
Expand Down
3 changes: 3 additions & 0 deletions lib/IRGen/GenBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin,
ArrayRef<SILType> argTypes,
Explosion &args, Explosion &out,
SubstitutionMap substitutions) {
assert(Builtin.ID != BuiltinValueKind::IsOnStack &&
"Builtin should not exist at IRGen time");

if (Builtin.ID == BuiltinValueKind::COWBufferForReading) {
// Just forward the incoming argument.
assert(args.size() == 1 && "Expecting one incoming argument");
Expand Down
1 change: 1 addition & 0 deletions lib/SIL/IR/OperandOwnership.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -763,6 +763,7 @@ BUILTIN_OPERAND_OWNERSHIP(DestroyingConsume, StartAsyncLetWithLocalBuffer)
BUILTIN_OPERAND_OWNERSHIP(DestroyingConsume, EndAsyncLetLifetime)
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, CreateTaskGroup)
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, DestroyTaskGroup)
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, IsOnStack)

BUILTIN_OPERAND_OWNERSHIP(ForwardingConsume, COWBufferForReading)
BUILTIN_OPERAND_OWNERSHIP(ForwardingConsume, UnsafeGuaranteed)
Expand Down
1 change: 1 addition & 0 deletions lib/SIL/IR/ValueOwnership.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,7 @@ CONSTANT_OWNERSHIP_BUILTIN(None, StartAsyncLetWithLocalBuffer)
CONSTANT_OWNERSHIP_BUILTIN(None, EndAsyncLetLifetime)
CONSTANT_OWNERSHIP_BUILTIN(None, CreateTaskGroup)
CONSTANT_OWNERSHIP_BUILTIN(None, DestroyTaskGroup)
CONSTANT_OWNERSHIP_BUILTIN(None, IsOnStack)

#undef CONSTANT_OWNERSHIP_BUILTIN

Expand Down
15 changes: 15 additions & 0 deletions lib/SILGen/SILGenBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1657,6 +1657,21 @@ static ManagedValue emitBuiltinBuildMainActorExecutorRef(
BuiltinValueKind::BuildMainActorExecutorRef);
}

static ManagedValue emitBuiltinIsOnStack(SILGenFunction &SGF, SILLocation loc,
SubstitutionMap substitutions,
ArrayRef<ManagedValue> args,
SGFContext C) {
auto &ctx = SGF.getASTContext();
auto id = ctx.getIdentifier(getBuiltinName(BuiltinValueKind::IsOnStack));
SmallVector<SILValue, 1> argValues;
if (!args.empty())
argValues.push_back(args[0].getValue());
auto builtinType = SILType::getBuiltinIntegerType(1, ctx);
auto builtin =
SGF.B.createBuiltin(loc, id, builtinType, substitutions, argValues);
return ManagedValue::forUnmanaged(builtin);
}

Optional<SpecializedEmitter>
SpecializedEmitter::forDecl(SILGenModule &SGM, SILDeclRef function) {
// Only consider standalone declarations in the Builtin module.
Expand Down
12 changes: 12 additions & 0 deletions lib/SILOptimizer/Analysis/EscapeAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2373,6 +2373,18 @@ void EscapeAnalysis::analyzeInstruction(SILInstruction *I,
}
return;
}
case SILInstructionKind::BuiltinInst: {
// Some builtins do not escape.
if (auto *bi = dyn_cast<BuiltinInst>(I))
if (auto kind = bi->getBuiltinKind())
// For now we only do is on stack.
if (*kind == BuiltinValueKind::IsOnStack)
return;

// If we don't have one of those, be conservative.
setAllEscaping(I, ConGraph);
return;
}
default:
// We handle all other instructions conservatively.
setAllEscaping(I, ConGraph);
Expand Down
6 changes: 6 additions & 0 deletions lib/SILOptimizer/PassManager/PassPipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,10 @@ SILPassPipelinePlan::getLoweringPassPipeline(const SILOptions &Options) {
return P;
}

static llvm::cl::opt<bool>
EnableStackSizeLimitTransform("swift-irgen-enable-stack-size-limit",
llvm::cl::init(true), llvm::cl::Hidden);

SILPassPipelinePlan
SILPassPipelinePlan::getIRGenPreparePassPipeline(const SILOptions &Options) {
SILPassPipelinePlan P(Options);
Expand All @@ -773,6 +777,8 @@ SILPassPipelinePlan::getIRGenPreparePassPipeline(const SILOptions &Options) {
// llvm-ir generation for dynamic alloca instructions.
P.addAllocStackHoisting();
P.addLoadableByAddress();
if (EnableStackSizeLimitTransform)
P.addStackSizeLimitTransform();

return P;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ static bool isBarrier(SILInstruction *inst) {
case BuiltinValueKind::Sizeof:
case BuiltinValueKind::Strideof:
case BuiltinValueKind::IsPOD:
case BuiltinValueKind::IsOnStack:
case BuiltinValueKind::IsConcrete:
case BuiltinValueKind::IsBitwiseTakable:
case BuiltinValueKind::IsSameMetatype:
Expand Down
4 changes: 2 additions & 2 deletions stdlib/public/core/ContiguousArrayBuffer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -276,8 +276,8 @@ internal struct _ContiguousArrayBuffer<Element>: _ArrayBufferProtocol {
_ContiguousArrayStorage<Element>.self,
realMinimumCapacity._builtinWordValue, Element.self)

let storageAddr = UnsafeMutableRawPointer(Builtin.bridgeToRawPointer(_storage))
if let allocSize = _mallocSize(ofAllocation: storageAddr) {
if let allocSize = _mallocSizeIfHeap(of: _storage) {
let storageAddr = UnsafeMutableRawPointer(Builtin.bridgeToRawPointer(_storage))
let endAddr = storageAddr + allocSize
let realCapacity = endAddr.assumingMemoryBound(to: Element.self) - firstElementAddress
_initStorageHeader(
Expand Down
14 changes: 13 additions & 1 deletion stdlib/public/core/Shims.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,19 @@ internal let _fastEnumerationStorageMutationsPtr =
UnsafeMutablePointer<CUnsignedLong>(Builtin.addressof(&_fastEnumerationStorageMutationsTarget))
#endif

@usableFromInline @_alwaysEmitIntoClient



@usableFromInline @_alwaysEmitIntoClient @_effects(readonly)
internal func _mallocSize(ofAllocation ptr: UnsafeRawPointer) -> Int? {
return _swift_stdlib_has_malloc_size() ? _swift_stdlib_malloc_size(ptr) : nil
}

@_transparent @inlinable @_effects(readonly)
internal func _mallocSizeIfHeap(of object: AnyObject) -> Int? {
if Bool(Builtin.isOnStack(_nativeObject(fromNative: object))) { return nil }
return _mallocSize(
ofAllocation: UnsafeRawPointer(Builtin.bridgeToRawPointer(object))
)
}