Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
db4bfcc
Move -enable-sil-opaque-value to SILOptions.
atrick Jan 18, 2022
0897a69
Add emitLoad/emitStore to OpaqueValue type lowering.
atrick Jan 18, 2022
4ccb2e9
SILModule::hasLoweredAddress
atrick Feb 15, 2022
bd803b9
Update and reimplement AddressLowering pass (for SIL opaque values).
atrick Nov 29, 2021
4ceed0e
Add support for indirect tuple-type results.
atrick Mar 1, 2022
bbf6177
[SIL-opaque] Code review suggestions
atrick Mar 8, 2022
862c7bc
Fix alloc_stack placement for open_existential.
atrick Mar 9, 2022
222477a
Rename "phi copy" to "phi move" for consistency with documentation.
atrick Mar 9, 2022
2a9c305
[SIL-opaque] avoid handling operands past 64k
atrick Mar 9, 2022
7c663a4
[SIL-opaque] More file-level documentation
atrick Mar 9, 2022
5181705
[SIL-opaque] Add section-level comment explaining storage allocation
atrick Mar 9, 2022
f164c37
[SIL-opaque] remove cleanupAfterCall helper
atrick Mar 9, 2022
bb0dbf3
[SIL-opaque] add a test case for phi coalescing
atrick Mar 10, 2022
ba3e613
[SIL-opaque] in-depth top-level documentation for phi coalescing.
atrick Mar 10, 2022
752173c
[SIL-opaque] minor NFC review feedback
atrick Mar 10, 2022
04f4bcd
[SIL-opaque] rename materialization functions.
atrick Mar 10, 2022
906bee3
[SIL-opaque] rename initializeComposingUse
atrick Mar 10, 2022
97eec75
[SIL-opaque] Removed [Unconditional]CheckedCastValue
atrick Mar 6, 2022
1a0a92a
[SIL-opaque] Cleanup and reenable SILGen unit tests
atrick Mar 2, 2022
d4bc86a
[SIL-opaque] Various SILGen fixes
atrick Mar 5, 2022
23516ec
Add a test file for combined SILGen + AddressLowering
atrick Mar 7, 2022
06948a8
[SIL-opaque] use generated SILLocations
atrick Mar 16, 2022
95add90
Remove an unused test file (opaque_value_silgen_todo).
atrick Mar 19, 2022
390ab4d
Update SILGen/opaque_values_silgen_lib.swift for [serialized]
atrick Mar 19, 2022
434faee
[SIL-opaque] Add @in_guaranteed function argument support.
atrick Mar 20, 2022
d6f0c73
[SIL-opaque] Add an assert for open_existential_value.
atrick Mar 20, 2022
2d53e03
[SIL-opaque] [NFC] clang-format AddressLowering.cpp
atrick Mar 20, 2022
757a9d2
[SIL-opaque] Add address lowering test case.
atrick Mar 20, 2022
3ddce99
[SIL-opaque] Don't override arg value category.
nate-chandler Mar 21, 2022
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
20 changes: 20 additions & 0 deletions docs/SIL.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2193,6 +2193,26 @@ parts::
return %1 : $Klass
}

Forwarding Address-Only Values
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Address-only values are potentially unmovable when borrowed. This
means that they cannot be forwarded with guaranteed ownership unless
the forwarded value has the same representation as in the original
value and can reuse the same storage. Non-destructive projection is
allowed, such as `struct_extract`. Aggregation, such as `struct`, and
destructive disaggregation, such as `switch_enum` is not allowed. This
is an invariant for OSSA with opaque SIL values for these reasons:

1. To avoid implicit semantic copies. For move-only values, this allows
complete diagnostics. And in general, it makes it impossible for SIL
passes to "accidentally" create copies.

2. To reuse borrowed storage. This allows the optimizer to share the same
storage for multiple exclusive reads of the same variable, avoiding
copies. It may also be necessary to support native Swift atomics, which
will be unmovable-when-borrowed.

