Skip to content

Commit 71107fb

Browse files
committed
WIP: [CanOSSALifetime] Fwding consume -> borrow.
When none of the uses are consuming.
1 parent a7eb82a commit 71107fb

File tree

6 files changed

+467
-21
lines changed

6 files changed

+467
-21
lines changed

include/swift/SILOptimizer/Utils/CanonicalizeOSSALifetime.h

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -133,17 +133,38 @@ void diagnoseRequiredCopyOfMoveOnly(Operand *use,
133133
/// This result remains valid during copy rewriting. The only instructions
134134
/// referenced it contains are consumes that cannot be deleted.
135135
class CanonicalOSSAConsumeInfo final {
136+
public:
137+
struct ForwardRewriteInfo {
138+
CopyValueInst *def = nullptr;
139+
SmallVector<Operand *, 4> borrowedOperands;
140+
SmallVector<SILInstruction *, 4> users;
141+
SmallPtrSetVector<Operand *, 4> operands;
142+
SmallVector<DestroyValueInst *, 4> destroys;
143+
};
144+
145+
private:
136146
/// Map blocks on the lifetime boundary to the last consuming instruction.
137147
llvm::SmallDenseMap<SILBasicBlock *, SILInstruction *, 4> finalBlockConsumes;
138148

139149
/// The instructions on the availability boundary of the dead-end region where
140150
/// this value is not consumed.
141151
SmallPtrSet<SILInstruction *, 4> unreachableLifetimeEnds;
142152

153+
SmallVector<ForwardRewriteInfo, 4> forwards;
154+
143155
public:
144-
void clear() { finalBlockConsumes.clear(); }
156+
void clear() {
157+
finalBlockConsumes.clear();
158+
unreachableLifetimeEnds.clear();
159+
forwards.clear();
160+
}
145161

146-
bool empty() { return finalBlockConsumes.empty(); }
162+
// FIXME: FIXME_NOW: Avoid this copy.
163+
void recordForward(ForwardRewriteInfo forward) {
164+
forwards.push_back(forward);
165+
}
166+
167+
ArrayRef<ForwardRewriteInfo> getForwards() { return forwards; }
147168

148169
bool hasUnclaimedConsumes() const { return !finalBlockConsumes.empty(); }
149170

@@ -279,6 +300,8 @@ class CanonicalizeOSSALifetime final {
279300
/// repeatedly do use-def walks from destroys).
280301
SmallPtrSetVector<SILInstruction *, 8> destroys;
281302

303+
llvm::SmallSetVector<Operand *, 8> forwardingConsumes;
304+
282305
/// Information about consuming instructions discovered in this canonical OSSA
283306
/// lifetime.
284307
CanonicalOSSAConsumeInfo consumes;
@@ -331,19 +354,22 @@ class CanonicalizeOSSALifetime final {
331354
accessBlocks = nullptr;
332355
consumes.clear();
333356
destroys.clear();
357+
forwardingConsumes.clear();
358+
discoveredBlocks.clear();
334359

335360
currentDef = def;
336361

337-
if (maximizeLifetime || respectsDeinitBarriers()) {
338-
liveness->initializeDiscoveredBlocks(&discoveredBlocks);
339-
}
362+
// if (maximizeLifetime || respectsDeinitBarriers()) {
363+
liveness->initializeDiscoveredBlocks(&discoveredBlocks);
364+
//}
340365
liveness->initializeDef(getCurrentDef());
341366
}
342367

343368
void clear() {
344369
consumingBlocks.clear();
345370
debugValues.clear();
346371
discoveredBlocks.clear();
372+
forwardingConsumes.clear();
347373
}
348374

349375
/// Top-Level API: rewrites copies and destroys within \p def's extended
@@ -420,6 +446,8 @@ class CanonicalizeOSSALifetime final {
420446

421447
void recordDebugValue(DebugValueInst *dvi) { debugValues.insert(dvi); }
422448

449+
void recordForwardingConsume(Operand *use) { forwardingConsumes.insert(use); }
450+
423451
void recordConsumingUse(Operand *use) { recordConsumingUser(use->getUser()); }
424452
/// Record that the value is consumed at `user`.
425453
///
@@ -450,6 +478,13 @@ class CanonicalizeOSSALifetime final {
450478
void insertDestroysOnBoundary(PrunedLivenessBoundary const &boundary);
451479

452480
void rewriteCopies();
481+
void addForwardingConsumesToLiveness();
482+
bool addForwardingConsumeToLiveness(
483+
CopyValueInst *cvi, CanonicalOSSAConsumeInfo::ForwardRewriteInfo &info);
484+
485+
void rewriteForwardingConsumes();
486+
void rewriteForwardingConsume(
487+
CanonicalOSSAConsumeInfo::ForwardRewriteInfo const &info);
453488
};
454489

455490
} // end namespace swift

lib/SIL/Utils/OwnershipUtils.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1432,8 +1432,8 @@ void ForwardingOperand::setForwardingOwnershipKind(
14321432
continue;
14331433

14341434
for (auto *succArg : succBlock->getSILPhiArguments()) {
1435-
// If we have an any value, just continue.
1436-
if (!succArg->getType().isTrivial(*ofti->getFunction()))
1435+
// If we have any trivial value, just continue.
1436+
if (succArg->getType().isTrivial(*ofti->getFunction()))
14371437
continue;
14381438
succArg->setOwnershipKind(newKind);
14391439
}

lib/SIL/Verifier/SILOwnershipVerifier.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,12 @@ bool SILValueOwnershipChecker::gatherUsers(
454454
auto *succArg = succBlock->getArgument(0);
455455

456456
auto succArgOwnershipKind = succArg->getOwnershipKind();
457-
assert(succArgOwnershipKind.isCompatibleWith(OwnershipKind::Guaranteed));
457+
if (!succArgOwnershipKind.isCompatibleWith(OwnershipKind::Guaranteed)) {
458+
llvm::errs() << "OwnershipKind incompatible with ::Guaranteed!\n"
459+
<< "Argument: " << *succArg << '\n'
460+
<< "Ownership:" << succArgOwnershipKind.asString() << '\n';
461+
assert(false);
462+
}
458463

459464
// If we have an any value, just continue.
460465
if (succArgOwnershipKind == OwnershipKind::None)

0 commit comments

Comments
 (0)