16
16
#include " GlobalARCSequenceDataflow.h"
17
17
#include " GlobalLoopARCSequenceDataflow.h"
18
18
#include " swift/SIL/SILValue.h"
19
+ #include " swift/SILPasses/Utils/LoopUtils.h"
19
20
#include " llvm/ADT/SetVector.h"
20
21
21
22
namespace swift {
@@ -31,13 +32,31 @@ class RCIdentityFunctionInfo;
31
32
// / A set of matching reference count increments, decrements, increment
32
33
// / insertion pts, and decrement insertion pts.
33
34
struct ARCMatchingSet {
35
+
36
+ // / The pointer that this ARCMatchingSet is providing matching increment and
37
+ // / decrement sets for.
38
+ // /
39
+ // / TODO: This should really be called RCIdentity.
34
40
SILValue Ptr;
41
+
42
+ // / The set of reference count increments that were paired.
35
43
llvm::SetVector<SILInstruction *> Increments;
44
+
45
+ // / An insertion point for an increment means the earliest point in the
46
+ // / program after the increment has occured that the increment can be moved to
47
+ // / without moving the increment over an instruction that may decrement a
48
+ // / reference count.
36
49
llvm::SetVector<SILInstruction *> IncrementInsertPts;
50
+
51
+ // / The set of reference count decrements that were paired.
37
52
llvm::SetVector<SILInstruction *> Decrements;
53
+
54
+ // / An insertion point for a decrement means the latest point in the program
55
+ // / before the decrement that the optimizer conservatively assumes that a
56
+ // / reference counted value could be used.
38
57
llvm::SetVector<SILInstruction *> DecrementInsertPts;
39
58
40
- // This is a data structure that can not be moved.
59
+ // This is a data structure that can not be moved or copied .
41
60
ARCMatchingSet () = default ;
42
61
ARCMatchingSet (const ARCMatchingSet &) = delete ;
43
62
ARCMatchingSet (ARCMatchingSet &&) = delete ;
@@ -53,24 +72,31 @@ struct ARCMatchingSet {
53
72
}
54
73
};
55
74
56
- // / A structure that via its virtual calls recieves the results of the analysis.
57
- // /
58
- // / TODO: We could potentially pass in all of the matching sets as a list and
59
- // / use less virtual calls at the cost of potentially greater numbers of moves.
60
- struct ARCMatchingSetCallback {
61
- virtual ~ARCMatchingSetCallback () = default ;
75
+ class CodeMotionOrDeleteCallback {
76
+ bool Changed = false ;
77
+ llvm::SmallVector<SILInstruction *, 16 > InstructionsToDelete;
62
78
79
+ public:
63
80
// / This call should process \p Set and modify any internal state of
64
81
// / ARCMatchingSetCallback given \p Set. This call should not remove any
65
82
// / instructions since any removed instruction might be used as an insertion
66
83
// / point for another retain, release pair.
67
- virtual void processMatchingSet (ARCMatchingSet &Set) {}
84
+ void processMatchingSet (ARCMatchingSet &Set);
85
+
86
+ // Delete instructions after we have processed all matching sets so that we do
87
+ // not remove instructions that may be insertion points for other retain,
88
+ // releases.
89
+ void finalize () {
90
+ while (!InstructionsToDelete.empty ()) {
91
+ InstructionsToDelete.pop_back_val ()->eraseFromParent ();
92
+ }
93
+ }
68
94
69
- // / This call should perform any deletion of instructions necessary. It is run
70
- // / strictly after all computation has been completed.
71
- virtual void finalize () {}
95
+ bool madeChange () const { return Changed; }
72
96
};
73
97
98
+ // / A wrapper around the results of the bottomup/topdown dataflow that knows how
99
+ // / to pair the retains/releases in those results.
74
100
struct ARCPairingContext {
75
101
SILFunction &F;
76
102
BlotMapVector<SILInstruction *, TopDownRefCountState> DecToIncStateMap;
@@ -79,9 +105,14 @@ struct ARCPairingContext {
79
105
80
106
ARCPairingContext (SILFunction &F, RCIdentityFunctionInfo *RCIA)
81
107
: F(F), DecToIncStateMap(), IncToDecStateMap(), RCIA(RCIA) {}
82
- bool performMatching (ARCMatchingSetCallback &Callback);
108
+ bool performMatching (CodeMotionOrDeleteCallback &Callback);
83
109
};
84
110
111
+ // / A composition of an ARCSequenceDataflowEvaluator and an
112
+ // / ARCPairingContext. The evaluator performs top down/bottom up dataflows
113
+ // / clearing the dataflow at loop boundaries. Then the results of the evaluator
114
+ // / are placed into the ARCPairingContext and then the ARCPairingContext is used
115
+ // / to pair retains/releases.
85
116
struct BlockARCPairingContext {
86
117
ARCPairingContext Context;
87
118
ARCSequenceDataflowEvaluator Evaluator;
@@ -91,7 +122,7 @@ struct BlockARCPairingContext {
91
122
: Context(F, RCFI), Evaluator(F, AA, POTA, RCFI, Context.DecToIncStateMap,
92
123
Context.IncToDecStateMap) {}
93
124
94
- bool run (bool FreezePostDomReleases, ARCMatchingSetCallback &Callback) {
125
+ bool run (bool FreezePostDomReleases, CodeMotionOrDeleteCallback &Callback) {
95
126
bool NestingDetected = Evaluator.run (FreezePostDomReleases);
96
127
Evaluator.clear ();
97
128
@@ -100,23 +131,36 @@ struct BlockARCPairingContext {
100
131
}
101
132
};
102
133
103
- struct LoopARCPairingContext {
134
+ // / A composition of a LoopARCSequenceDataflowEvaluator and an
135
+ // / ARCPairingContext. The loop nest is processed bottom up. For each loop, we
136
+ // / run the evaluator on the loop and then use the ARCPairingContext to pair
137
+ // / retains/releases and eliminate them.
138
+ struct LoopARCPairingContext : SILLoopVisitor {
104
139
ARCPairingContext Context;
105
140
LoopARCSequenceDataflowEvaluator Evaluator;
106
141
LoopRegionFunctionInfo *LRFI;
107
142
SILLoopInfo *SLI;
143
+ CodeMotionOrDeleteCallback Callback;
144
+ bool FreezePostDomReleases = false ;
108
145
109
146
LoopARCPairingContext (SILFunction &F, AliasAnalysis *AA,
110
147
LoopRegionFunctionInfo *LRFI, SILLoopInfo *SLI,
111
148
RCIdentityFunctionInfo *RCFI)
112
- : Context(F, RCFI),
149
+ : SILLoopVisitor(&F, SLI), Context(F, RCFI),
113
150
Evaluator (F, AA, LRFI, SLI, RCFI, Context.DecToIncStateMap,
114
151
Context.IncToDecStateMap),
115
- LRFI(LRFI), SLI(SLI) {}
152
+ LRFI(LRFI), SLI(SLI), Callback() {}
153
+
154
+ bool process (bool FreezePDReleases) {
155
+ FreezePostDomReleases = FreezePDReleases;
156
+ run ();
157
+ return Callback.madeChange ();
158
+ }
159
+
160
+ void runOnLoop (SILLoop *L) override ;
161
+ void runOnFunction (SILFunction *F) override ;
116
162
117
- bool run (bool FreezePostDomReleases, ARCMatchingSetCallback &Callback);
118
- void processLoop (const LoopRegion *R, bool FreezePostDomReleases,
119
- ARCMatchingSetCallback &Callback);
163
+ void processRegion (const LoopRegion *R);
120
164
};
121
165
122
166
} // end swift namespace
0 commit comments