Borrowed Object based Safe Interior Pointers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down
3 changes: 3 additions & 0 deletions include/swift/AST/SILOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,9 @@ class SILOptions {
/// If this is disabled we do not serialize in OSSA form when optimizing.
bool EnableOSSAModules = false;

/// If set to true, compile with the SIL Opaque Values enabled.
bool EnableSILOpaqueValues = false;

// The kind of function bodies to skip emitting.
FunctionBodySkipping SkipFunctionBodies = FunctionBodySkipping::None;

Expand Down
5 changes: 0 additions & 5 deletions include/swift/Basic/LangOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -379,11 +379,6 @@ namespace swift {
/// [TODO: Clang-type-plumbing] Turn on for feature rollout.
bool UseClangFunctionTypes = false;

/// If set to true, compile with the SIL Opaque Values enabled.
/// This is for bootstrapping. It can't be in SILOptions because the
/// TypeChecker uses it to set resolve the ParameterConvention.
bool EnableSILOpaqueValues = false;

/// If set to true, the diagnosis engine can assume the emitted diagnostics
/// will be used in editor. This usually leads to more aggressive fixit.
bool DiagnosticsEditorMode = false;
Expand Down
6 changes: 3 additions & 3 deletions include/swift/Option/FrontendOptions.td
Original file line number Diff line number Diff line change
Expand Up @@ -507,9 +507,6 @@ def disable_sil_ownership_verifier : Flag<["-"], "disable-sil-ownership-verifier
def suppress_static_exclusivity_swap : Flag<["-"], "suppress-static-exclusivity-swap">,
HelpText<"Suppress static violations of exclusive access with swap()">;

def enable_sil_opaque_values : Flag<["-"], "enable-sil-opaque-values">,
HelpText<"Enable SIL Opaque Values">;

def enable_experimental_static_assert :
Flag<["-"], "enable-experimental-static-assert">,
HelpText<"Enable experimental #assert">;
Expand Down Expand Up @@ -1022,6 +1019,9 @@ def enable_ossa_modules : Flag<["-"], "enable-ossa-modules">,
HelpText<"Always serialize SIL in ossa form. If this flag is not passed in, "
"when optimizing ownership will be lowered before serializing SIL">;

def enable_sil_opaque_values : Flag<["-"], "enable-sil-opaque-values">,
HelpText<"Enable SIL Opaque Values">;

def new_driver_path
: Separate<["-"], "new-driver-path">, MetaVarName<"<path>">,
HelpText<"Path of the new driver to be used">;
Expand Down
8 changes: 4 additions & 4 deletions include/swift/SIL/ApplySite.h
Original file line number Diff line number Diff line change
Expand Up @@ -585,9 +585,9 @@ class FullApplySite : public ApplySite {
}

/// Get the SIL value that represents all of the given call's results. For a
/// single direct result, returns the result. For multiple results, returns a
/// fake tuple value. The tuple has no storage of its own. The real results
/// must be extracted from it.
/// single direct result, returns the actual result. For multiple results,
/// returns a pseudo-result tuple. The tuple has no storage of its own. The
/// real results must be extracted from it.
///
/// For ApplyInst, returns the single-value instruction itself.
///
Expand All @@ -596,7 +596,7 @@ class FullApplySite : public ApplySite {
/// For BeginApplyInst, returns an invalid value. For coroutines, there is no
/// single value representing all results. Yielded values are generally
/// handled differently since they have the convention of incoming arguments.
SILValue getPseudoResult() const {
SILValue getResult() const {
switch (getKind()) {
case FullApplySiteKind::ApplyInst:
return SILValue(cast<ApplyInst>(getInstruction()));
Expand Down
54 changes: 0 additions & 54 deletions include/swift/SIL/DynamicCasts.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,14 +187,10 @@ struct SILDynamicCastInst {
// checked_cast_value_br yet. Should we ever support it, please
// review this code.
case SILDynamicCastKind::CheckedCastBranchInst:
case SILDynamicCastKind::CheckedCastValueBranchInst:
return CastConsumptionKind::CopyOnSuccess;
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
return CastConsumptionKind::TakeAlways;
case SILDynamicCastKind::UnconditionalCheckedCastInst:
return CastConsumptionKind::CopyOnSuccess;
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
llvm_unreachable("unsupported");
}
llvm_unreachable("covered switch");
}
Expand All @@ -203,10 +199,8 @@ struct SILDynamicCastInst {
switch (getKind()) {
case SILDynamicCastKind::CheckedCastAddrBranchInst:
case SILDynamicCastKind::CheckedCastBranchInst:
case SILDynamicCastKind::CheckedCastValueBranchInst:
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
case SILDynamicCastKind::UnconditionalCheckedCastInst:
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
llvm_unreachable("unsupported");
}
}
Expand All @@ -217,13 +211,9 @@ struct SILDynamicCastInst {
return cast<CheckedCastAddrBranchInst>(inst)->getSuccessBB();
case SILDynamicCastKind::CheckedCastBranchInst:
return cast<CheckedCastBranchInst>(inst)->getSuccessBB();
case SILDynamicCastKind::CheckedCastValueBranchInst:
return cast<CheckedCastValueBranchInst>(inst)->getSuccessBB();
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
case SILDynamicCastKind::UnconditionalCheckedCastInst:
return nullptr;
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
llvm_unreachable("unsupported");
}
llvm_unreachable("covered switch");
}
Expand All @@ -234,13 +224,9 @@ struct SILDynamicCastInst {
llvm_unreachable("unsupported");
case SILDynamicCastKind::CheckedCastBranchInst:
return cast<CheckedCastBranchInst>(inst)->getTrueBBCount();
case SILDynamicCastKind::CheckedCastValueBranchInst:
llvm_unreachable("unsupported");
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
case SILDynamicCastKind::UnconditionalCheckedCastInst:
return None;
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
llvm_unreachable("unsupported");
}
llvm_unreachable("covered switch");
}
Expand All @@ -255,13 +241,9 @@ struct SILDynamicCastInst {
return cast<CheckedCastAddrBranchInst>(inst)->getFailureBB();
case SILDynamicCastKind::CheckedCastBranchInst:
return cast<CheckedCastBranchInst>(inst)->getFailureBB();
case SILDynamicCastKind::CheckedCastValueBranchInst:
return cast<CheckedCastValueBranchInst>(inst)->getFailureBB();
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
case SILDynamicCastKind::UnconditionalCheckedCastInst:
return nullptr;
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
llvm_unreachable("unsupported");
}
llvm_unreachable("covered switch");
}
Expand All @@ -272,13 +254,9 @@ struct SILDynamicCastInst {
llvm_unreachable("unsupported");
case SILDynamicCastKind::CheckedCastBranchInst:
return cast<CheckedCastBranchInst>(inst)->getFalseBBCount();
case SILDynamicCastKind::CheckedCastValueBranchInst:
llvm_unreachable("unsupported");
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
case SILDynamicCastKind::UnconditionalCheckedCastInst:
return None;
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
llvm_unreachable("unsupported");
}
llvm_unreachable("covered switch");
}
Expand All @@ -293,14 +271,10 @@ struct SILDynamicCastInst {
return cast<CheckedCastAddrBranchInst>(inst)->getSrc();
case SILDynamicCastKind::CheckedCastBranchInst:
return cast<CheckedCastBranchInst>(inst)->getOperand();
case SILDynamicCastKind::CheckedCastValueBranchInst:
return cast<CheckedCastValueBranchInst>(inst)->getOperand();
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
return cast<UnconditionalCheckedCastAddrInst>(inst)->getSrc();
case SILDynamicCastKind::UnconditionalCheckedCastInst:
return cast<UnconditionalCheckedCastInst>(inst)->getOperand();
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
llvm_unreachable("unsupported");
}
llvm_unreachable("covered switch");
}
Expand All @@ -311,7 +285,6 @@ struct SILDynamicCastInst {
case SILDynamicCastKind::CheckedCastAddrBranchInst:
return cast<CheckedCastAddrBranchInst>(inst)->getDest();
case SILDynamicCastKind::CheckedCastBranchInst:
case SILDynamicCastKind::CheckedCastValueBranchInst:
// TODO: Shouldn't this return getSuccessBlock()->getArgument(0)?
return SILValue();
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
Expand All @@ -321,8 +294,6 @@ struct SILDynamicCastInst {
//
// return cast<UnconditionalCheckedCastInst>(inst);
return SILValue();
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
llvm_unreachable("unimplemented");
}
llvm_unreachable("covered switch");
}
Expand All @@ -333,14 +304,10 @@ struct SILDynamicCastInst {
return cast<CheckedCastAddrBranchInst>(inst)->getSourceFormalType();
case SILDynamicCastKind::CheckedCastBranchInst:
return cast<CheckedCastBranchInst>(inst)->getSourceFormalType();
case SILDynamicCastKind::CheckedCastValueBranchInst:
return cast<CheckedCastValueBranchInst>(inst)->getSourceFormalType();
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
return cast<UnconditionalCheckedCastAddrInst>(inst)->getSourceFormalType();
case SILDynamicCastKind::UnconditionalCheckedCastInst:
return cast<UnconditionalCheckedCastInst>(inst)->getSourceFormalType();
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
return cast<UnconditionalCheckedCastValueInst>(inst)->getSourceFormalType();
}
llvm_unreachable("covered switch");
}
Expand All @@ -351,14 +318,10 @@ struct SILDynamicCastInst {
return cast<CheckedCastAddrBranchInst>(inst)->getSourceLoweredType();
case SILDynamicCastKind::CheckedCastBranchInst:
return cast<CheckedCastBranchInst>(inst)->getSourceLoweredType();
case SILDynamicCastKind::CheckedCastValueBranchInst:
return cast<CheckedCastValueBranchInst>(inst)->getSourceLoweredType();
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
return cast<UnconditionalCheckedCastAddrInst>(inst)->getSourceLoweredType();
case SILDynamicCastKind::UnconditionalCheckedCastInst:
return cast<UnconditionalCheckedCastInst>(inst)->getSourceLoweredType();
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
return cast<UnconditionalCheckedCastValueInst>(inst)->getSourceLoweredType();
}
llvm_unreachable("covered switch");
}
Expand All @@ -369,14 +332,10 @@ struct SILDynamicCastInst {
return cast<CheckedCastAddrBranchInst>(inst)->getTargetFormalType();
case SILDynamicCastKind::CheckedCastBranchInst:
return cast<CheckedCastBranchInst>(inst)->getTargetFormalType();
case SILDynamicCastKind::CheckedCastValueBranchInst:
return cast<CheckedCastValueBranchInst>(inst)->getTargetFormalType();
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
return cast<UnconditionalCheckedCastAddrInst>(inst)->getTargetFormalType();
case SILDynamicCastKind::UnconditionalCheckedCastInst:
return cast<UnconditionalCheckedCastInst>(inst)->getTargetFormalType();
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
return cast<UnconditionalCheckedCastValueInst>(inst)->getTargetFormalType();
}
llvm_unreachable("covered switch");
}
Expand All @@ -387,28 +346,21 @@ struct SILDynamicCastInst {
return cast<CheckedCastAddrBranchInst>(inst)->getDest()->getType();
case SILDynamicCastKind::CheckedCastBranchInst:
return cast<CheckedCastBranchInst>(inst)->getTargetLoweredType();
case SILDynamicCastKind::CheckedCastValueBranchInst:
return cast<CheckedCastValueBranchInst>(inst)->getTargetLoweredType();
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
return cast<UnconditionalCheckedCastAddrInst>(inst)->getDest()->getType();
case SILDynamicCastKind::UnconditionalCheckedCastInst:
return cast<UnconditionalCheckedCastInst>(inst)->getTargetLoweredType();
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
return cast<UnconditionalCheckedCastValueInst>(inst)->getTargetLoweredType();
}
llvm_unreachable("covered switch");
}

