Skip to content

Commit ac4bc89

Browse files
committed
SIL: add the borrowed-from instruction.
It declares from which enclosing values a guaranteed phi argument is borrowed from.
1 parent 44f4ea9 commit ac4bc89

33 files changed

+304
-16
lines changed

SwiftCompilerSources/Sources/SIL/Argument.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,15 @@ public struct Phi {
139139
value.ownership == .owned || value.isReborrow
140140
}
141141

142+
public var borrowedFrom: BorrowedFromInst? {
143+
for use in value.uses {
144+
if let bfi = use.forwardingBorrowedFromUser {
145+
return bfi
146+
}
147+
}
148+
return nil
149+
}
150+
142151
public static func ==(lhs: Phi, rhs: Phi) -> Bool {
143152
lhs.value === rhs.value
144153
}
@@ -148,6 +157,15 @@ public struct Phi {
148157
}
149158
}
150159

160+
extension Operand {
161+
public var forwardingBorrowedFromUser: BorrowedFromInst? {
162+
if let bfi = instruction as? BorrowedFromInst, index == 0 {
163+
return bfi
164+
}
165+
return nil
166+
}
167+
}
168+
151169
public struct TerminatorResult {
152170
public let value: Argument
153171

SwiftCompilerSources/Sources/SIL/Builder.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,13 @@ public struct Builder {
184184
return notifyNew(bridged.createBeginBorrow(value.bridged).getAs(BeginBorrowInst.self))
185185
}
186186

187+
public func createBorrowedFrom(borrowedValue: Value, enclosingValues: [Value]) -> BorrowedFromInst {
188+
let bfi = enclosingValues.withBridgedValues { valuesRef in
189+
return bridged.createBorrowedFrom(borrowedValue.bridged, valuesRef)
190+
}
191+
return notifyNew(bfi.getAs(BorrowedFromInst.self))
192+
}
193+
187194
@discardableResult
188195
public func createEndBorrow(of beginBorrow: Value) -> EndBorrowInst {
189196
return notifyNew(bridged.createEndBorrow(beginBorrow.bridged).getAs(EndBorrowInst.self))

SwiftCompilerSources/Sources/SIL/ForwardingInstruction.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,14 @@ extension LinearFunctionExtractInst: ForwardingInstruction {
441441
public var canForwardOwnedValues: Bool { true }
442442
}
443443

444+
extension BorrowedFromInst: ForwardingInstruction {
445+
public var singleForwardedOperand: Operand? { operands[0] }
446+
public var preservesIdentity: Bool { true }
447+
public var preservesRepresentation: Bool { true }
448+
public var canForwardGuaranteedValues: Bool { true }
449+
public var canForwardOwnedValues: Bool { false }
450+
}
451+
444452
// -----------------------------------------------------------------------------
445453
// ownership transition instructions
446454

SwiftCompilerSources/Sources/SIL/Instruction.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -956,6 +956,18 @@ final public class BridgeObjectToRefInst : SingleValueInstruction, UnaryInstruct
956956

957957
final public class BridgeObjectToWordInst : SingleValueInstruction, UnaryInstruction {}
958958

959+
final public class BorrowedFromInst : SingleValueInstruction, BorrowIntroducingInstruction {
960+
public var borrowedValue: Value { operands[0].value }
961+
public var borrowedPhi: Phi { Phi(borrowedValue)! }
962+
public var enclosingOperands: OperandArray {
963+
let ops = operands
964+
return ops[1..<ops.count]
965+
}
966+
public var enclosingValues: LazyMapSequence<LazySequence<OperandArray>.Elements, Value> {
967+
enclosingOperands.values
968+
}
969+
}
970+
959971
final public class ProjectBoxInst : SingleValueInstruction, UnaryInstruction {
960972
public var box: Value { operand.value }
961973
public var fieldIndex: Int { bridged.ProjectBoxInst_fieldIndex() }

SwiftCompilerSources/Sources/SIL/Registration.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ public func registerSILClasses() {
201201
register(ExtractExecutorInst.self)
202202
register(BeginAccessInst.self)
203203
register(BeginBorrowInst.self)
204+
register(BorrowedFromInst.self)
204205
register(ProjectBoxInst.self)
205206
register(ProjectExistentialBoxInst.self)
206207
register(CopyValueInst.self)

docs/SIL.rst

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4615,6 +4615,38 @@ We require that ``%1`` and ``%0`` have the same type ignoring SILValueCategory.
46154615

46164616
This instruction is only valid in functions in Ownership SSA form.
46174617

4618+
borrowed from
4619+
`````````````
4620+
4621+
::
4622+
4623+
sil-instruction ::= 'borrowed' sil-operand 'from' '(' (sil-operand (',' sil-operand)*)? ')'
4624+
4625+
bb1(%1 : @owned $T, %2 : @guaranteed $T):
4626+
%3 = borrowed %2 : $T from (%1 : $T, %0 : $S)
4627+
// %3 has type $T and guaranteed ownership
4628+
4629+
Declares from which enclosing values a guaranteed phi argument is borrowed
4630+
from.
4631+
An enclosing value is either a dominating borrow introducer (``%0``) of the
4632+
borrowed operand (``%2``) or an adjacent phi-argument in the same block
4633+
(``%1``).
4634+
In case of an adjacent phi, all incoming values of the adjacent phi must be
4635+
borrow introducers for the corresponding incoming value of the borrowed
4636+
operand in all predecessor blocks.
4637+
4638+
The borrowed operand (``%2``) must be a guaranteed phi argument and is
4639+
forwarded to the instruction result.
4640+
4641+
The list of enclosing values (operands after ``from``) can be empty if the
4642+
borrowed operand stems from a borrow introducer with no enclosing value, e.g.
4643+
a ``load_borrow``.
4644+
4645+
Guaranteed phi arguments must not have other users than borrowed-from
4646+
instructions.
4647+
4648+
This instruction is only valid in functions in Ownership SSA form.
4649+
46184650
end_lifetime
46194651
````````````
46204652

include/swift/SIL/InstWrappers.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,8 @@ class ForwardingOperation {
279279
&forwardingInst->getOperandRef(RefToBridgeObjectInst::ConvertedOperand);
280280
case SILInstructionKind::TuplePackExtractInst:
281281
return &forwardingInst->getOperandRef(TuplePackExtractInst::TupleOperand);
282+
case SILInstructionKind::BorrowedFromInst:
283+
return &forwardingInst->getOperandRef(0);
282284
default:
283285
int numRealOperands = forwardingInst->getNumRealOperands();
284286
if (numRealOperands == 0) {

include/swift/SIL/OwnershipUtils.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ class BorrowingOperandKind {
254254
enum Kind : uint8_t {
255255
Invalid = 0,
256256
BeginBorrow,
257+
BorrowedFrom,
257258
StoreBorrow,
258259
BeginApply,
259260
Branch,
@@ -279,6 +280,8 @@ class BorrowingOperandKind {
279280
return Kind::Invalid;
280281
case SILInstructionKind::BeginBorrowInst:
281282
return Kind::BeginBorrow;
283+
case SILInstructionKind::BorrowedFromInst:
284+
return Kind::BorrowedFrom;
282285
case SILInstructionKind::StoreBorrowInst:
283286
return Kind::StoreBorrow;
284287
case SILInstructionKind::BeginApplyInst:
@@ -399,6 +402,7 @@ struct BorrowingOperand {
399402
case BorrowingOperandKind::Invalid:
400403
llvm_unreachable("Using invalid case?!");
401404
case BorrowingOperandKind::BeginBorrow:
405+
case BorrowingOperandKind::BorrowedFrom:
402406
case BorrowingOperandKind::StoreBorrow:
403407
case BorrowingOperandKind::BeginApply:
404408
case BorrowingOperandKind::Apply:
@@ -431,6 +435,7 @@ struct BorrowingOperand {
431435
case BorrowingOperandKind::Invalid:
432436
llvm_unreachable("Using invalid case?!");
433437
case BorrowingOperandKind::BeginBorrow:
438+
case BorrowingOperandKind::BorrowedFrom:
434439
case BorrowingOperandKind::Branch:
435440
return true;
436441
case BorrowingOperandKind::StoreBorrow:

include/swift/SIL/SILBridging.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1163,6 +1163,8 @@ struct BridgedBuilder{
11631163
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedInstruction createFunctionRef(BridgedFunction function) const;
11641164
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedInstruction createCopyValue(BridgedValue op) const;
11651165
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedInstruction createBeginBorrow(BridgedValue op) const;
1166+
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedInstruction createBorrowedFrom(BridgedValue borrowedValue,
1167+
BridgedValueArray enclosingValues) const;
11661168
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedInstruction createEndBorrow(BridgedValue op) const;
11671169
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedInstruction createCopyAddr(BridgedValue from, BridgedValue to,
11681170
bool takeSource, bool initializeDest) const;

include/swift/SIL/SILBridgingImpl.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1575,6 +1575,13 @@ BridgedInstruction BridgedBuilder::createBeginBorrow(BridgedValue op) const {
15751575
return {unbridged().createBeginBorrow(regularLoc(), op.getSILValue())};
15761576
}
15771577

1578+
BridgedInstruction BridgedBuilder::createBorrowedFrom(BridgedValue borrowedValue,
1579+
BridgedValueArray enclosingValues) const {
1580+
llvm::SmallVector<swift::SILValue, 16> evs;
1581+
return {unbridged().createBorrowedFrom(regularLoc(), borrowedValue.getSILValue(),
1582+
enclosingValues.getValues(evs))};
1583+
}
1584+
15781585
BridgedInstruction BridgedBuilder::createEndBorrow(BridgedValue op) const {
15791586
return {unbridged().createEndBorrow(regularLoc(), op.getSILValue())};
15801587
}

0 commit comments

Comments
 (0)