Skip to content

Commit 5d85ad3

Browse files
committed
[SILOpt] Add utility to find guaranteed roots.
The new utility looks through ownership forwarding instructions to find the original values with guaranteed ownership.
1 parent 0a7272b commit 5d85ad3

File tree

2 files changed

+64
-3
lines changed

2 files changed

+64
-3
lines changed

include/swift/SIL/MemAccessUtils.h

+5
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,11 @@ SILValue findReferenceRoot(SILValue ref);
204204
/// Find the first owned root of the reference.
205205
SILValue findOwnershipReferenceRoot(SILValue ref);
206206

207+
/// Look through all ownership forwarding instructions to find the values which
208+
/// were originally borrowed.
209+
void findGuaranteedReferenceRoots(SILValue value,
210+
SmallVectorImpl<SILValue> &roots);
211+
207212
/// Find the aggregate containing the first owned root of the
208213
/// reference. Identical to findOwnershipReferenceRoot, but looks through
209214
/// struct_extract, tuple_extract, etc.

lib/SIL/Utils/MemAccessUtils.cpp

+59-3
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@
1313
#define DEBUG_TYPE "sil-access-utils"
1414

1515
#include "swift/SIL/MemAccessUtils.h"
16-
#include "swift/SIL/SILModule.h"
17-
#include "swift/SIL/SILUndef.h"
18-
#include "swift/SIL/DynamicCasts.h"
16+
#include "swift/Basic/GraphNodeWorklist.h"
1917
#include "swift/SIL/Consumption.h"
18+
#include "swift/SIL/DynamicCasts.h"
2019
#include "swift/SIL/SILInstruction.h"
20+
#include "swift/SIL/SILModule.h"
21+
#include "swift/SIL/SILUndef.h"
2122
#include "llvm/Support/Debug.h"
2223

2324
using namespace swift;
@@ -800,6 +801,61 @@ SILValue swift::findOwnershipReferenceRoot(SILValue ref) {
800801
return ref;
801802
}
802803

804+
void swift::findGuaranteedReferenceRoots(SILValue value,
805+
SmallVectorImpl<SILValue> &roots) {
806+
GraphNodeWorklist<SILValue, 4> worklist;
807+
auto addAllOperandsToWorklist = [&worklist](SILInstruction *inst) -> bool {
808+
if (inst->getNumOperands() > 0) {
809+
for (auto operand : inst->getOperandValues()) {
810+
worklist.insert(operand);
811+
}
812+
return true;
813+
}
814+
return false;
815+
};
816+
worklist.initialize(value);
817+
while (auto value = worklist.pop()) {
818+
if (auto *arg = dyn_cast<SILPhiArgument>(value)) {
819+
if (auto *terminator = arg->getSingleTerminator()) {
820+
worklist.insert(terminator->getOperand(arg->getIndex()));
821+
continue;
822+
}
823+
} else if (auto *inst = value->getDefiningInstruction()) {
824+
if (auto *result =
825+
dyn_cast<FirstArgOwnershipForwardingSingleValueInst>(inst)) {
826+
if (result->getNumOperands() > 0) {
827+
worklist.insert(result->getOperand(0));
828+
continue;
829+
}
830+
} else if (auto *result =
831+
dyn_cast<AllArgOwnershipForwardingSingleValueInst>(inst)) {
832+
if (addAllOperandsToWorklist(result)) {
833+
continue;
834+
}
835+
} else if (auto *result = dyn_cast<OwnershipForwardingTermInst>(inst)) {
836+
assert(false && "value defined by a terminator?!");
837+
} else if (auto *result =
838+
dyn_cast<OwnershipForwardingConversionInst>(inst)) {
839+
worklist.insert(result->getConverted());
840+
continue;
841+
} else if (auto *result =
842+
dyn_cast<OwnershipForwardingSelectEnumInstBase>(inst)) {
843+
if (addAllOperandsToWorklist(result)) {
844+
continue;
845+
}
846+
} else if (auto *result =
847+
dyn_cast<OwnershipForwardingMultipleValueInstruction>(
848+
inst)) {
849+
if (addAllOperandsToWorklist(result)) {
850+
continue;
851+
}
852+
}
853+
}
854+
if (value.getOwnershipKind() == OwnershipKind::Guaranteed)
855+
roots.push_back(value);
856+
}
857+
}
858+
803859
/// Find the first owned aggregate containing the reference, or simply the
804860
/// reference root if no aggregate is found.
805861
///

0 commit comments

Comments
 (0)