bool isSourceTypeExact() const {
switch (getKind()) {
case SILDynamicCastKind::CheckedCastValueBranchInst:
case SILDynamicCastKind::CheckedCastBranchInst:
case SILDynamicCastKind::CheckedCastAddrBranchInst:
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
case SILDynamicCastKind::UnconditionalCheckedCastInst:
return isa<MetatypeInst>(getSource());
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
llvm_unreachable("unsupported");
}
llvm_unreachable("covered switch");
}
Expand Down Expand Up @@ -476,15 +428,9 @@ struct SILDynamicCastInst {
auto f = classifyFeasibility(false /*allow wmo*/);
return f == DynamicCastFeasibility::MaySucceed;
}
case SILDynamicCastKind::CheckedCastValueBranchInst: {
auto f = classifyFeasibility(false /*allow wmo opts*/);
return f == DynamicCastFeasibility::MaySucceed;
}
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
case SILDynamicCastKind::UnconditionalCheckedCastInst:
return false;
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
llvm_unreachable("unsupported");
}
llvm_unreachable("covered switch");
}
Expand Down
29 changes: 3 additions & 26 deletions include/swift/SIL/SILBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -266,11 +266,10 @@ class SILBuilder {
void clearInsertionPoint() { BB = nullptr; }

/// setInsertionPoint - Set the insertion point.
void setInsertionPoint(SILBasicBlock *BB, SILBasicBlock::iterator InsertPt) {
void setInsertionPoint(SILBasicBlock *BB, SILBasicBlock::iterator insertPt) {
this->BB = BB;
this->InsertPt = InsertPt;
if (InsertPt == BB->end())
return;
this->InsertPt = insertPt;
assert(insertPt == BB->end() || insertPt->getParent() == BB);
}

/// setInsertionPoint - Set the insertion point to insert before the specified
Expand Down Expand Up @@ -1315,16 +1314,6 @@ class SILBuilder {
dest, targetFormalType, getFunction()));
}

