Skip to content

Commit 93c42f7

Browse files
authored
Merge pull request #68370 from meg-gupta/fwdops
Add new apis to ForwardingOperation
2 parents 68d146e + bacfdbd commit 93c42f7

File tree

5 files changed

+60
-41
lines changed

5 files changed

+60
-41
lines changed

include/swift/SIL/InstWrappers.h

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -252,44 +252,34 @@ class ForwardingOperation {
252252
ValueOwnershipKind getForwardingOwnershipKind();
253253
bool preservesOwnership();
254254

255-
// FIXME: Find a better name. Even unary instructions like struct_extract
256-
// forward "all" operands.
257-
bool canForwardAllOperands() const {
255+
Operand *getSingleForwardingOperand() const {
258256
switch (forwardingInst->getKind()) {
259257
case SILInstructionKind::StructInst:
260258
case SILInstructionKind::TupleInst:
261259
case SILInstructionKind::LinearFunctionInst:
262260
case SILInstructionKind::DifferentiableFunctionInst:
263-
return true;
261+
return nullptr;
264262
default:
265-
return false;
263+
if (forwardingInst->getNumRealOperands() == 0) {
264+
// This can happen with enum instructions that have no payload.
265+
return nullptr;
266+
}
267+
return &forwardingInst->getOperandRef(0);
266268
}
267269
}
268270

269-
// FIXME: Find a better name. Even instructions that forward all operands can
270-
// forward the first operand.
271-
bool canForwardFirstOperandOnly() const {
272-
return !canForwardAllOperands() && forwardingInst->getNumRealOperands() > 0;
273-
}
274-
275271
ArrayRef<Operand> getForwardedOperands() const {
276-
if (canForwardAllOperands()) {
277-
return forwardingInst->getAllOperands();
272+
if (auto *singleForwardingOp = getSingleForwardingOperand()) {
273+
return *singleForwardingOp;
278274
}
279-
if (canForwardFirstOperandOnly()) {
280-
return forwardingInst->getOperandRef(0);
281-
}
282-
return {};
275+
return forwardingInst->getAllOperands();
283276
}
284277

285278
MutableArrayRef<Operand> getForwardedOperands() {
286-
if (canForwardAllOperands()) {
287-
return forwardingInst->getAllOperands();
288-
}
289-
if (canForwardFirstOperandOnly()) {
290-
return forwardingInst->getOperandRef(0);
279+
if (auto *singleForwardingOp = getSingleForwardingOperand()) {
280+
return *singleForwardingOp;
291281
}
292-
return {};
282+
return forwardingInst->getAllOperands();
293283
}
294284

295285
bool canForwardOwnedCompatibleValuesOnly() {
@@ -321,6 +311,10 @@ class ForwardingOperation {
321311
/// Return true if the forwarded value is address-only either before or after
322312
/// forwarding.
323313
bool isAddressOnly() const;
314+
315+
// Call \p visitor on all forwarded results of the current forwarding
316+
// operation.
317+
bool visitForwardedValues(function_ref<bool(SILValue)> visitor);
324318
};
325319
} // end namespace swift
326320

lib/SIL/Utils/InstWrappers.cpp

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,39 @@ bool ForwardingOperation::hasSameRepresentation() const {
5959
}
6060

6161
bool ForwardingOperation::isAddressOnly() const {
62-
if (canForwardAllOperands()) {
63-
// All ForwardingInstructions that forward all operands are currently a
64-
// single value instruction.
65-
auto *aggregate =
66-
cast<OwnershipForwardingSingleValueInstruction>(forwardingInst);
67-
// If any of the operands are address-only, then the aggregate must be.
68-
return aggregate->getType().isAddressOnly(*forwardingInst->getFunction());
62+
if (auto *singleForwardingOp = getSingleForwardingOperand()) {
63+
return singleForwardingOp->get()->getType().isAddressOnly(
64+
*forwardingInst->getFunction());
6965
}
70-
return forwardingInst->getOperand(0)->getType().isAddressOnly(
71-
*forwardingInst->getFunction());
66+
// All ForwardingInstructions that forward all operands are currently a
67+
// single value instruction.
68+
auto *aggregate =
69+
cast<OwnershipForwardingSingleValueInstruction>(forwardingInst);
70+
// If any of the operands are address-only, then the aggregate must be.
71+
return aggregate->getType().isAddressOnly(*forwardingInst->getFunction());
7272
}
73+
74+
bool ForwardingOperation::visitForwardedValues(
75+
function_ref<bool(SILValue)> visitor) {
76+
if (auto *svi = dyn_cast<SingleValueInstruction>(forwardingInst)) {
77+
return visitor(svi);
78+
}
79+
if (auto *mvri = dyn_cast<MultipleValueInstruction>(forwardingInst)) {
80+
return llvm::all_of(mvri->getResults(), [&](SILValue value) {
81+
if (value->getOwnershipKind() == OwnershipKind::None)
82+
return true;
83+
return visitor(value);
84+
});
85+
}
86+
auto *ti = cast<TermInst>(forwardingInst);
87+
assert(ti->mayHaveTerminatorResult());
88+
return llvm::all_of(ti->getSuccessorBlocks(), [&](SILBasicBlock *succBlock) {
89+
// If we do not have any arguments, then continue.
90+
if (succBlock->args_empty())
91+
return true;
92+
93+
auto args = succBlock->getSILPhiArguments();
94+
assert(args.size() == 1 && "Transforming terminator with multiple args?!");
95+
return visitor(args[0]);
96+
});
97+
}

lib/SIL/Utils/MemAccessUtils.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -902,12 +902,8 @@ SILValue swift::findOwnershipReferenceAggregate(SILValue ref) {
902902

903903
if (auto *inst = root->getDefiningInstruction()) {
904904
if (auto fwdOp = ForwardingOperation(inst)) {
905-
if (fwdOp.canForwardFirstOperandOnly()) {
906-
// The `enum` instruction can have no operand.
907-
if (inst->getNumOperands() == 0)
908-
return root;
909-
910-
root = inst->getOperand(0);
905+
if (auto *singleForwardingOp = fwdOp.getSingleForwardingOperand()) {
906+
root = singleForwardingOp->get();
911907
continue;
912908
}
913909
}

lib/SILOptimizer/SILCombiner/SILCombine.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,7 @@ bool SILCombiner::doOneIteration(SILFunction &F, unsigned Iteration) {
441441
// block.
442442
if (auto *svi = dyn_cast<SingleValueInstruction>(I)) {
443443
if (auto fwdOp = ForwardingOperation(svi)) {
444-
if (fwdOp.canForwardFirstOperandOnly() &&
444+
if (fwdOp.getSingleForwardingOperand() &&
445445
SILValue(svi)->getOwnershipKind() == OwnershipKind::Owned) {
446446
// Try to sink the value. If we sank the value and deleted it,
447447
// continue. If we didn't optimize or sank but we are still able to

lib/SILOptimizer/Utils/InstOptUtils.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1806,7 +1806,11 @@ SILValue swift::makeValueAvailable(SILValue value, SILBasicBlock *inBlock) {
18061806
bool swift::tryEliminateOnlyOwnershipUsedForwardingInst(
18071807
SingleValueInstruction *forwardingInst, InstModCallbacks &callbacks) {
18081808
auto fwdOp = ForwardingOperation(forwardingInst);
1809-
if (!fwdOp || !fwdOp.canForwardFirstOperandOnly()) {
1809+
if (!fwdOp) {
1810+
return false;
1811+
}
1812+
auto *singleFwdOp = fwdOp.getSingleForwardingOperand();
1813+
if (!singleFwdOp) {
18101814
return false;
18111815
}
18121816

@@ -1831,7 +1835,7 @@ bool swift::tryEliminateOnlyOwnershipUsedForwardingInst(
18311835

18321836
// Now that we know we can perform our transform, set all uses of
18331837
// forwardingInst to be used of its operand and then delete \p forwardingInst.
1834-
auto newValue = forwardingInst->getOperand(0);
1838+
auto newValue = singleFwdOp->get();
18351839
while (!forwardingInst->use_empty()) {
18361840
auto *use = *(forwardingInst->use_begin());
18371841
use->set(newValue);

0 commit comments

Comments
 (0)