mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[rc-id] Address Andy's comments to r25339.
The only substantial change is that I was iterating over instructions to look for unchecked_enum_data. The only reason really to do that is to stop phase ordering issues with simplify-cfg, but it is really not necessary. Swift SVN r25359
This commit is contained in:
@@ -136,21 +136,6 @@ SILValue RCIdentityAnalysis::stripOneRCIdentityIncomingValue(SILArgument *A,
|
|||||||
/// anything.
|
/// anything.
|
||||||
static llvm::Optional<bool> proveNonPayloadedEnumCase(SILBasicBlock *BB,
|
static llvm::Optional<bool> proveNonPayloadedEnumCase(SILBasicBlock *BB,
|
||||||
SILValue RCIdentity) {
|
SILValue RCIdentity) {
|
||||||
// First iterate through all of the instructions in BB and see if we can find
|
|
||||||
// an unchecked_enum_data on RCIdentity.
|
|
||||||
|
|
||||||
// For each II in BB...
|
|
||||||
for (auto &II : *BB) {
|
|
||||||
// If we do not have a UEDI that is applied to RCIdentity, continue.
|
|
||||||
auto *UEDI = dyn_cast<UncheckedEnumDataInst>(&II);
|
|
||||||
if (!UEDI || UEDI->getOperand() != RCIdentity)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Otherwise, return true if UEDI is extracting a non-payloaded enum case
|
|
||||||
// and false otherwise.
|
|
||||||
return !UEDI->getElement()->hasArgumentType();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Then see if BB has one predecessor... if it does not, return None so we
|
// Then see if BB has one predecessor... if it does not, return None so we
|
||||||
// keep searching up the domtree.
|
// keep searching up the domtree.
|
||||||
SILBasicBlock *SinglePred = BB->getSinglePredecessor();
|
SILBasicBlock *SinglePred = BB->getSinglePredecessor();
|
||||||
@@ -166,7 +151,10 @@ static llvm::Optional<bool> proveNonPayloadedEnumCase(SILBasicBlock *BB,
|
|||||||
|
|
||||||
// Then return true if along the edge from the SEI to BB, RCIdentity has a
|
// Then return true if along the edge from the SEI to BB, RCIdentity has a
|
||||||
// non-payloaded enum value.
|
// non-payloaded enum value.
|
||||||
return !SEI->getUniqueCaseForDestination(BB)->hasArgumentType();
|
auto *Decl = SEI->getUniqueCaseForDestination(BB);
|
||||||
|
if (!Decl)
|
||||||
|
return None;
|
||||||
|
return !Decl->hasArgumentType();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RCIdentityAnalysis::
|
bool RCIdentityAnalysis::
|
||||||
@@ -185,6 +173,8 @@ findDominatingNonPayloadedEdge(SILBasicBlock *IncomingEdgeBB,
|
|||||||
// I think the only way this can happen is if we have a switch_enum of some
|
// I think the only way this can happen is if we have a switch_enum of some
|
||||||
// sort with multiple incoming values going into the destination BB. We are
|
// sort with multiple incoming values going into the destination BB. We are
|
||||||
// not interested in handling that case anyways.
|
// not interested in handling that case anyways.
|
||||||
|
//
|
||||||
|
// FIXME: If we ever split all critical edges, this should be relooked at.
|
||||||
if (IncomingEdgeBB == RCIdentityBB)
|
if (IncomingEdgeBB == RCIdentityBB)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -212,7 +202,7 @@ findDominatingNonPayloadedEdge(SILBasicBlock *IncomingEdgeBB,
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (auto *Node = DI->getNode(IncomingEdgeBB); Node; Node = Node->getIDom()) {
|
for (auto *Node = DI->getNode(IncomingEdgeBB); Node; Node = Node->getIDom()) {
|
||||||
// Search for uses of RCIdentity in Node->getBB() that will enable us to
|
// Search for uses of RCIdentity in Node->getBlock() that will enable us to
|
||||||
// know that it has a non-payloaded enum case.
|
// know that it has a non-payloaded enum case.
|
||||||
SILBasicBlock *DominatingBB = Node->getBlock();
|
SILBasicBlock *DominatingBB = Node->getBlock();
|
||||||
llvm::Optional<bool> Result =
|
llvm::Optional<bool> Result =
|
||||||
@@ -285,7 +275,7 @@ stripRCIdentityPreservingArgs(SILValue V, unsigned RecursionDepth) {
|
|||||||
// Ok, this is the first time that we have visited this BB. Get the
|
// Ok, this is the first time that we have visited this BB. Get the
|
||||||
// SILArgument's incoming values. If we don't have an incoming value for each
|
// SILArgument's incoming values. If we don't have an incoming value for each
|
||||||
// one of our predecessors, just return SILValue().
|
// one of our predecessors, just return SILValue().
|
||||||
llvm::SmallVector<SILValue, 8> IncomingValues;
|
llvm::SmallVector<std::pair<SILBasicBlock *, SILValue>, 8> IncomingValues;
|
||||||
if (!A->getIncomingValues(IncomingValues) || IncomingValues.empty()) {
|
if (!A->getIncomingValues(IncomingValues) || IncomingValues.empty()) {
|
||||||
return SILValue();
|
return SILValue();
|
||||||
}
|
}
|
||||||
@@ -295,14 +285,14 @@ stripRCIdentityPreservingArgs(SILValue V, unsigned RecursionDepth) {
|
|||||||
// If we only have one incoming value, just return the identity root of that
|
// If we only have one incoming value, just return the identity root of that
|
||||||
// incoming value. There can be no loop problems.
|
// incoming value. There can be no loop problems.
|
||||||
if (IVListSize == 1) {
|
if (IVListSize == 1) {
|
||||||
return IncomingValues[0];
|
return IncomingValues[0].second;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ok, we have multiple predecessors. First find the first non-payloaded enum.
|
// Ok, we have multiple predecessors. First find the first non-payloaded enum.
|
||||||
llvm::SmallVector<SILValue, 8> NoPayloadEnums;
|
llvm::SmallVector<SILBasicBlock *, 8> NoPayloadEnumBBs;
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
for (; i < IVListSize && isNoPayloadEnum(IncomingValues[i]); ++i) {
|
for (; i < IVListSize && isNoPayloadEnum(IncomingValues[i].second); ++i) {
|
||||||
NoPayloadEnums.push_back(IncomingValues[i]);
|
NoPayloadEnumBBs.push_back(IncomingValues[i].first);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we did not find any non-payloaded enum, there is no RC associated with
|
// If we did not find any non-payloaded enum, there is no RC associated with
|
||||||
@@ -310,16 +300,19 @@ stripRCIdentityPreservingArgs(SILValue V, unsigned RecursionDepth) {
|
|||||||
if (i == IVListSize)
|
if (i == IVListSize)
|
||||||
return SILValue();
|
return SILValue();
|
||||||
|
|
||||||
SILValue FirstIV = stripOneRCIdentityIncomingValue(A, IncomingValues[i]);
|
SILValue FirstIV =
|
||||||
|
stripOneRCIdentityIncomingValue(A, IncomingValues[i].second);
|
||||||
if (!FirstIV)
|
if (!FirstIV)
|
||||||
return SILValue();
|
return SILValue();
|
||||||
|
|
||||||
while (i < IVListSize) {
|
while (i < IVListSize) {
|
||||||
SILValue IV = IncomingValues[i++];
|
SILBasicBlock *IVBB;
|
||||||
|
SILValue IV;
|
||||||
|
std::tie(IVBB, IV) = IncomingValues[i++];
|
||||||
|
|
||||||
// If IV is a no payload enum, we don't care about it. Skip it.
|
// If IV is a no payload enum, we don't care about it. Skip it.
|
||||||
if (isNoPayloadEnum(IV)) {
|
if (isNoPayloadEnum(IV)) {
|
||||||
NoPayloadEnums.push_back(IV);
|
NoPayloadEnumBBs.push_back(IVBB);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,7 +329,7 @@ stripRCIdentityPreservingArgs(SILValue V, unsigned RecursionDepth) {
|
|||||||
// enums are equal to FirstIV after just stripping RCIdentical instructions
|
// enums are equal to FirstIV after just stripping RCIdentical instructions
|
||||||
// (*NOTE* not args). If we have no NonPayloadEnums, then we know that this
|
// (*NOTE* not args). If we have no NonPayloadEnums, then we know that this
|
||||||
// Arg's RCIdentity must be FirstIV.
|
// Arg's RCIdentity must be FirstIV.
|
||||||
if (NoPayloadEnums.empty())
|
if (NoPayloadEnumBBs.empty())
|
||||||
return FirstIV;
|
return FirstIV;
|
||||||
|
|
||||||
// At this point, we know that we have *some* no-payload enums. If FirstIV is
|
// At this point, we know that we have *some* no-payload enums. If FirstIV is
|
||||||
@@ -351,11 +344,8 @@ stripRCIdentityPreservingArgs(SILValue V, unsigned RecursionDepth) {
|
|||||||
// Let IVE be the edge for the non-payloaded enum. It is only safe to perform
|
// Let IVE be the edge for the non-payloaded enum. It is only safe to perform
|
||||||
// this operation when there exists a dominating edge E' of IVE for which
|
// this operation when there exists a dominating edge E' of IVE for which
|
||||||
// FirstIV also takes on a non-payloaded enum value.
|
// FirstIV also takes on a non-payloaded enum value.
|
||||||
if (std::any_of(NoPayloadEnums.begin(), NoPayloadEnums.end(),
|
if (std::any_of(NoPayloadEnumBBs.begin(), NoPayloadEnumBBs.end(),
|
||||||
[&](const SILValue V) -> bool {
|
[&](SILBasicBlock *BB) -> bool {
|
||||||
auto *BB = V->getParentBB();
|
|
||||||
if (!BB)
|
|
||||||
return true;
|
|
||||||
return !findDominatingNonPayloadedEdge(BB, FirstIV);
|
return !findDominatingNonPayloadedEdge(BB, FirstIV);
|
||||||
}))
|
}))
|
||||||
return SILValue();
|
return SILValue();
|
||||||
|
|||||||
Reference in New Issue
Block a user