UnconditionalCheckedCastValueInst *
createUnconditionalCheckedCastValue(SILLocation Loc,
SILValue op, CanType srcFormalTy,
SILType destLoweredTy,
CanType destFormalTy) {
return insert(UnconditionalCheckedCastValueInst::create(
getSILDebugLocation(Loc), op, srcFormalTy,
destLoweredTy, destFormalTy, getFunction()));
}

RetainValueInst *createRetainValue(SILLocation Loc, SILValue operand,
Atomicity atomicity) {
assert(!hasOwnership());
Expand Down Expand Up @@ -2325,18 +2314,6 @@ class SILBuilder {
ProfileCounter Target1Count = ProfileCounter(),
ProfileCounter Target2Count = ProfileCounter());

CheckedCastValueBranchInst *
createCheckedCastValueBranch(SILLocation Loc,
SILValue op, CanType srcFormalTy,
SILType destLoweredTy,
CanType destFormalTy,
SILBasicBlock *successBB,
SILBasicBlock *failureBB) {
return insertTerminator(CheckedCastValueBranchInst::create(
getSILDebugLocation(Loc), op, srcFormalTy,
destLoweredTy, destFormalTy, successBB, failureBB, getFunction()));
}

CheckedCastAddrBranchInst *
createCheckedCastAddrBranch(SILLocation Loc, CastConsumptionKind consumption,
SILValue src, CanType sourceFormalType,
Expand Down
34 changes: 0 additions & 34 deletions include/swift/SIL/SILCloner.h
Original file line number Diff line number Diff line change
Expand Up @@ -1706,24 +1706,6 @@ SILCloner<ImplClass>::visitUnconditionalCheckedCastAddrInst(
OpLoc, SrcValue, SrcType, DestValue, TargetType));
}

