17
17
#include " swift/SIL/SILInstruction.h"
18
18
#include " swift/SIL/SILModule.h"
19
19
#include " swift/SIL/SILVisitor.h"
20
+ #include " swift/SILOptimizer/Analysis/RCIdentityAnalysis.h"
20
21
#include " swift/SILOptimizer/PassManager/Passes.h"
21
22
#include " swift/SILOptimizer/PassManager/Transforms.h"
22
23
@@ -31,10 +32,12 @@ namespace {
31
32
struct OptRemarkGeneratorInstructionVisitor
32
33
: public SILInstructionVisitor<OptRemarkGeneratorInstructionVisitor> {
33
34
SILModule &mod;
35
+ RCIdentityFunctionInfo &rcfi;
34
36
OptRemark::Emitter ORE;
35
37
36
- OptRemarkGeneratorInstructionVisitor (SILModule &mod)
37
- : mod(mod), ORE(DEBUG_TYPE, mod) {}
38
+ OptRemarkGeneratorInstructionVisitor (SILModule &mod,
39
+ RCIdentityFunctionInfo &rcfi)
40
+ : mod(mod), rcfi(rcfi), ORE(DEBUG_TYPE, mod) {}
38
41
39
42
void visitStrongRetainInst (StrongRetainInst *sri);
40
43
void visitStrongReleaseInst (StrongReleaseInst *sri);
@@ -49,10 +52,28 @@ void OptRemarkGeneratorInstructionVisitor::visitStrongRetainInst(
49
52
StrongRetainInst *sri) {
50
53
ORE.emit ([&]() {
51
54
using namespace OptRemark ;
55
+ SILValue root = rcfi.getRCIdentityRoot (sri->getOperand ());
56
+ SmallVector<Argument, 8 > inferredArgs;
57
+ bool foundArgs = Argument::inferArgumentsForValue (
58
+ ArgumentKeyKind::Note, " on value:" , root, [&](Argument arg) {
59
+ inferredArgs.push_back (arg);
60
+ return true ;
61
+ });
62
+ (void )foundArgs;
63
+
52
64
// Retains begin a lifetime scope so we infer scan forward.
53
- return RemarkMissed (" memory-management" , *sri,
54
- SourceLocInferenceBehavior::ForwardScanOnly)
55
- << " Unable to remove retain" ;
65
+ auto remark = RemarkMissed (" memory-management" , *sri,
66
+ SourceLocInferenceBehavior::ForwardScanOnly)
67
+ << " Found retain:" ;
68
+ if (inferredArgs.empty ()) {
69
+ remark << Argument ({ArgumentKeyKind::ParentLocNote, " InferValueFailure" },
70
+ " Unable to infer any values being retained." );
71
+ } else {
72
+ for (auto arg : inferredArgs) {
73
+ remark << arg;
74
+ }
75
+ }
76
+ return remark;
56
77
});
57
78
}
58
79
@@ -61,31 +82,85 @@ void OptRemarkGeneratorInstructionVisitor::visitStrongReleaseInst(
61
82
ORE.emit ([&]() {
62
83
using namespace OptRemark ;
63
84
// Releases end a lifetime scope so we infer scan backward.
64
- return RemarkMissed (" memory-management" , *sri,
65
- SourceLocInferenceBehavior::BackwardScanOnly)
66
- << " Unable to remove release" ;
85
+ SILValue root = rcfi.getRCIdentityRoot (sri->getOperand ());
86
+ SmallVector<Argument, 8 > inferredArgs;
87
+ bool foundArgs = Argument::inferArgumentsForValue (
88
+ ArgumentKeyKind::Note, " on value:" , root, [&](Argument arg) {
89
+ inferredArgs.push_back (arg);
90
+ return true ;
91
+ });
92
+ (void )foundArgs;
93
+ auto remark = RemarkMissed (" memory-management" , *sri,
94
+ SourceLocInferenceBehavior::BackwardScanOnly)
95
+ << " Found release:" ;
96
+ if (inferredArgs.empty ()) {
97
+ remark << Argument ({ArgumentKeyKind::ParentLocNote, " InferValueFailure" },
98
+ " Unable to infer any values being released." );
99
+ } else {
100
+ for (auto arg : inferredArgs) {
101
+ remark << arg;
102
+ }
103
+ }
104
+ return remark;
67
105
});
68
106
}
69
107
70
108
void OptRemarkGeneratorInstructionVisitor::visitRetainValueInst (
71
109
RetainValueInst *rvi) {
72
110
ORE.emit ([&]() {
73
111
using namespace OptRemark ;
112
+ SILValue root = rcfi.getRCIdentityRoot (rvi->getOperand ());
113
+ SmallVector<Argument, 8 > inferredArgs;
114
+ bool foundArgs = Argument::inferArgumentsForValue (
115
+ ArgumentKeyKind::Note, " on value:" , root, [&](Argument arg) {
116
+ inferredArgs.push_back (arg);
117
+ return true ;
118
+ });
119
+ (void )foundArgs;
120
+
74
121
// Retains begin a lifetime scope, so we infer scan forwards.
75
- return RemarkMissed (" memory-management" , *rvi,
76
- SourceLocInferenceBehavior::ForwardScanOnly)
77
- << " Unable to remove retain" ;
122
+ auto remark = RemarkMissed (" memory-management" , *rvi,
123
+ SourceLocInferenceBehavior::ForwardScanOnly)
124
+ << " Found retain:" ;
125
+ if (inferredArgs.empty ()) {
126
+ remark << Argument ({ArgumentKeyKind::ParentLocNote, " InferValueFailure" },
127
+ " Unable to infer any values being retained." );
128
+ } else {
129
+ for (auto arg : inferredArgs) {
130
+ remark << arg;
131
+ }
132
+ }
133
+ return remark;
78
134
});
79
135
}
80
136
81
137
void OptRemarkGeneratorInstructionVisitor::visitReleaseValueInst (
82
138
ReleaseValueInst *rvi) {
83
139
ORE.emit ([&]() {
84
140
using namespace OptRemark ;
141
+ SILValue root = rcfi.getRCIdentityRoot (rvi->getOperand ());
142
+ SmallVector<Argument, 8 > inferredArgs;
143
+ bool foundArgs = Argument::inferArgumentsForValue (
144
+ ArgumentKeyKind::Note, " on value:" , root, [&](Argument arg) {
145
+ inferredArgs.push_back (arg);
146
+ return true ;
147
+ });
148
+ (void )foundArgs;
149
+
85
150
// Releases end a lifetime scope so we infer scan backward.
86
- return RemarkMissed (" memory-management" , *rvi,
87
- SourceLocInferenceBehavior::BackwardScanOnly)
88
- << " Unable to remove release" ;
151
+ auto remark = RemarkMissed (" memory-management" , *rvi,
152
+ SourceLocInferenceBehavior::BackwardScanOnly)
153
+ << " Found release:" ;
154
+ if (inferredArgs.empty ()) {
155
+ remark << Argument ({ArgumentKeyKind::ParentLocNote, " InferValueFailure" },
156
+ " Unable to infer any values being released." );
157
+ } else {
158
+ for (auto arg : inferredArgs) {
159
+ remark << arg;
160
+ }
161
+ }
162
+
163
+ return remark;
89
164
});
90
165
}
91
166
@@ -115,7 +190,8 @@ class OptRemarkGenerator : public SILFunctionTransform {
115
190
116
191
auto *fn = getFunction ();
117
192
LLVM_DEBUG (llvm::dbgs () << " Visiting: " << fn->getName () << " \n " );
118
- OptRemarkGeneratorInstructionVisitor visitor (fn->getModule ());
193
+ auto &rcfi = *getAnalysis<RCIdentityAnalysis>()->get (fn);
194
+ OptRemarkGeneratorInstructionVisitor visitor (fn->getModule (), rcfi);
119
195
for (auto &block : *fn) {
120
196
for (auto &inst : block) {
121
197
visitor.visit (&inst);
0 commit comments