Skip to content

Commit 6df7ebb

Browse files
committed
Update and add new apis on ForwardingInstruction
1 parent 43b20ca commit 6df7ebb

File tree

8 files changed

+107
-62
lines changed

8 files changed

+107
-62
lines changed

include/swift/SIL/SILInstruction.h

Lines changed: 71 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1239,9 +1239,48 @@ class ForwardingInstruction {
12391239
ownershipKind = newKind;
12401240
}
12411241

1242+
static bool canForwardAllOperands(SILInstruction *inst) {
1243+
switch (inst->getKind()) {
1244+
case SILInstructionKind::StructInst:
1245+
case SILInstructionKind::TupleInst:
1246+
case SILInstructionKind::LinearFunctionInst:
1247+
case SILInstructionKind::DifferentiableFunctionInst:
1248+
return true;
1249+
default:
1250+
return false;
1251+
}
1252+
}
1253+
1254+
static bool canForwardFirstOperandOnly(SILInstruction *inst) {
1255+
if (!ForwardingInstruction::isa(inst)) {
1256+
return false;
1257+
}
1258+
return !canForwardAllOperands(inst);
1259+
}
1260+
1261+
static bool canForwardOwnedCompatibleValuesOnly(SILInstruction *inst) {
1262+
switch (inst->getKind()) {
1263+
case SILInstructionKind::MarkUninitializedInst:
1264+
return true;
1265+
default:
1266+
return false;
1267+
}
1268+
}
1269+
1270+
static bool canForwardGuaranteedCompatibleValuesOnly(SILInstruction *inst) {
1271+
switch (inst->getKind()) {
1272+
case SILInstructionKind::TupleExtractInst:
1273+
case SILInstructionKind::StructExtractInst:
1274+
case SILInstructionKind::DifferentiableFunctionExtractInst:
1275+
case SILInstructionKind::LinearFunctionExtractInst:
1276+
return true;
1277+
default:
1278+
return false;
1279+
}
1280+
}
1281+
12421282
/// Defined inline below due to forward declaration issues.
12431283
static ForwardingInstruction *get(SILInstruction *inst);
1244-
/// Defined inline below due to forward declaration issues.
12451284
static bool isa(SILInstructionKind kind);
12461285
static bool isa(const SILInstruction *inst) { return isa(inst->getKind()); }
12471286
static bool isa(SILNodePointer node) {
@@ -1296,24 +1335,6 @@ class OwnershipForwardingSingleValueInstruction : public SingleValueInstruction,
12961335
}
12971336
};
12981337

1299-
inline bool
1300-
OwnershipForwardingSingleValueInstruction::classof(SILInstructionKind kind) {
1301-
switch (kind) {
1302-
case SILInstructionKind::ObjectInst:
1303-
case SILInstructionKind::EnumInst:
1304-
case SILInstructionKind::UncheckedEnumDataInst:
1305-
case SILInstructionKind::OpenExistentialRefInst:
1306-
case SILInstructionKind::InitExistentialRefInst:
1307-
case SILInstructionKind::MarkDependenceInst:
1308-
case SILInstructionKind::MoveOnlyWrapperToCopyableValueInst:
1309-
case SILInstructionKind::MoveOnlyWrapperToCopyableBoxInst:
1310-
case SILInstructionKind::CopyableToMoveOnlyWrapperValueInst:
1311-
return true;
1312-
default:
1313-
return false;
1314-
}
1315-
}
1316-
13171338
/// A value base result of a multiple value instruction.
13181339
///
13191340
/// *NOTE* We want this to be a pure abstract class that does not add /any/ size
@@ -10548,6 +10569,37 @@ class LinearFunctionExtractInst
1054810569
}
1054910570
};
1055010571