template <typename ImplClass>
void SILCloner<ImplClass>::visitUnconditionalCheckedCastValueInst(
UnconditionalCheckedCastValueInst *Inst) {
SILLocation OpLoc = getOpLocation(Inst->getLoc());
SILValue OpValue = getOpValue(Inst->getOperand());
CanType SrcFormalType = getOpASTType(Inst->getSourceFormalType());
SILType OpLoweredType = getOpType(Inst->getTargetLoweredType());
CanType OpFormalType = getOpASTType(Inst->getTargetFormalType());
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
recordClonedInstruction(
Inst,
getBuilder().createUnconditionalCheckedCastValue(OpLoc,
OpValue,
SrcFormalType,
OpLoweredType,
OpFormalType));
}

template <typename ImplClass>
void SILCloner<ImplClass>::visitRetainValueInst(RetainValueInst *Inst) {
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
Expand Down Expand Up @@ -2737,22 +2719,6 @@ SILCloner<ImplClass>::visitCheckedCastBranchInst(CheckedCastBranchInst *Inst) {
Inst->getForwardingOwnershipKind(), TrueCount, FalseCount));
}

template <typename ImplClass>
void SILCloner<ImplClass>::visitCheckedCastValueBranchInst(
CheckedCastValueBranchInst *Inst) {
SILBasicBlock *OpSuccBB = getOpBasicBlock(Inst->getSuccessBB());
SILBasicBlock *OpFailBB = getOpBasicBlock(Inst->getFailureBB());
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
recordClonedInstruction(
Inst, getBuilder().createCheckedCastValueBranch(
getOpLocation(Inst->getLoc()),
getOpValue(Inst->getOperand()),
getOpASTType(Inst->getSourceFormalType()),
getOpType(Inst->getTargetLoweredType()),
getOpASTType(Inst->getTargetFormalType()),
OpSuccBB, OpFailBB));
}

template<typename ImplClass>
void SILCloner<ImplClass>::visitCheckedCastAddrBranchInst(
CheckedCastAddrBranchInst *Inst) {
Expand Down
Loading