Skip to content

Commit fa8c9d0

Browse files
committed
[semantic-arc] Move main optimize loop of SemanticARCOptVisitor into its own file.
1 parent 8d898e5 commit fa8c9d0

File tree

3 files changed

+115
-119
lines changed

3 files changed

+115
-119
lines changed

lib/SILOptimizer/SemanticARC/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ target_sources(swiftSILOptimizer PRIVATE
66
CopyValueOpts.cpp
77
OwnedToGuaranteedPhiOpt.cpp
88
Context.cpp
9+
SemanticARCOptVisitor.cpp
910
)
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
//===--- SemanticARCOptVisitor.cpp ----------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
///
13+
/// \file
14+
///
15+
/// Implementation of the main optimize loop of the ARC visitor peephole
16+
/// optimizer.
17+
///
18+
//===----------------------------------------------------------------------===//
19+
20+
#include "SemanticARCOptVisitor.h"
21+
#include "swift/SIL/DebugUtils.h"
22+
23+
using namespace swift;
24+
using namespace swift::semanticarc;
25+
26+
bool SemanticARCOptVisitor::optimize() {
27+
bool madeChange = false;
28+
29+
// First process the worklist until we reach a fixed point.
30+
madeChange |= processWorklist();
31+
32+
{
33+
// If we made a change, set that we assume we are at fixed point and then
34+
// re-run the worklist so that we can
35+
// properly seeded the ARC peephole map.
36+
ctx.assumingAtFixedPoint = true;
37+
SWIFT_DEFER { ctx.assumingAtFixedPoint = false; };
38+
39+
// Add everything in visitedSinceLastMutation to the worklist so we
40+
// recompute our fixed point.
41+
drainVisitedSinceLastMutationIntoWorklist();
42+
43+
// Then re-run the worklist. We shouldn't modify anything since we are at a
44+
// fixed point and are just using this to seed the
45+
// joinedOwnedIntroducerToConsumedOperands after we have finished changing
46+
// things. If we did change something, we did something weird, so assert!
47+
bool madeAdditionalChanges = processWorklist();
48+
(void)madeAdditionalChanges;
49+
assert(!madeAdditionalChanges && "Should be at the fixed point");
50+
}
51+
52+
return madeChange;
53+
}
54+
55+
bool SemanticARCOptVisitor::processWorklist() {
56+
// NOTE: The madeChange here is not strictly necessary since we only have
57+
// items added to the worklist today if we have already made /some/ sort of
58+
// change. That being said, I think there is a low cost to including this here
59+
// and makes the algorithm more correct, visually and in the face of potential
60+
// refactoring.
61+
bool madeChange = false;
62+
63+
while (!worklist.empty()) {
64+
// Pop the last element off the list. If we were returned None, we blotted
65+
// this element, so skip it.
66+
SILValue next = worklist.pop_back_val().getValueOr(SILValue());
67+
if (!next)
68+
continue;
69+
70+
// First check if this is a value that we have visited since the last time
71+
// we erased an instruction. If we have visited it, skip it. Every time we
72+
// modify something, we should be deleting an instruction, so we have not
73+
// found any further information.
74+
if (!visitedSinceLastMutation.insert(next).second) {
75+
continue;
76+
}
77+
78+
// First check if this is an instruction that is trivially dead. This can
79+
// occur if we eliminate rr traffic resulting in dead projections and the
80+
// like.
81+
//
82+
// If we delete, we first add all of our deleted instructions operands to
83+
// the worklist and then remove all results (since we are going to delete
84+
// the instruction).
85+
if (auto *defInst = next->getDefiningInstruction()) {
86+
if (isInstructionTriviallyDead(defInst)) {
87+
assert(!ctx.assumingAtFixedPoint &&
88+
"Assumed was at fixed point and recomputing state?!");
89+
deleteAllDebugUses(defInst);
90+
eraseInstruction(defInst);
91+
madeChange = true;
92+
ctx.verify();
93+
continue;
94+
}
95+
}
96+
97+
// Otherwise, if we have a single value instruction (to be expanded later
98+
// perhaps), try to visit that value recursively.
99+
if (auto *svi = dyn_cast<SingleValueInstruction>(next)) {
100+
bool madeSingleChange = visit(svi);
101+
assert((!madeSingleChange || !ctx.assumingAtFixedPoint) &&
102+
"Assumed was at fixed point and modified state?!");
103+
madeChange |= madeSingleChange;
104+
if (madeSingleChange) {
105+
ctx.verify();
106+
}
107+
continue;
108+
}
109+
}
110+
111+
return madeChange;
112+
}

lib/SILOptimizer/SemanticARC/SemanticARCOpts.cpp

Lines changed: 2 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -12,131 +12,14 @@
1212

1313
#define DEBUG_TYPE "sil-semantic-arc-opts"
1414

15-
#include "OwnershipLiveRange.h"
16-
#include "OwnershipPhiOperand.h"
1715
#include "SemanticARCOptVisitor.h"
1816
#include "Transforms.h"
1917

