Skip to content

Commit cdd798b

Browse files
authored
Merge pull request #30319 from gottesmm/pr-9df4a4957e5ff72c67e090d3880070d8cd472328
[semantic-arc-opts] Follow ups to #30289
2 parents 29ff0ea + 09cfcbf commit cdd798b

File tree

1 file changed

+31
-29
lines changed

1 file changed

+31
-29
lines changed

Diff for: lib/SILOptimizer/Transforms/SemanticARCOpts.cpp

+31-29
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,13 @@ class LiveRange {
5454
/// A list of destroy_values of the live range.
5555
SmallVector<Operand *, 2> destroyingUses;
5656

57-
/// A list of forwarding instructions that forward our destroys ownership, but
58-
/// that are also able to forward guaranteed ownership.
59-
SmallVector<Operand *, 2> generalForwardingUses;
57+
/// A list of forwarding instructions that forward owned ownership, but that
58+
/// are also able to be converted to guaranteed ownership. If we are able to
59+
/// eliminate this LiveRange due to it being from a guaranteed value, we must
60+
/// flip the ownership of all of these instructions to guaranteed from owned.
61+
///
62+
/// Corresponds to isOwnershipForwardingInst(...).
63+
SmallVector<Operand *, 2> ownershipForwardingUses;
6064

6165
/// Consuming uses that we were not able to understand as a forwarding
6266
/// instruction or a destroy_value. These must be passed a strongly control
@@ -80,8 +84,7 @@ class LiveRange {
8084
/// Semantically this implies that a value is never passed off as +1 to memory
8185
/// or another function implying it can be used everywhere at +0.
8286
HasConsumingUse_t
83-
hasConsumingUse(FrozenMultiMap<SILPhiArgument *, OwnedValueIntroducer>
84-
*phiToIncomingValueMultiMap = nullptr) const;
87+
hasUnknownConsumingUse(bool assumingFixedPoint = false) const;
8588

8689
ArrayRef<Operand *> getDestroyingUses() const { return destroyingUses; }
8790

@@ -113,8 +116,8 @@ class LiveRange {
113116

114117
OwnedValueIntroducer getIntroducer() const { return introducer; }
115118

116-
ArrayRef<Operand *> getNonConsumingForwardingUses() const {
117-
return generalForwardingUses;
119+
ArrayRef<Operand *> getOwnershipForwardingUses() const {
120+
return ownershipForwardingUses;
118121
}
119122

120123
void convertOwnedGeneralForwardingUsesToGuaranteed();
@@ -185,7 +188,7 @@ LiveRange::DestroyingInstsRange LiveRange::getDestroyingInsts() const {
185188

186189
LiveRange::LiveRange(SILValue value)
187190
: introducer(*OwnedValueIntroducer::get(value)), destroyingUses(),
188-
generalForwardingUses(), unknownConsumingUses() {
191+
ownershipForwardingUses(), unknownConsumingUses() {
189192
assert(introducer.value.getOwnershipKind() == ValueOwnershipKind::Owned);
190193

191194
// We know that our silvalue produces an @owned value. Look through all of our
@@ -246,7 +249,7 @@ LiveRange::LiveRange(SILValue value)
246249

247250
// Ok, this is a forwarding instruction whose ownership we can flip from
248251
// owned -> guaranteed.
249-
generalForwardingUses.push_back(op);
252+
ownershipForwardingUses.push_back(op);
250253

251254
// If we have a non-terminator, just visit its users recursively to see if
252255
// the the users force the live range to be alive.
@@ -336,8 +339,8 @@ void LiveRange::insertEndBorrowsAtDestroys(
336339
}
337340

338341
void LiveRange::convertOwnedGeneralForwardingUsesToGuaranteed() {
339-
while (!generalForwardingUses.empty()) {
340-
auto *i = generalForwardingUses.pop_back_val()->getUser();
342+
while (!ownershipForwardingUses.empty()) {
343+
auto *i = ownershipForwardingUses.pop_back_val()->getUser();
341344

342345
// If this is a term inst, just convert all of its incoming values that are
343346
// owned to be guaranteed.
@@ -436,9 +439,8 @@ void LiveRange::convertArgToGuaranteed(DeadEndBlocks &deadEndBlocks,
436439
convertOwnedGeneralForwardingUsesToGuaranteed();
437440
}
438441

439-
LiveRange::HasConsumingUse_t LiveRange::hasConsumingUse(
440-
FrozenMultiMap<SILPhiArgument *, OwnedValueIntroducer>
441-
*phiToIncomingValueMultiMap) const {
442+
LiveRange::HasConsumingUse_t
443+
LiveRange::hasUnknownConsumingUse(bool assumingAtFixPoint) const {
442444
// First do a quick check if we have /any/ unknown consuming
443445
// uses. If we do not have any, return false early.
444446
if (unknownConsumingUses.empty()) {
@@ -447,7 +449,7 @@ LiveRange::HasConsumingUse_t LiveRange::hasConsumingUse(
447449

448450
// Ok, we do have some unknown consuming uses. If we aren't asked to
449451
// update phiToIncomingValueMultiMap, then just return true quickly.
450-
if (!phiToIncomingValueMultiMap) {
452+
if (!assumingAtFixPoint) {
451453
return HasConsumingUse_t::Yes;
452454
}
453455

@@ -828,7 +830,6 @@ static bool canEliminatePhi(
828830
if (!introducer.isConvertableToGuaranteed()) {
829831
return false;
830832
}
831-
832833
// If this linear search is too slow, we can change the
833834
// multimap to sort the mapped to list by pointer
834835
// instead of insertion order. In such a case, we could
@@ -870,17 +871,17 @@ bool SemanticARCOptVisitor::performPostPeepholeOwnedArgElimination() {
870871
// First compute the LiveRange for our phi argument. For simplicity, we only
871872
// handle cases now where our phi argument does not have any phi unknown
872873
// consumers.
873-
SILPhiArgument *phiArg = pair.first;
874-
LiveRange phiArgLiveRange(phiArg);
875-
if (bool(phiArgLiveRange.hasConsumingUse())) {
874+
SILPhiArgument *phi = pair.first;
875+
LiveRange phiLiveRange(phi);
876+
if (bool(phiLiveRange.hasUnknownConsumingUse())) {
876877
continue;
877878
}
878879

879880
// Ok, we know that our phi argument /could/ be converted to guaranteed if
880881
// our incoming values are able to be converted to guaranteed. Now for each
881882
// incoming value, compute the incoming values ownership roots and see if
882883
// all of the ownership roots are in our owned incoming value array.
883-
if (!phiArg->getIncomingPhiOperands(incomingValueOperandList)) {
884+
if (!phi->getIncomingPhiOperands(incomingValueOperandList)) {
884885
continue;
885886
}
886887

@@ -903,7 +904,7 @@ bool SemanticARCOptVisitor::performPostPeepholeOwnedArgElimination() {
903904
for (Operand *incomingValueOperand : incomingValueOperandList) {
904905
originalIncomingValues.push_back(incomingValueOperand->get());
905906
SILType type = incomingValueOperand->get()->getType();
906-
auto *undef = SILUndef::get(type, *phiArg->getFunction());
907+
auto *undef = SILUndef::get(type, *phi->getFunction());
907908
incomingValueOperand->set(undef);
908909
}
909910

@@ -956,7 +957,7 @@ bool SemanticARCOptVisitor::performPostPeepholeOwnedArgElimination() {
956957
}
957958

958959
// Then convert the phi's live range to be guaranteed.
959-
std::move(phiArgLiveRange)
960+
std::move(phiLiveRange)
960961
.convertArgToGuaranteed(getDeadEndBlocks(), lifetimeFrontier,
961962
getCallbacks());
962963

@@ -980,7 +981,7 @@ bool SemanticARCOptVisitor::performPostPeepholeOwnedArgElimination() {
980981

981982
madeChange = true;
982983
if (VerifyAfterTransform) {
983-
phiArg->getFunction()->verify();
984+
phi->getFunction()->verify();
984985
}
985986
}
986987

@@ -1175,9 +1176,9 @@ bool SemanticARCOptVisitor::performGuaranteedCopyValueOptimization(CopyValueInst
11751176
// forwarding or a user that truly represents a necessary consume of the value
11761177
// (e.x. storing into memory).
11771178
LiveRange lr(cvi);
1178-
auto hasConsumingUseState =
1179-
lr.hasConsumingUse(getPhiToIncomingValueMultiMap());
1180-
if (hasConsumingUseState == LiveRange::HasConsumingUse_t::Yes) {
1179+
auto hasUnknownConsumingUseState =
1180+
lr.hasUnknownConsumingUse(getPhiToIncomingValueMultiMap());
1181+
if (hasUnknownConsumingUseState == LiveRange::HasConsumingUse_t::Yes) {
11811182
return false;
11821183
}
11831184

@@ -1286,7 +1287,8 @@ bool SemanticARCOptVisitor::performGuaranteedCopyValueOptimization(CopyValueInst
12861287
// was consumed, the hasConsumedUse code updated phiToIncomingValueMultiMap
12871288
// for us before returning its prognosis. After we reach a fixed point, we
12881289
// will try to eliminate this value then.
1289-
if (hasConsumingUseState == LiveRange::HasConsumingUse_t::YesButAllPhiArgs) {
1290+
if (hasUnknownConsumingUseState ==
1291+
LiveRange::HasConsumingUse_t::YesButAllPhiArgs) {
12901292
auto *op = lr.getSingleUnknownConsumingUse();
12911293
assert(op);
12921294
unsigned opNum = op->getOperandNumber();
@@ -1302,7 +1304,7 @@ bool SemanticARCOptVisitor::performGuaranteedCopyValueOptimization(CopyValueInst
13021304

13031305
auto *arg = succBlock->getSILPhiArguments()[opNum];
13041306
LiveRange phiArgLR(arg);
1305-
if (bool(phiArgLR.hasConsumingUse())) {
1307+
if (bool(phiArgLR.hasUnknownConsumingUse())) {
13061308
return false;
13071309
}
13081310

@@ -1784,7 +1786,7 @@ bool SemanticARCOptVisitor::visitLoadInst(LoadInst *li) {
17841786
// -> load_borrow if we can put a copy_value on a cold path and thus
17851787
// eliminate RR traffic on a hot path.
17861788
LiveRange lr(li);
1787-
if (bool(lr.hasConsumingUse()))
1789+
if (bool(lr.hasUnknownConsumingUse()))
17881790
return false;
17891791

17901792
// Then check if our address is ever written to. If it is, then we cannot use

0 commit comments

Comments
 (0)