mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[ownership] Update devirtualization utilities for ownership.
I discovered this due to the mandatory inliner doing devirtualization. I ported all of the relevant SIL tests to increase code coverage of this code when ownership is enabled.
This commit is contained in:
@@ -22,15 +22,30 @@
|
||||
|
||||
using namespace swift;
|
||||
|
||||
SILValue swift::stripOwnershipInsts(SILValue v) {
|
||||
while (true) {
|
||||
switch (v->getKind()) {
|
||||
default:
|
||||
return v;
|
||||
case ValueKind::CopyValueInst:
|
||||
case ValueKind::BeginBorrowInst:
|
||||
v = cast<SingleValueInstruction>(v)->getOperand(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Strip off casts/indexing insts/address projections from V until there is
|
||||
/// nothing left to strip.
|
||||
/// FIXME: Why don't we strip projections after stripping indexes?
|
||||
SILValue swift::getUnderlyingObject(SILValue V) {
|
||||
SILValue swift::getUnderlyingObject(SILValue v) {
|
||||
while (true) {
|
||||
SILValue V2 = stripIndexingInsts(stripAddressProjections(stripCasts(V)));
|
||||
if (V2 == V)
|
||||
return V2;
|
||||
V = V2;
|
||||
SILValue v2 = stripCasts(v);
|
||||
v2 = stripAddressProjections(v2);
|
||||
v2 = stripIndexingInsts(v2);
|
||||
v2 = stripOwnershipInsts(v2);
|
||||
if (v2 == v)
|
||||
return v2;
|
||||
v = v2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,12 +71,15 @@ SILValue swift::getUnderlyingAddressRoot(SILValue V) {
|
||||
}
|
||||
|
||||
|
||||
SILValue swift::getUnderlyingObjectStopAtMarkDependence(SILValue V) {
|
||||
SILValue swift::getUnderlyingObjectStopAtMarkDependence(SILValue v) {
|
||||
while (true) {
|
||||
SILValue V2 = stripIndexingInsts(stripAddressProjections(stripCastsWithoutMarkDependence(V)));
|
||||
if (V2 == V)
|
||||
return V2;
|
||||
V = V2;
|
||||
SILValue v2 = stripCastsWithoutMarkDependence(v);
|
||||
v2 = stripAddressProjections(v2);
|
||||
v2 = stripIndexingInsts(v2);
|
||||
v2 = stripOwnershipInsts(v2);
|
||||
if (v2 == v)
|
||||
return v2;
|
||||
v = v2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,47 +156,68 @@ SILValue swift::stripCastsWithoutMarkDependence(SILValue V) {
|
||||
}
|
||||
}
|
||||
|
||||
SILValue swift::stripCasts(SILValue V) {
|
||||
SILValue swift::stripCasts(SILValue v) {
|
||||
while (true) {
|
||||
V = stripSinglePredecessorArgs(V);
|
||||
v = stripSinglePredecessorArgs(v);
|
||||
|
||||
auto K = V->getKind();
|
||||
if (isRCIdentityPreservingCast(K)
|
||||
|| K == ValueKind::UncheckedTrivialBitCastInst
|
||||
|| K == ValueKind::MarkDependenceInst) {
|
||||
V = cast<SingleValueInstruction>(V)->getOperand(0);
|
||||
auto k = v->getKind();
|
||||
if (isRCIdentityPreservingCast(k)
|
||||
|| k == ValueKind::UncheckedTrivialBitCastInst
|
||||
|| k == ValueKind::MarkDependenceInst) {
|
||||
v = cast<SingleValueInstruction>(v)->getOperand(0);
|
||||
continue;
|
||||
}
|
||||
|
||||
return V;
|
||||
|
||||
SILValue v2 = stripOwnershipInsts(v);
|
||||
if (v2 != v) {
|
||||
v = v2;
|
||||
continue;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
SILValue swift::stripUpCasts(SILValue V) {
|
||||
assert(V->getType().isClassOrClassMetatype() &&
|
||||
SILValue swift::stripUpCasts(SILValue v) {
|
||||
assert(v->getType().isClassOrClassMetatype() &&
|
||||
"Expected class or class metatype!");
|
||||
|
||||
V = stripSinglePredecessorArgs(V);
|
||||
v = stripSinglePredecessorArgs(v);
|
||||
|
||||
while (auto upcast = dyn_cast<UpcastInst>(V))
|
||||
V = stripSinglePredecessorArgs(upcast->getOperand());
|
||||
|
||||
return V;
|
||||
while (true) {
|
||||
if (auto *ui = dyn_cast<UpcastInst>(v)) {
|
||||
v = ui->getOperand();
|
||||
continue;
|
||||
}
|
||||
|
||||
SILValue v2 = stripSinglePredecessorArgs(v);
|
||||
v2 = stripOwnershipInsts(v2);
|
||||
if (v2 == v) {
|
||||
return v2;
|
||||
}
|
||||
v = v2;
|
||||
}
|
||||
}
|
||||
|
||||
SILValue swift::stripClassCasts(SILValue V) {
|
||||
SILValue swift::stripClassCasts(SILValue v) {
|
||||
while (true) {
|
||||
if (auto *UI = dyn_cast<UpcastInst>(V)) {
|
||||
V = UI->getOperand();
|
||||
if (auto *ui = dyn_cast<UpcastInst>(v)) {
|
||||
v = ui->getOperand();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (auto *UCCI = dyn_cast<UnconditionalCheckedCastInst>(V)) {
|
||||
V = UCCI->getOperand();
|
||||
if (auto *ucci = dyn_cast<UnconditionalCheckedCastInst>(v)) {
|
||||
v = ucci->getOperand();
|
||||
continue;
|
||||
}
|
||||
|
||||
return V;
|
||||
|
||||
SILValue v2 = stripOwnershipInsts(v);
|
||||
if (v2 != v) {
|
||||
v = v2;
|
||||
continue;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user