20-
#include "swift/Basic/LLVM.h"
21-
22-
#include "swift/Basic/BlotSetVector.h"
23-
#include "swift/Basic/FrozenMultiMap.h"
24-
#include "swift/Basic/MultiMapCache.h"
25-
#include "swift/Basic/STLExtras.h"
26-
#include "swift/SIL/BasicBlockUtils.h"
27-
#include "swift/SIL/DebugUtils.h"
28-
#include "swift/SIL/LinearLifetimeChecker.h"
29-
#include "swift/SIL/MemAccessUtils.h"
30-
#include "swift/SIL/OwnershipUtils.h"
31-
#include "swift/SIL/Projection.h"
32-
#include "swift/SIL/SILArgument.h"
33-
#include "swift/SIL/SILBuilder.h"
34-
#include "swift/SIL/SILInstruction.h"
35-
#include "swift/SIL/SILVisitor.h"
36-
#include "swift/SILOptimizer/Analysis/PostOrderAnalysis.h"
37-
#include "swift/SILOptimizer/PassManager/Passes.h"
3818
#include "swift/SILOptimizer/PassManager/Transforms.h"
39-
#include "swift/SILOptimizer/Utils/InstOptUtils.h"
40-
#include "swift/SILOptimizer/Utils/ValueLifetime.h"
41-
#include "llvm/ADT/SmallPtrSet.h"
42-
#include "llvm/ADT/SmallVector.h"
43-
#include "llvm/ADT/Statistic.h"
4419

4520
using namespace swift;
4621
using namespace swift::semanticarc;
4722

48-
//===----------------------------------------------------------------------===//
49-
// Implementation
50-
//===----------------------------------------------------------------------===//
51-
52-
bool SemanticARCOptVisitor::optimize() {
53-
bool madeChange = false;
54-
55-
// First process the worklist until we reach a fixed point.
56-
madeChange |= processWorklist();
57-
58-
{
59-
// If we made a change, set that we assume we are at fixed point and then
60-
// re-run the worklist so that we can
61-
// properly seeded the ARC peephole map.
62-
ctx.assumingAtFixedPoint = true;
63-
SWIFT_DEFER { ctx.assumingAtFixedPoint = false; };
64-
65-
// Add everything in visitedSinceLastMutation to the worklist so we
66-
// recompute our fixed point.
67-
drainVisitedSinceLastMutationIntoWorklist();
68-
69-
// Then re-run the worklist. We shouldn't modify anything since we are at a
70-
// fixed point and are just using this to seed the
71-
// joinedOwnedIntroducerToConsumedOperands after we have finished changing
72-
// things. If we did change something, we did something weird, so assert!
73-
bool madeAdditionalChanges = processWorklist();
74-
(void)madeAdditionalChanges;
75-
assert(!madeAdditionalChanges && "Should be at the fixed point");
76-
}
77-
78-
return madeChange;
79-
}
80-
81-
bool SemanticARCOptVisitor::processWorklist() {
82-
// NOTE: The madeChange here is not strictly necessary since we only have
83-
// items added to the worklist today if we have already made /some/ sort of
84-
// change. That being said, I think there is a low cost to including this here
85-
// and makes the algorithm more correct, visually and in the face of potential
86-
// refactoring.
87-
bool madeChange = false;
88-
89-
while (!worklist.empty()) {
90-
// Pop the last element off the list. If we were returned None, we blotted
91-
// this element, so skip it.
92-
SILValue next = worklist.pop_back_val().getValueOr(SILValue());
93-
if (!next)
94-
continue;
95-
96-
// First check if this is a value that we have visited since the last time
97-
// we erased an instruction. If we have visited it, skip it. Every time we
98-
// modify something, we should be deleting an instruction, so we have not
99-
// found any further information.
100-
if (!visitedSinceLastMutation.insert(next).second) {
101-
continue;
102-
}
103-
104-
// First check if this is an instruction that is trivially dead. This can
105-
// occur if we eliminate rr traffic resulting in dead projections and the
106-
// like.
107-
//
108-
// If we delete, we first add all of our deleted instructions operands to
109-
// the worklist and then remove all results (since we are going to delete
110-
// the instruction).
111-
if (auto *defInst = next->getDefiningInstruction()) {
112-
if (isInstructionTriviallyDead(defInst)) {
113-
assert(!ctx.assumingAtFixedPoint &&
114-
"Assumed was at fixed point and recomputing state?!");
115-
deleteAllDebugUses(defInst);
116-
eraseInstruction(defInst);
117-
madeChange = true;
118-
ctx.verify();
119-
continue;
120-
}
121-
}
122-
123-
// Otherwise, if we have a single value instruction (to be expanded later
124-
// perhaps), try to visit that value recursively.
125-
if (auto *svi = dyn_cast<SingleValueInstruction>(next)) {
126-
bool madeSingleChange = visit(svi);
127-
assert((!madeSingleChange || !ctx.assumingAtFixedPoint) &&
128-
"Assumed was at fixed point and modified state?!");
129-
madeChange |= madeSingleChange;
130-
if (madeSingleChange) {
131-
ctx.verify();
132-
}
133-
continue;
134-
}
135-
}
136-
137-
return madeChange;
138-
}
139-
14023
//===----------------------------------------------------------------------===//
14124
// Top Level Entrypoint
14225
//===----------------------------------------------------------------------===//
@@ -179,7 +62,7 @@ struct SemanticARCOpts : SILFunctionTransform {
17962
}
18063

18164
// Then process the worklist, performing peepholes.
182-
bool madeChange = visitor.optimize();
65+
bool eliminatedARCInst = visitor.optimize();
18366

18467
// Now that we have seeded the map of phis to incoming values that could be
18568
// converted to guaranteed, ignoring the phi, try convert those phis to be
@@ -191,7 +74,7 @@ struct SemanticARCOpts : SILFunctionTransform {
19174
}
19275

19376
// Otherwise, we only deleted instructions and did not touch phis.
194-
if (madeChange)
77+
if (eliminatedARCInst)
19578
invalidateAnalysis(SILAnalysis::InvalidationKind::Instructions);
19679
}
19780
};

0 commit comments

Comments
 (0)