|
13 | 13 | #define DEBUG_TYPE "sil-access-utils"
|
14 | 14 |
|
15 | 15 | #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" |
19 | 17 | #include "swift/SIL/Consumption.h"
|
| 18 | +#include "swift/SIL/DynamicCasts.h" |
20 | 19 | #include "swift/SIL/SILInstruction.h"
|
| 20 | +#include "swift/SIL/SILModule.h" |
| 21 | +#include "swift/SIL/SILUndef.h" |
21 | 22 | #include "llvm/Support/Debug.h"
|
22 | 23 |
|
23 | 24 | using namespace swift;
|
@@ -800,6 +801,61 @@ SILValue swift::findOwnershipReferenceRoot(SILValue ref) {
|
800 | 801 | return ref;
|
801 | 802 | }
|
802 | 803 |
|
| 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 | + |
803 | 859 | /// Find the first owned aggregate containing the reference, or simply the
|
804 | 860 | /// reference root if no aggregate is found.
|
805 | 861 | ///
|
|
0 commit comments