Skip to content

Commit c7e8cb0

Browse files
committed
Remove now unused utility functions for escape checking.
Those functions were replaced by EscapeAnalysis.
1 parent dd204e6 commit c7e8cb0

File tree

3 files changed

+0
-311
lines changed

3 files changed

+0
-311
lines changed

include/swift/SIL/SILValueProjection.h

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -477,18 +477,6 @@ class LSLocation : public SILValueProjection {
477477
/// projection.
478478
void getFirstLevelLSLocations(LSLocationList &Locs, SILModule *Mod);
479479

480-
/// Returns true if the LSLocation is local to this function, i.e.
481-
/// does not escape.
482-
///
483-
/// TODO: we should look at the projection path as well. i.e. one field
484-
/// might escape but the object itself does not.
485-
///
486-
bool isNonEscapingLocalLSLocation() {
487-
assert(isValid() && "Invalid memory location");
488-
// TODO: this does not have to be limited to allocstack.
489-
return isa<AllocStackInst>(Base) && isNonEscapingLocalObject(Base);
490-
}
491-
492480
/// Check whether the 2 LSLocations may alias each other or not.
493481
bool isMayAliasLSLocation(const LSLocation &RHS, AliasAnalysis *AA);
494482

include/swift/SILOptimizer/Analysis/ValueTracking.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,6 @@ bool isNotAliasingArgument(SILValue V, InoutAliasingAssumption isInoutAliasing =
4242
bool pointsToLocalObject(SILValue V, InoutAliasingAssumption isInoutAliasing =
4343
InoutAliasingAssumption::Aliasing);
4444

45-
/// Return true if the pointer is to a function-local object that never escapes
46-
/// from the function.
47-
bool isNonEscapingLocalObject(SILValue V);
48-
4945
enum class IsZeroKind {
5046
Zero,
5147
NotZero,

lib/SILOptimizer/Analysis/ValueTracking.cpp

Lines changed: 0 additions & 295 deletions
Original file line numberDiff line numberDiff line change
@@ -35,275 +35,6 @@ SILValue swift::getUnderlyingObject(SILValue V) {
3535
}
3636
}
3737

38-
/// Returns true if the ValueBase inside V is an apply whose callee is a no read
39-
/// builtin.
40-
static bool isNoReadBuiltinInst(SILValue V) {
41-
auto *BI = dyn_cast<BuiltinInst>(V);
42-
return BI && !BI->mayReadOrWriteMemory();
43-
}
44-
45-
/// Is Inst an instruction which escapes if and only if one of its results
46-
/// escape?
47-
static bool isTransitiveEscapeInst(SILInstruction *Inst) {
48-
switch (Inst->getKind()) {
49-
case ValueKind::AllocBoxInst:
50-
case ValueKind::AllocExistentialBoxInst:
51-
case ValueKind::AllocRefInst:
52-
case ValueKind::AllocRefDynamicInst:
53-
case ValueKind::AllocStackInst:
54-
case ValueKind::AllocValueBufferInst:
55-
case ValueKind::BuiltinInst:
56-
case ValueKind::ApplyInst:
57-
case ValueKind::TryApplyInst:
58-
case ValueKind::WitnessMethodInst:
59-
case ValueKind::CopyAddrInst:
60-
case ValueKind::RetainValueInst:
61-
case ValueKind::DeallocBoxInst:
62-
case ValueKind::DeallocExistentialBoxInst:
63-
case ValueKind::DeallocRefInst:
64-
case ValueKind::DeallocPartialRefInst:
65-
case ValueKind::DeallocStackInst:
66-
case ValueKind::DeallocValueBufferInst:
67-
case ValueKind::DebugValueAddrInst:
68-
case ValueKind::DebugValueInst:
69-
case ValueKind::DestroyAddrInst:
70-
case ValueKind::ReleaseValueInst:
71-
case ValueKind::AutoreleaseValueInst:
72-
case ValueKind::FloatLiteralInst:
73-
case ValueKind::FunctionRefInst:
74-
case ValueKind::IntegerLiteralInst:
75-
case ValueKind::LoadInst:
76-
case ValueKind::LoadUnownedInst:
77-
case ValueKind::LoadWeakInst:
78-
case ValueKind::MetatypeInst:
79-
case ValueKind::ObjCProtocolInst:
80-
case ValueKind::GlobalAddrInst:
81-
case ValueKind::StoreInst:
82-
case ValueKind::StoreUnownedInst:
83-
case ValueKind::StoreWeakInst:
84-
case ValueKind::StringLiteralInst:
85-
case ValueKind::CopyBlockInst:
86-
case ValueKind::StrongReleaseInst:
87-
case ValueKind::StrongPinInst: // Pin handle is independently managed
88-
case ValueKind::StrongRetainInst:
89-
case ValueKind::StrongRetainUnownedInst:
90-
case ValueKind::StrongUnpinInst:
91-
case ValueKind::UnownedReleaseInst:
92-
case ValueKind::UnownedRetainInst:
93-
case ValueKind::IsUniqueInst:
94-
case ValueKind::IsUniqueOrPinnedInst:
95-
case ValueKind::InjectEnumAddrInst:
96-
case ValueKind::DeinitExistentialAddrInst:
97-
case ValueKind::UnreachableInst:
98-
case ValueKind::IsNonnullInst:
99-
case ValueKind::CondFailInst:
100-
case ValueKind::DynamicMethodBranchInst:
101-
case ValueKind::ReturnInst:
102-
case ValueKind::ThrowInst:
103-
case ValueKind::FixLifetimeInst:
104-
return false;
105-
106-
case ValueKind::AddressToPointerInst:
107-
case ValueKind::ValueMetatypeInst:
108-
case ValueKind::BranchInst:
109-
case ValueKind::CheckedCastBranchInst:
110-
case ValueKind::CheckedCastAddrBranchInst:
111-
case ValueKind::ClassMethodInst:
112-
case ValueKind::CondBranchInst:
113-
case ValueKind::ConvertFunctionInst:
114-
case ValueKind::DynamicMethodInst:
115-
case ValueKind::EnumInst:
116-
case ValueKind::IndexAddrInst:
117-
case ValueKind::IndexRawPointerInst:
118-
case ValueKind::InitBlockStorageHeaderInst:
119-
case ValueKind::InitEnumDataAddrInst:
120-
case ValueKind::InitExistentialAddrInst:
121-
case ValueKind::InitExistentialMetatypeInst:
122-
case ValueKind::InitExistentialRefInst:
123-
case ValueKind::ObjCExistentialMetatypeToObjectInst:
124-
case ValueKind::ObjCMetatypeToObjectInst:
125-
case ValueKind::ObjCToThickMetatypeInst:
126-
case ValueKind::UncheckedRefCastInst:
127-
case ValueKind::UncheckedRefCastAddrInst:
128-
case ValueKind::UncheckedAddrCastInst:
129-
case ValueKind::UncheckedTrivialBitCastInst:
130-
case ValueKind::UncheckedBitwiseCastInst:
131-
case ValueKind::MarkDependenceInst:
132-
case ValueKind::OpenExistentialAddrInst:
133-
case ValueKind::OpenExistentialMetatypeInst:
134-
case ValueKind::OpenExistentialRefInst:
135-
case ValueKind::OpenExistentialBoxInst:
136-
case ValueKind::PartialApplyInst:
137-
case ValueKind::ProjectBoxInst:
138-
case ValueKind::ProjectValueBufferInst:
139-
case ValueKind::PointerToAddressInst:
140-
case ValueKind::PointerToThinFunctionInst:
141-
case ValueKind::ProjectBlockStorageInst:
142-
case ValueKind::ExistentialMetatypeInst:
143-
case ValueKind::RawPointerToRefInst:
144-
case ValueKind::RefElementAddrInst:
145-
case ValueKind::RefToRawPointerInst:
146-
case ValueKind::RefToUnmanagedInst:
147-
case ValueKind::RefToUnownedInst:
148-
case ValueKind::SelectEnumInst:
149-
case ValueKind::SelectEnumAddrInst:
150-
case ValueKind::SelectValueInst:
151-
case ValueKind::StructElementAddrInst:
152-
case ValueKind::StructExtractInst:
153-
case ValueKind::StructInst:
154-
case ValueKind::SuperMethodInst:
155-
case ValueKind::SwitchEnumAddrInst:
156-
case ValueKind::SwitchEnumInst:
157-
case ValueKind::SwitchValueInst:
158-
case ValueKind::UncheckedEnumDataInst:
159-
case ValueKind::UncheckedTakeEnumDataAddrInst:
160-
case ValueKind::ThickToObjCMetatypeInst:
161-
case ValueKind::ThinFunctionToPointerInst:
162-
case ValueKind::ThinToThickFunctionInst:
163-
case ValueKind::TupleElementAddrInst:
164-
case ValueKind::TupleExtractInst:
165-
case ValueKind::TupleInst:
166-
case ValueKind::UnconditionalCheckedCastInst:
167-
case ValueKind::UnconditionalCheckedCastAddrInst:
168-
case ValueKind::UnmanagedToRefInst:
169-
case ValueKind::UnownedToRefInst:
170-
case ValueKind::UpcastInst:
171-
case ValueKind::RefToBridgeObjectInst:
172-
case ValueKind::BridgeObjectToRefInst:
173-
case ValueKind::BridgeObjectToWordInst:
174-
return true;
175-
176-
case ValueKind::AssignInst:
177-
case ValueKind::MarkFunctionEscapeInst:
178-
case ValueKind::MarkUninitializedInst:
179-
llvm_unreachable("Invalid in canonical SIL.");
180-
181-
case ValueKind::SILArgument:
182-
case ValueKind::SILUndef:
183-
llvm_unreachable("These do not use other values.");
184-
}
185-
}
186-
187-
/// Maximum amount of ValueCapture queries.
188-
static unsigned const ValueCaptureSearchThreshold = 32;
189-
190-
namespace {
191-
192-
/// Are there any uses that should be ignored as capture uses.
193-
///
194-
/// TODO: Expand this if we ever do the store of pointer analysis mentioned in
195-
/// Basic AA.
196-
enum CaptureException : unsigned {
197-
None=0,
198-
ReturnsCannotCapture=1,
199-
};
200-
201-
} // end anonymous namespace
202-
203-
/// Returns true if V is a value that is used in a manner such that we know its
204-
/// captured or we don't understand whether or not it was captured. In such a
205-
/// case to be conservative, we must assume it is captured.
206-
/// FIXME: Maybe put this on SILValue?
207-
static bool valueMayBeCaptured(SILValue V, CaptureException Exception) {
208-
llvm::SmallVector<Operand *, ValueCaptureSearchThreshold> Worklist;
209-
llvm::SmallPtrSet<Operand *, ValueCaptureSearchThreshold> Visited;
210-
unsigned Count = 0;
211-
212-
DEBUG(llvm::dbgs() << " Checking for capture.\n");
213-
214-
215-
// All uses of V to the worklist.
216-
for (auto *UI : V.getUses()) {
217-
// If we have more uses than the threshold, be conservative and bail so we
218-
// don't use too much compile time.
219-
if (Count++ >= ValueCaptureSearchThreshold)
220-
return true;
221-
Visited.insert(UI);
222-
Worklist.push_back(UI);
223-
}
224-
225-
// Until the worklist is empty...
226-
while (!Worklist.empty()) {
227-
// Pop off an operand and grab the operand's user...
228-
Operand *Op = Worklist.pop_back_val();
229-
SILInstruction *Inst = Op->getUser();
230-
231-
DEBUG(llvm::dbgs() << " Visiting: " << *Inst);
232-
233-
// If Inst is an instruction with the transitive escape property, V escapes
234-
// if and only if the results of Inst escape as well.
235-
if (isTransitiveEscapeInst(Inst)) {
236-
DEBUG(llvm::dbgs() << " Found transitive escape "
237-
"instruction!\n");
238-
for (auto *UI : Inst->getUses()) {
239-
// If we have more uses than the threshold, be conservative and bail
240-
// so we don't use too much compile time.
241-
if (Count++ >= ValueCaptureSearchThreshold)
242-
return true;
243-
244-
if (Visited.insert(UI).second) {
245-
Worklist.push_back(UI);
246-
}
247-
}
248-
continue;
249-
}
250-
251-
// An apply of a builtin that does not read memory cannot capture a value.
252-
//
253-
// TODO: Use analysis of the other function perhaps to see if it captures
254-
// memory in some manner?
255-
// TODO: Add in knowledge about how parameters work on swift to make this
256-
// more aggressive.
257-
if (isNoReadBuiltinInst(Inst))
258-
continue;
259-
260-
// Loading from a pointer does not cause it to be captured.
261-
if (isa<LoadInst>(Inst))
262-
continue;
263-
264-
// If we have a store and are storing into the pointer, this is not a
265-
// capture. Otherwise it is safe.
266-
if (auto *SI = dyn_cast<StoreInst>(Inst)) {
267-
if (SI->getDest() == Op->get()) {
268-
continue;
269-
} else {
270-
return true;
271-
}
272-
}
273-
274-
// Deallocation instructions don't capture.
275-
if (isa<DeallocationInst>(Inst))
276-
continue;
277-
278-
// Debug instructions don't capture.
279-
if (isa<DebugValueInst>(Inst) || isa<DebugValueAddrInst>(Inst))
280-
continue;
281-
282-
// RefCountOperations don't capture.
283-
//
284-
// The release case is true since Swift does not allow destructors to
285-
// resurrect objects. This is enforced via a runtime failure.
286-
if (isa<RefCountingInst>(Inst))
287-
continue;
288-
289-
// If we have a return instruction and we are assuming that returns don't
290-
// capture, we are safe.
291-
if (Exception == CaptureException::ReturnsCannotCapture &&
292-
isa<ReturnInst>(Inst))
293-
continue;
294-
295-
// We could not prove that Inst does not capture V. Be conservative and
296-
// return true.
297-
DEBUG(llvm::dbgs() << " Could not prove that inst does not capture "
298-
"V!\n");
299-
return true;
300-
}
301-
302-
// We successfully proved that V is not captured. Return false.
303-
DEBUG(llvm::dbgs() << " V was not captured!\n");
304-
return false;
305-
}
306-
30738
bool swift::isNotAliasingArgument(SILValue V,
30839
InoutAliasingAssumption isInoutAliasing) {
30940
auto *Arg = dyn_cast<SILArgument>(V);
@@ -321,32 +52,6 @@ bool swift::pointsToLocalObject(SILValue V,
32152
isNotAliasingArgument(V, isInoutAliasing);
32253
}
32354

324-
/// Return true if the pointer is to a function-local object that never escapes
325-
/// from the function.
326-
bool swift::isNonEscapingLocalObject(SILValue V) {
327-
// If this is a local allocation, or the result of a no read apply inst (which
328-
// cannot affect memory in the caller), check to see if the allocation
329-
// escapes.
330-
if (isa<AllocationInst>(*V) || isNoReadBuiltinInst(V))
331-
return !valueMayBeCaptured(V, CaptureException::ReturnsCannotCapture);
332-
333-
// If this is a no alias argument then it has not escaped before entering the
334-
// function. Check if it escapes inside the function.
335-
if (isNotAliasingArgument(V))
336-
return !valueMayBeCaptured(V, CaptureException::ReturnsCannotCapture);
337-
338-
// If this is an enum value. If it or its operand does not escape, it is
339-
// local.
340-
if (auto *EI = dyn_cast<EnumInst>(V))
341-
return !EI->hasOperand() ||
342-
!valueMayBeCaptured(EI->getOperand(),
343-
CaptureException::ReturnsCannotCapture);
344-
345-
// Otherwise we could not prove that V is a non escaping local object. Be
346-
// conservative and return false.
347-
return false;
348-
}
349-
35055
/// Check if the value \p Value is known to be zero, non-zero or unknown.
35156
IsZeroKind swift::isZeroValue(SILValue Value) {
35257
// Inspect integer literals.

0 commit comments

Comments
 (0)