12
12
13
13
#define DEBUG_TYPE " sil-semantic-arc-opts"
14
14
15
- #include " OwnershipLiveRange.h"
16
- #include " OwnershipPhiOperand.h"
17
15
#include " SemanticARCOptVisitor.h"
18
16
#include " Transforms.h"
19
17
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"
38
18
#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"
44
19
45
20
using namespace swift ;
46
21
using namespace swift ::semanticarc;
47
22
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
-
140
23
// ===----------------------------------------------------------------------===//
141
24
// Top Level Entrypoint
142
25
// ===----------------------------------------------------------------------===//
@@ -179,7 +62,7 @@ struct SemanticARCOpts : SILFunctionTransform {
179
62
}
180
63
181
64
// Then process the worklist, performing peepholes.
182
- bool madeChange = visitor.optimize ();
65
+ bool eliminatedARCInst = visitor.optimize ();
183
66
184
67
// Now that we have seeded the map of phis to incoming values that could be
185
68
// converted to guaranteed, ignoring the phi, try convert those phis to be
@@ -191,7 +74,7 @@ struct SemanticARCOpts : SILFunctionTransform {
191
74
}
192
75
193
76
// Otherwise, we only deleted instructions and did not touch phis.
194
- if (madeChange )
77
+ if (eliminatedARCInst )
195
78
invalidateAnalysis (SILAnalysis::InvalidationKind::Instructions);
196
79
}
197
80
};
0 commit comments