10572+
inline bool
10573+
OwnershipForwardingSingleValueInstruction::classof(SILInstructionKind kind) {
10574+
switch (kind) {
10575+
case SILInstructionKind::ObjectInst:
10576+
case SILInstructionKind::EnumInst:
10577+
case SILInstructionKind::UncheckedEnumDataInst:
10578+
case SILInstructionKind::OpenExistentialRefInst:
10579+
case SILInstructionKind::InitExistentialRefInst:
10580+
case SILInstructionKind::MarkDependenceInst:
10581+
case SILInstructionKind::MoveOnlyWrapperToCopyableValueInst:
10582+
case SILInstructionKind::MoveOnlyWrapperToCopyableBoxInst:
10583+
case SILInstructionKind::CopyableToMoveOnlyWrapperValueInst:
10584+
case SILInstructionKind::MarkUninitializedInst:
10585+
case SILInstructionKind::TupleExtractInst:
10586+
case SILInstructionKind::StructExtractInst:
10587+
case SILInstructionKind::DifferentiableFunctionExtractInst:
10588+
case SILInstructionKind::LinearFunctionExtractInst:
10589+
case SILInstructionKind::OpenExistentialValueInst:
10590+
case SILInstructionKind::OpenExistentialBoxValueInst:
10591+
case SILInstructionKind::StructInst:
10592+
case SILInstructionKind::TupleInst:
10593+
case SILInstructionKind::LinearFunctionInst:
10594+
case SILInstructionKind::DifferentiableFunctionInst:
10595+
case SILInstructionKind::MarkMustCheckInst:
10596+
case SILInstructionKind::MarkUnresolvedReferenceBindingInst:
10597+
return true;
10598+
default:
10599+
return false;
10600+
}
10601+
}
10602+
1055110603
/// DifferentiabilityWitnessFunctionInst - Looks up a differentiability witness
1055210604
/// function for a given original function.
1055310605
class DifferentiabilityWitnessFunctionInst
@@ -10833,8 +10885,6 @@ inline ForwardingInstruction *ForwardingInstruction::get(SILInstruction *inst) {
1083310885
if (auto *result =
1083410886
dyn_cast<OwnershipForwardingMultipleValueInstruction>(inst))
1083510887
return result;
10836-
if (auto *result = dyn_cast<CopyableToMoveOnlyWrapperValueInst>(inst))
10837-
return result;
1083810888
return nullptr;
1083910889
}
1084010890

lib/SIL/IR/SILInstructions.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3229,13 +3229,15 @@ bool ForwardingInstruction::hasSameRepresentation(SILInstruction *inst) {
32293229
}
32303230

