Skip to content

Commit 898c0c0

Browse files
committed
- strict rules
1 parent 004020b commit 898c0c0

File tree

14 files changed

+80
-27
lines changed

14 files changed

+80
-27
lines changed

SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/SimplifyBranch.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,15 @@ private extension BranchInst {
4949
let parentBB = parentBlock
5050

5151
for (argIdx, op) in operands.enumerated() {
52-
targetBB.arguments[argIdx].uses.replaceAll(with: op.value, context)
52+
let arg = targetBB.arguments[argIdx]
53+
if let phi = Phi(arg),
54+
let bfi = phi.borrowedFrom
55+
{
56+
bfi.uses.replaceAll(with: op.value, context)
57+
context.erase(instruction: bfi)
58+
} else {
59+
arg.uses.replaceAll(with: op.value, context)
60+
}
5361
}
5462
targetBB.eraseAllArguments(context)
5563

SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/SimplifySwitchEnum.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,14 @@ extension SwitchEnumInst : OnoneSimplifyable {
4848
precondition(enumInst.payload == nil || !parentFunction.hasOwnership,
4949
"missing payload argument in switch_enum case block")
5050
builder.createBranch(to: caseBlock)
51+
context.erase(instruction: self)
5152
case 1:
5253
builder.createBranch(to: caseBlock, arguments: [enumInst.payload!])
54+
context.erase(instruction: self)
55+
updateBorrowedFrom(for: [Phi(caseBlock.arguments[0])!], context)
5356
default:
5457
fatalError("case block of switch_enum cannot have more than 1 argument")
5558
}
56-
context.erase(instruction: self)
5759

5860
if canEraseEnumInst {
5961
context.erase(instructionIncludingDebugUses: enumInst)

SwiftCompilerSources/Sources/Optimizer/Utilities/BorrowUtils.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,7 @@ func gatherEnclosingValues(for value: Value,
534534
// There is no enclosing value on this path.
535535
break
536536
case .reborrow(let phi):
537-
enclosingValues.append(contentsOf: phi.borrowedFrom.enclosingValues)
537+
enclosingValues.append(contentsOf: phi.borrowedFrom!.enclosingValues)
538538
}
539539
} else {
540540
// Handle forwarded guaranteed values.

SwiftCompilerSources/Sources/Optimizer/Utilities/BorrowedFromUpdater.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,19 @@ func updateBorrowedFrom(for phis: some Sequence<Phi>, _ context: some MutatingCo
3535
if !phi.value.parentFunction.hasOwnership {
3636
return
3737
}
38-
createBorrowedFrom(for: phi, context)
38+
if phi.value.ownership == .guaranteed {
39+
createBorrowedFrom(for: phi, context)
40+
}
3941
}
4042

4143
var changed: Bool
4244
repeat {
4345
changed = false
4446

4547
for phi in phis {
46-
changed = updateBorrowedFrom(for: phi, context) || changed
48+
if phi.value.ownership == .guaranteed {
49+
changed = updateBorrowedFrom(for: phi, context) || changed
50+
}
4751
}
4852
} while changed
4953
}

SwiftCompilerSources/Sources/Optimizer/Utilities/Verifier.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,10 @@ extension BorrowedFromInst : VerifyableInstruction {
3737
var computedEVs = Stack<Value>(context)
3838
defer { computedEVs.deinitialize() }
3939

40-
if let phi = Phi(borrowedValue) {
41-
gatherEnclosingValuesFromPredecessors(for: phi, in: &computedEVs, context)
42-
} else {
43-
gatherEnclosingValues(for: borrowedValue, in: &computedEVs, context)
40+
guard let phi = Phi(borrowedValue) else {
41+
fatalError("borrowed value of borrowed-from must be a phi: \(self)")
4442
}
43+
gatherEnclosingValuesFromPredecessors(for: phi, in: &computedEVs, context)
4544

4645
var existingEVs = ValueSet(insertContentsOf: enclosingValues, context)
4746
defer { existingEVs.deinitialize() }
@@ -60,7 +59,8 @@ private extension Argument {
6059
for use in phi.value.uses {
6160
precondition(use.instruction is BorrowedFromInst,
6261
"guaranteed phi \(self) has non borrowed-from use \(use)")
63-
if use.forwardingBorrowedFromUser != nil {
62+
if use.index == 0 {
63+
precondition(!forwardingBorrowedFromFound, "phi \(self) has multiple forwarding borrowed-from uses")
6464
forwardingBorrowedFromFound = true
6565
}
6666
}

SwiftCompilerSources/Sources/SIL/Argument.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,13 +128,13 @@ public struct Phi {
128128
value.ownership == .owned || value.isReborrow
129129
}
130130

131-
public var borrowedFrom: BorrowedFromInst {
131+
public var borrowedFrom: BorrowedFromInst? {
132132
for use in value.uses {
133133
if let bfi = use.forwardingBorrowedFromUser {
134134
return bfi
135135
}
136136
}
137-
fatalError("phi argument doesn't have a borrowed-from user")
137+
return nil
138138
}
139139

140140
public static func ==(lhs: Phi, rhs: Phi) -> Bool {

include/swift/SIL/OwnershipUtils.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ inline bool isForwardingConsume(SILValue value) {
9090
// Ownership Def-Use Utilities
9191
//===----------------------------------------------------------------------===//
9292

93+
BorrowedFromInst *getBorrowedFromUser(SILValue v);
9394
SILValue lookThroughSingleBorrowedFromUser(SILValue v);
9495
SILValue lookThroughBorrowedFromDef(SILValue v);
9596
void getTransitiveConsumingUses(SILValue v, llvm::SmallVectorImpl<Operand *> &results);

include/swift/SIL/SILValue.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1071,8 +1071,11 @@ class Operand {
10711071
removeFromCurrent();
10721072
TheValueAndThreeBits.setPointer(newValue);
10731073
insertIntoCurrent();
1074+
verify();
10741075
}
10751076

1077+
void verify() const;
1078+
10761079
/// Swap the given operand with the current one.
10771080
void swap(Operand &Op) {
10781081
SILValue OtherV = Op.get();

lib/SIL/IR/SILValue.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,12 @@ llvm::raw_ostream &swift::operator<<(llvm::raw_ostream &os,
410410
// Operand
411411
//===----------------------------------------------------------------------===//
412412

413+
void Operand::verify() const {
414+
if (isa<BorrowedFromInst>(getUser()) && getOperandNumber() == 0) {
415+
assert(isa<SILArgument>(get()) || isa<SILUndef>(get()));
416+
}
417+
}
418+
413419
SILBasicBlock *Operand::getParentBlock() const {
414420
auto *self = const_cast<Operand *>(this);
415421
return self->getUser()->getParent();

lib/SIL/Utils/BasicBlockUtils.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "swift/Basic/STLExtras.h"
1717
#include "swift/SIL/Dominance.h"
1818
#include "swift/SIL/LoopInfo.h"
19+
#include "swift/SIL/OwnershipUtils.h"
1920
#include "swift/SIL/SILArgument.h"
2021
#include "swift/SIL/SILBasicBlock.h"
2122
#include "swift/SIL/SILBuilder.h"
@@ -345,8 +346,14 @@ void swift::mergeBasicBlockWithSingleSuccessor(SILBasicBlock *BB,
345346

346347
// If there are any BB arguments in the destination, replace them with the
347348
// branch operands, since they must dominate the dest block.
348-
for (unsigned i = 0, e = BI->getArgs().size(); i != e; ++i)
349-
succBB->getArgument(i)->replaceAllUsesWith(BI->getArg(i));
349+
for (unsigned i = 0, e = BI->getArgs().size(); i != e; ++i) {
350+
SILArgument *arg = succBB->getArgument(i);
351+
if (auto *bfi = getBorrowedFromUser(arg)) {
352+
bfi->replaceAllUsesWith(arg);
353+
bfi->eraseFromParent();
354+
}
355+
arg->replaceAllUsesWith(BI->getArg(i));
356+
}
350357

351358
BI->eraseFromParent();
352359

lib/SIL/Utils/OwnershipUtils.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -203,19 +203,20 @@ bool swift::computeIsGuaranteedForwarding(SILValue value) {
203203
return isGuaranteedForwardingPhi;
204204
}
205205

206-
SILValue swift::lookThroughSingleBorrowedFromUser(SILValue v) {
207-
BorrowedFromInst *singleBfi = nullptr;
206+
BorrowedFromInst *swift::getBorrowedFromUser(SILValue v) {
208207
for (auto *use : v->getUses()) {
209208
if (auto *bfi = dyn_cast<BorrowedFromInst>(use->getUser())) {
210209
if (use->getOperandNumber() == 0) {
211-
if (singleBfi)
212-
return v;
213-
singleBfi = bfi;
210+
return bfi;
214211
}
215212
}
216213
}
217-
if (singleBfi)
218-
return singleBfi;
214+
return nullptr;
215+
}
216+
217+
SILValue swift::lookThroughSingleBorrowedFromUser(SILValue v) {
218+
if (BorrowedFromInst *bfi = getBorrowedFromUser(v))
219+
return bfi;
219220
return v;
220221
}
221222

lib/SILOptimizer/LoopTransforms/LoopRotate.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,9 @@ bool swift::rotateLoop(SILLoop *loop, DominanceInfo *domInfo,
410410
}
411411

412412
for (auto &inst : *header) {
413-
if (SILInstruction *cloned = inst.clone(preheaderBranch)) {
413+
if (auto *bfi = dyn_cast<BorrowedFromInst>(&inst)) {
414+
valueMap[bfi] = valueMap[bfi->getBorrowedValue()];
415+
} else if (SILInstruction *cloned = inst.clone(preheaderBranch)) {
414416
mapOperands(cloned, valueMap);
415417

416418
// The actual operand will sort out which result idx to use.

lib/SILOptimizer/Transforms/SimplifyCFG.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1287,7 +1287,13 @@ bool SimplifyCFG::simplifyBranchBlock(BranchInst *BI) {
12871287
for (unsigned i = 0, e = BI->getArgs().size(); i != e; ++i) {
12881288
assert(DestBB->getArgument(i) != BI->getArg(i));
12891289
SILValue Val = BI->getArg(i);
1290-
DestBB->getArgument(i)->replaceAllUsesWith(Val);
1290+
SILValue arg = DestBB->getArgument(i);
1291+
if (auto *bfi = getBorrowedFromUser(arg)) {
1292+
bfi->replaceAllUsesWith(Val);
1293+
bfi->eraseFromParent();
1294+
} else {
1295+
arg->replaceAllUsesWith(Val);
1296+
}
12911297
if (!isVeryLargeFunction) {
12921298
if (auto *I = dyn_cast<SingleValueInstruction>(Val)) {
12931299
// Replacing operands may trigger constant folding which then could
@@ -1545,8 +1551,12 @@ bool SimplifyCFG::simplifyCondBrBlock(CondBranchInst *BI) {
15451551
// Erase in reverse order to pop each element as we go.
15461552
for (unsigned i = destBB->getArguments().size(); i != 0;) {
15471553
--i;
1548-
destBB->getArgument(i)->replaceAllUsesWith(
1549-
trampolineDest.newSourceBranchArgs[i]);
1554+
SILArgument *arg = destBB->getArgument(i);
1555+
if (auto *bfi = getBorrowedFromUser(arg)) {
1556+
bfi->replaceAllUsesWith(arg);
1557+
bfi->eraseFromParent();
1558+
}
1559+
arg->replaceAllUsesWith(trampolineDest.newSourceBranchArgs[i]);
15501560
destBB->eraseArgument(i);
15511561
}
15521562
};
@@ -3809,6 +3819,10 @@ static void tryToReplaceArgWithIncomingValue(SILBasicBlock *BB, unsigned i,
38093819
// An argument has one result value. We need to replace this with the *value*
38103820
// of the incoming block(s).
38113821
LLVM_DEBUG(llvm::dbgs() << "replace arg with incoming value:" << *A);
3822+
if (auto *bfi = getBorrowedFromUser(A)) {
3823+
bfi->replaceAllUsesWith(A);
3824+
bfi->eraseFromParent();
3825+
}
38123826
A->replaceAllUsesWith(V);
38133827
}
38143828

lib/SILOptimizer/Utils/CFGOptUtils.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "swift/SIL/SILArgument.h"
2020
#include "swift/SIL/SILBuilder.h"
2121
#include "swift/SIL/BasicBlockDatastructures.h"
22+
#include "swift/SIL/OwnershipUtils.h"
2223
#include "swift/SILOptimizer/Utils/InstOptUtils.h"
2324
#include "llvm/ADT/TinyPtrVector.h"
2425

@@ -142,8 +143,12 @@ TermInst *swift::deleteEdgeValue(TermInst *branch, SILBasicBlock *destBlock,
142143
void swift::erasePhiArgument(SILBasicBlock *block, unsigned argIndex,
143144
bool cleanupDeadPhiOps,
144145
InstModCallbacks callbacks) {
145-
assert(block->getArgument(argIndex)->isPhi()
146-
&& "Only should be used on phi arguments");
146+
SILArgument *arg = block->getArgument(argIndex);
147+
assert(arg->isPhi() && "Only should be used on phi arguments");
148+
if (auto *bfi = getBorrowedFromUser(arg)) {
149+
bfi->replaceAllUsesWith(arg);
150+
bfi->eraseFromParent();
151+
}
147152
block->eraseArgument(argIndex);
148153

149154
// Determine the set of predecessors in case any predecessor has

0 commit comments

Comments
 (0)