@@ -28,103 +28,8 @@ class SILInstruction;
28
28
class SILModule ;
29
29
class SILValue ;
30
30
class DeadEndBlocks ;
31
-
32
- namespace ownership {
33
-
34
- struct ErrorBehaviorKind {
35
- enum inner_t {
36
- Invalid = 0 ,
37
- ReturnFalse = 1 ,
38
- PrintMessage = 2 ,
39
- Assert = 4 ,
40
- ReturnFalseOnLeak = 8 ,
41
- PrintMessageAndReturnFalse = PrintMessage | ReturnFalse,
42
- PrintMessageAndAssert = PrintMessage | Assert,
43
- ReturnFalseOnLeakAssertOtherwise = ReturnFalseOnLeak | Assert,
44
- } Value;
45
-
46
- ErrorBehaviorKind () : Value(Invalid) {}
47
- ErrorBehaviorKind (inner_t Inner) : Value(Inner) { assert (Value != Invalid); }
48
-
49
- bool shouldAssert () const {
50
- assert (Value != Invalid);
51
- return Value & Assert;
52
- }
53
-
54
- bool shouldReturnFalseOnLeak () const {
55
- assert (Value != Invalid);
56
- return Value & ReturnFalseOnLeak;
57
- }
58
-
59
- bool shouldPrintMessage () const {
60
- assert (Value != Invalid);
61
- return Value & PrintMessage;
62
- }
63
-
64
- bool shouldReturnFalse () const {
65
- assert (Value != Invalid);
66
- return Value & ReturnFalse;
67
- }
68
- };
69
-
70
- } // end namespace ownership
71
-
72
- class LinearLifetimeError {
73
- ownership::ErrorBehaviorKind errorBehavior;
74
- bool foundUseAfterFree = false ;
75
- bool foundLeak = false ;
76
- bool foundOverConsume = false ;
77
-
78
- public:
79
- LinearLifetimeError (ownership::ErrorBehaviorKind errorBehavior)
80
- : errorBehavior(errorBehavior) {}
81
-
82
- bool getFoundError () const {
83
- return foundUseAfterFree || foundLeak || foundOverConsume;
84
- }
85
-
86
- bool getFoundLeak () const { return foundLeak; }
87
-
88
- bool getFoundUseAfterFree () const { return foundUseAfterFree; }
89
-
90
- bool getFoundOverConsume () const { return foundOverConsume; }
91
-
92
- void handleLeak (llvm::function_ref<void ()> &&messagePrinterFunc) {
93
- foundLeak = true ;
94
-
95
- if (errorBehavior.shouldPrintMessage ())
96
- messagePrinterFunc ();
97
-
98
- if (errorBehavior.shouldReturnFalseOnLeak ())
99
- return ;
100
-
101
- // We already printed out our error if we needed to, so don't pass it along.
102
- handleError ([]() {});
103
- }
104
-
105
- void handleOverConsume (llvm::function_ref<void ()> &&messagePrinterFunc) {
106
- foundOverConsume = true ;
107
- handleError (std::move (messagePrinterFunc));
108
- }
109
-
110
- void handleUseAfterFree (llvm::function_ref<void ()> &&messagePrinterFunc) {
111
- foundUseAfterFree = true ;
112
- handleError (std::move (messagePrinterFunc));
113
- }
114
-
115
- private:
116
- void handleError (llvm::function_ref<void ()> &&messagePrinterFunc) {
117
- if (errorBehavior.shouldPrintMessage ())
118
- messagePrinterFunc ();
119
-
120
- if (errorBehavior.shouldReturnFalse ()) {
121
- return ;
122
- }
123
-
124
- assert (errorBehavior.shouldAssert () && " At this point, we should assert" );
125
- llvm_unreachable (" triggering standard assertion failure routine" );
126
- }
127
- };
31
+ class SILOwnershipVerifier ;
32
+ class SILValueOwnershipChecker ;
128
33
129
34
// / A class used to validate linear lifetime with respect to an SSA-like
130
35
// / definition.
@@ -140,6 +45,14 @@ class LinearLifetimeError {
140
45
// / uses must not be reachable from each other and jointly post-dominate all
141
46
// / consuming uses as well as the defining block/instruction.
142
47
class LinearLifetimeChecker {
48
+ public:
49
+ class Error ;
50
+ struct ErrorBehaviorKind ;
51
+
52
+ private:
53
+ friend class SILOwnershipVerifier ;
54
+ friend class SILValueOwnershipChecker ;
55
+
143
56
SmallPtrSetImpl<SILBasicBlock *> &visitedBlocks;
144
57
DeadEndBlocks &deadEndBlocks;
145
58
@@ -148,6 +61,36 @@ class LinearLifetimeChecker {
148
61
DeadEndBlocks &deadEndBlocks)
149
62
: visitedBlocks(visitedBlocks), deadEndBlocks(deadEndBlocks) {}
150
63
64
+ // / Returns true that \p value forms a linear lifetime with consuming uses \p
65
+ // / consumingUses, non consuming uses \p nonConsumingUses. Returns false
66
+ // / otherwise.
67
+ bool validateLifetime (SILValue value, ArrayRef<Operand *> consumingUses,
68
+ ArrayRef<Operand *> nonConsumingUses);
69
+
70
+ // / Given a value and a consuming use of that value, compute a non-unique
71
+ // / minimal set of insertion points that together with \p consumingUse
72
+ // / post-dominate and end the lifetime of \p value.
73
+ // /
74
+ // / Returns true if we completed the consuming use set and discovered that \p
75
+ // / consumingUse is not strongly control equivalent to value (meaning
76
+ // / consumingUse is not in the same loop in the loop nest as value).
77
+ // /
78
+ // / \p scratch A scratch buffer to be used during our computation. If nullptr,
79
+ // / routine will create its own small vector.
80
+ bool completeConsumingUseSet (
81
+ SILValue value, Operand *consumingUse,
82
+ SmallVectorImpl<SILBasicBlock *> &scratch,
83
+ function_ref<void (SILBasicBlock::iterator insertPt)> visitor);
84
+
85
+ // / Overload without scratch space.
86
+ bool completeConsumingUseSet (
87
+ SILValue value, Operand *consumingUse,
88
+ function_ref<void (SILBasicBlock::iterator insertPt)> visitor) {
89
+ SmallVector<SILBasicBlock *, 4 > scratch;
90
+ return completeConsumingUseSet (value, consumingUse, scratch, visitor);
91
+ }
92
+
93
+ private:
151
94
// / Returns true if:
152
95
// /
153
96
// / 1. No consuming uses are reachable from any other consuming use, from any
@@ -164,22 +107,10 @@ class LinearLifetimeChecker {
164
107
// / error.
165
108
// / \p leakingBlocks If non-null a list of blocks where the value was detected
166
109
// / to leak. Can be used to insert missing destroys.
167
- LinearLifetimeError
168
- checkValue (SILValue value, ArrayRef<Operand *> consumingUses,
169
- ArrayRef<Operand *> nonConsumingUses,
170
- ownership::ErrorBehaviorKind errorBehavior,
171
- SmallVectorImpl<SILBasicBlock *> *leakingBlocks = nullptr );
172
-
173
- // / Returns true that \p value forms a linear lifetime with consuming uses \p
174
- // / consumingUses, non consuming uses \p nonConsumingUses. Returns false
175
- // / otherwise.
176
- bool validateLifetime (SILValue value, ArrayRef<Operand *> consumingUses,
177
- ArrayRef<Operand *> nonConsumingUses) {
178
- return !checkValue (value, consumingUses, nonConsumingUses,
179
- ownership::ErrorBehaviorKind::ReturnFalse,
180
- nullptr /* leakingBlocks*/ )
181
- .getFoundError ();
182
- }
110
+ Error checkValue (SILValue value, ArrayRef<Operand *> consumingUses,
111
+ ArrayRef<Operand *> nonConsumingUses,
112
+ ErrorBehaviorKind errorBehavior,
113
+ SmallVectorImpl<SILBasicBlock *> *leakingBlocks = nullptr );
183
114
};
184
115
185
116
} // namespace swift
0 commit comments