[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:
Michael Gottesman
2019-01-30 16:40:42 -08:00
parent 87b66e79a7
commit ed1cd46d25
16 changed files with 1919 additions and 70 deletions

View File

@@ -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;
}
}