32313231
bool ForwardingInstruction::isAddressOnly(SILInstruction *inst) {
3232-
if (auto *aggregate =
3233-
dyn_cast<AllArgOwnershipForwardingSingleValueInst>(inst)) {
3232+
if (canForwardAllOperands(inst)) {
3233+
// All ForwardingInstructions that forward all operands are currently a
3234+
// single value instruction.
3235+
auto *aggregate = cast<OwnershipForwardingSingleValueInstruction>(inst);
32343236
// If any of the operands are address-only, then the aggregate must be.
32353237
return aggregate->getType().isAddressOnly(*inst->getFunction());
32363238
}
32373239
// All other forwarding instructions must forward their first operand.
3238-
assert(ForwardingInstruction::isa(inst));
3240+
assert(canForwardFirstOperandOnly(inst));
32393241
return inst->getOperand(0)->getType().isAddressOnly(*inst->getFunction());
32403242
}
32413243

lib/SIL/Utils/MemAccessUtils.cpp

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -899,18 +899,15 @@ SILValue swift::findOwnershipReferenceAggregate(SILValue ref) {
899899
if (!root)
900900
return root;
901901

902-
if (isa<FirstArgOwnershipForwardingSingleValueInst>(root) ||
903-
isa<OwnershipForwardingConversionInst>(root) ||
904-
isa<OwnershipForwardingSelectEnumInstBase>(root) ||
905-
isa<OwnershipForwardingMultipleValueInstruction>(root)) {
906-
SILInstruction *inst = root->getDefiningInstruction();
902+
if (auto *inst = root->getDefiningInstruction()) {
903+
if (ForwardingInstruction::canForwardFirstOperandOnly(inst)) {
904+
// The `enum` instruction can have no operand.
905+
if (inst->getNumOperands() == 0)
906+
return root;
907907

908-
// The `enum` instruction can have no operand.
909-
if (inst->getNumOperands() == 0)
910-
return root;
911-
912-
root = inst->getOperand(0);
913-
continue;
908+
root = inst->getOperand(0);
909+
continue;
910+
}
914911
}
915912
if (auto *termResult = SILArgument::isTerminatorResult(root)) {
916913
if (auto *oper = termResult->forwardedTerminatorResultOperand()) {

lib/SIL/Utils/OwnershipUtils.cpp

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -117,33 +117,36 @@ bool swift::canOpcodeForwardInnerGuaranteedValues(SILValue value) {
117117
if (auto *inst = value->getDefiningInstruction())
118118
if (auto *mixin = ForwardingInstruction::get(inst))
119119
return mixin->preservesOwnership() &&
120-
!isa<OwnedFirstArgForwardingSingleValueInst>(inst);
120+
!ForwardingInstruction::canForwardOwnedCompatibleValuesOnly(inst);
121121

122122
return false;
123123
}
124124

125125
bool swift::canOpcodeForwardInnerGuaranteedValues(Operand *use) {
126-
if (auto *mixin = ForwardingInstruction::get(use->getUser()))
127-
return mixin->preservesOwnership() &&
128-
!isa<OwnedFirstArgForwardingSingleValueInst>(use->getUser());
126+
if (auto *fwi = ForwardingInstruction::get(use->getUser()))
127+
return fwi->preservesOwnership() &&
128+
!ForwardingInstruction::canForwardOwnedCompatibleValuesOnly(
129+
use->getUser());
129130
return false;
130131
}
131132

132133
bool swift::canOpcodeForwardOwnedValues(SILValue value) {
133134
if (auto *inst = value->getDefiningInstructionOrTerminator()) {
134-
if (auto *mixin = ForwardingInstruction::get(inst)) {
135-
return mixin->preservesOwnership() &&
136-
!isa<GuaranteedFirstArgForwardingSingleValueInst>(inst);
135+
if (auto *fwi = ForwardingInstruction::get(inst)) {
136+
return fwi->preservesOwnership() &&
137+
!ForwardingInstruction::canForwardGuaranteedCompatibleValuesOnly(
138+
inst);
137139
}
138140
}
139141
return false;
140142
}
141143

142144
bool swift::canOpcodeForwardOwnedValues(Operand *use) {
143145
auto *user = use->getUser();
144-
if (auto *mixin = ForwardingInstruction::get(user))
145-
return mixin->preservesOwnership() &&
146-
!isa<GuaranteedFirstArgForwardingSingleValueInst>(user);
146+
if (auto *fwi = ForwardingInstruction::get(user))
147+
return fwi->preservesOwnership() &&
148+
!ForwardingInstruction::canForwardGuaranteedCompatibleValuesOnly(
149+
user);
147150
return false;
148151
}
149152

@@ -1717,17 +1720,11 @@ bool swift::visitForwardedGuaranteedOperands(
17171720
if (inst->getNumRealOperands() == 0) {
17181721
return false;
17191722
}
1720-
if (isa<FirstArgOwnershipForwardingSingleValueInst>(inst) ||
1721-
isa<OwnershipForwardingConversionInst>(inst) ||
1722-
isa<OwnershipForwardingSelectEnumInstBase>(inst) ||
1723-
isa<OwnershipForwardingMultipleValueInstruction>(inst)) {
1724-
assert(!isa<SingleValueInstruction>(inst)
1725-
|| !BorrowedValue(cast<SingleValueInstruction>(inst))
1726-
&& "forwarded operand cannot begin a borrow scope");
1723+
if (ForwardingInstruction::canForwardFirstOperandOnly(inst)) {
17271724
visitOperand(&inst->getOperandRef(0));
17281725
return true;
17291726
}
1730-
if (isa<AllArgOwnershipForwardingSingleValueInst>(inst)) {
1727+
if (ForwardingInstruction::canForwardAllOperands(inst)) {
17311728
assert(inst->getNumOperands() > 0 && "checked above");
17321729
assert(inst->getNumOperands() == inst->getNumRealOperands() &&
17331730
"mixin expects all readl operands");

lib/SIL/Verifier/SILVerifier.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1355,14 +1355,14 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
13551355
ValueOwnershipKind ownership =
13561356
ForwardingInstruction::get(i)->getForwardingOwnershipKind();
13571357

1358-
if (auto *o = dyn_cast<OwnedFirstArgForwardingSingleValueInst>(i)) {
1358+
if (ForwardingInstruction::canForwardOwnedCompatibleValuesOnly(i)) {
13591359
ValueOwnershipKind kind = OwnershipKind::Owned;
13601360
require(kind.isCompatibleWith(ownership),
13611361
"OwnedFirstArgForwardingSingleValueInst's ownership kind must be "
13621362
"compatible with owned");
13631363
}
13641364

1365-
if (auto *o = dyn_cast<GuaranteedFirstArgForwardingSingleValueInst>(i)) {
1365+
if (ForwardingInstruction::canForwardGuaranteedCompatibleValuesOnly(i)) {
13661366
ValueOwnershipKind kind = OwnershipKind::Guaranteed;
13671367
require(kind.isCompatibleWith(ownership),
13681368
"GuaranteedFirstArgForwardingSingleValueInst's ownership kind "

lib/SILOptimizer/SILCombiner/SILCombine.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -440,8 +440,7 @@ bool SILCombiner::doOneIteration(SILFunction &F, unsigned Iteration) {
440440
// owned parameters since chains of these values will be in the same
441441
// block.
442442
if (auto *svi = dyn_cast<SingleValueInstruction>(I)) {
443-
if ((isa<FirstArgOwnershipForwardingSingleValueInst>(svi) ||
444-
isa<OwnershipForwardingConversionInst>(svi)) &&
443+
if (ForwardingInstruction::canForwardFirstOperandOnly(svi) &&
445444
SILValue(svi)->getOwnershipKind() == OwnershipKind::Owned) {
446445
// Try to sink the value. If we sank the value and deleted it,
447446
// continue. If we didn't optimize or sank but we are still able to

lib/SILOptimizer/Utils/CanonicalizeBorrowScope.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,6 @@ static void deleteCopyAndMoveChain(SILValue v, InstructionDeleter &deleter) {
7878
/// OwnershipForwardingConversionInst (all kinds of ref casts)
7979
/// OwnershipForwardingMultipleValueInstruction
8080
/// (DestructureStruct, DestructureTuple)
81-
/// AllArgOwnershipForwardingSingleValueInst
82-
/// (Struct, Tuple)
8381
/// FirstArgOwnershipForwardingSingleValueInst
8482
/// (Object, Enum, UncheckedEnumData, Open/InitExistentialRef,
8583
/// MarkDependence)
@@ -96,7 +94,7 @@ bool CanonicalizeBorrowScope::isRewritableOSSAForward(SILInstruction *inst) {
9694
if (inst->getNumOperands() != 1)
9795
return false;
9896

99-
if (isa<OwnershipForwardingSingleValueInstruction>(inst)
97+
if (isa<OwnershipForwardingSingleValueInstruction>(inst) ||
10098
isa<OwnershipForwardingConversionInst>(inst) ||
10199
isa<OwnershipForwardingMultipleValueInstruction>(inst)) {
102100
Operand *forwardedOper = &inst->getOperandRef(0);

lib/SILOptimizer/Utils/InstOptUtils.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1803,8 +1803,10 @@ SILValue swift::makeValueAvailable(SILValue value, SILBasicBlock *inBlock) {
18031803

18041804
bool swift::tryEliminateOnlyOwnershipUsedForwardingInst(
18051805
SingleValueInstruction *forwardingInst, InstModCallbacks &callbacks) {
1806-
if (!ForwardingInstruction::isa(forwardingInst) ||
1807-
isa<AllArgOwnershipForwardingSingleValueInst>(forwardingInst))
1806+
if (!ForwardingInstruction::isa(forwardingInst))
1807+
return false;
1808+
1809+
if (ForwardingInstruction::canForwardAllOperands(forwardingInst))
18081810
return false;
18091811

18101812
SmallVector<Operand *, 32> worklist(getNonDebugUses(forwardingInst));

0 commit comments

Comments
 (0)