Skip to content

Commit 1757893

Browse files
authored
Merge pull request #33820 from gottesmm/pr-2022a20c73c213c8d5041a6de01d0874cd466764
[opt-remark] Infer the source loc retain, release even if they have non-inlined locs.
2 parents 26b9e0e + c54fb33 commit 1757893

File tree

5 files changed

+71
-67
lines changed

5 files changed

+71
-67
lines changed

include/swift/SIL/OptimizationRemark.h

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -137,14 +137,26 @@ struct IndentDebug {
137137
unsigned width;
138138
};
139139

140-
enum class SourceLocInferenceBehavior {
141-
None,
142-
ForwardScanOnly,
143-
BackwardScanOnly,
144-
ForwardThenBackward,
145-
BackwardThenForward,
140+
enum class SourceLocInferenceBehavior : unsigned {
141+
None = 0,
142+
ForwardScan = 0x1,
143+
BackwardScan = 0x2,
144+
ForwardScan2nd = 0x4,
145+
AlwaysInfer = 0x8,
146+
147+
ForwardThenBackwards = ForwardScan | BackwardScan,
148+
BackwardsThenForwards = BackwardScan | ForwardScan2nd,
149+
ForwardScanAlwaysInfer = ForwardScan | AlwaysInfer,
150+
BackwardScanAlwaysInfer = BackwardScan | AlwaysInfer,
146151
};
147152

153+
inline SourceLocInferenceBehavior operator&(SourceLocInferenceBehavior lhs,
154+
SourceLocInferenceBehavior rhs) {
155+
auto lhsVal = std::underlying_type<SourceLocInferenceBehavior>::type(lhs);
156+
auto rhsVal = std::underlying_type<SourceLocInferenceBehavior>::type(rhs);
157+
return SourceLocInferenceBehavior(lhsVal & rhsVal);
158+
}
159+
148160
/// Infer the proper SourceLoc to use for the given SILInstruction.
149161
///
150162
/// This means that if we have a valid location for the instruction, we just

lib/SIL/Utils/OptimizationRemark.cpp

Lines changed: 25 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -182,59 +182,48 @@ static SourceLoc inferOptRemarkSearchBackwards(SILInstruction &i) {
182182
return SourceLoc();
183183
}
184184

185+
static llvm::cl::opt<bool> IgnoreAlwaysInferForTesting(
186+
"sil-opt-remark-ignore-always-infer", llvm::cl::Hidden,
187+
llvm::cl::init(false),
188+
llvm::cl::desc(
189+
"Disables always infer source loc behavior for testing purposes"));
190+
191+
// Attempt to infer a SourceLoc for \p i using heuristics specified by \p
192+
// inferBehavior.
193+
//
194+
// NOTE: We distinguish in between situations where we always must infer
195+
// (retain, release) and other situations where we are ok with original source
196+
// locs if we are not inlined (alloc_ref, alloc_stack).
185197
SourceLoc swift::OptRemark::inferOptRemarkSourceLoc(
186198
SILInstruction &i, SourceLocInferenceBehavior inferBehavior) {
187-
// Do a quick check if we already have a valid loc and it isnt an inline
188-
// loc. In such a case, just return. Otherwise, we try to infer using one of
189-
// our heuristics below.
199+
// If we are only supposed to infer in inline contexts, see if we have a valid
200+
// loc and if that loc is an inlined call site.
190201
auto loc = i.getLoc();
191-
if (loc.getSourceLoc().isValid()) {
192-
// Before we do anything, if we do not have an inlined call site, just
193-
// return our loc.
194-
if (!i.getDebugScope() || !i.getDebugScope()->InlinedCallSite)
195-
return loc.getSourceLoc();
196-
}
202+
if (loc.getSourceLoc().isValid() &&
203+
!(bool(inferBehavior & SourceLocInferenceBehavior::AlwaysInfer) &&
204+
!IgnoreAlwaysInferForTesting) &&
205+
!(i.getDebugScope() && i.getDebugScope()->InlinedCallSite))
206+
return loc.getSourceLoc();
197207

198-
// Otherwise, try to handle the individual behavior cases, returning loc at
199-
// the end of each case (its invalid, so it will get ignored). If loc is not
200-
// returned, we hit an assert at the end to make it easy to identify a case
201-
// was missed.
202-
switch (inferBehavior) {
203-
case SourceLocInferenceBehavior::None:
204-
return SourceLoc();
205-
case SourceLocInferenceBehavior::ForwardScanOnly: {
208+
if (bool(inferBehavior & SourceLocInferenceBehavior::ForwardScan)) {
206209
SourceLoc newLoc = inferOptRemarkSearchForwards(i);
207210
if (newLoc.isValid())
208211
return newLoc;
209-
return SourceLoc();
210212
}
211-
case SourceLocInferenceBehavior::BackwardScanOnly: {
213+
214+
if (bool(inferBehavior & SourceLocInferenceBehavior::BackwardScan)) {
212215
SourceLoc newLoc = inferOptRemarkSearchBackwards(i);
213216
if (newLoc.isValid())
214217
return newLoc;
215-
return SourceLoc();
216218
}
217-
case SourceLocInferenceBehavior::ForwardThenBackward: {
219+
220+
if (bool(inferBehavior & SourceLocInferenceBehavior::ForwardScan2nd)) {
218221
SourceLoc newLoc = inferOptRemarkSearchForwards(i);
219222
if (newLoc.isValid())
220223
return newLoc;
221-
newLoc = inferOptRemarkSearchBackwards(i);
222-
if (newLoc.isValid())
223-
return newLoc;
224-
return SourceLoc();
225-
}
226-
case SourceLocInferenceBehavior::BackwardThenForward: {
227-
SourceLoc newLoc = inferOptRemarkSearchBackwards(i);
228-
if (newLoc.isValid())
229-
return newLoc;
230-
newLoc = inferOptRemarkSearchForwards(i);
231-
if (newLoc.isValid())
232-
return newLoc;
233-
return SourceLoc();
234-
}
235224
}
236225

237-
llvm_unreachable("Covered switch isn't covered?!");
226+
return SourceLoc();
238227
}
239228

240229
template <typename RemarkT, typename... ArgTypes>

lib/SILOptimizer/Transforms/OptRemarkGenerator.cpp

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -425,10 +425,11 @@ void OptRemarkGeneratorInstructionVisitor::visitStrongRetainInst(
425425
(void)foundArgs;
426426

427427
// Retains begin a lifetime scope so we infer scan forward.
428-
auto remark = RemarkMissed("memory", *sri,
429-
SourceLocInferenceBehavior::ForwardScanOnly)
430-
<< "retain of type '"
431-
<< NV("ValueType", sri->getOperand()->getType()) << "'";
428+
auto remark =
429+
RemarkMissed("memory", *sri,
430+
SourceLocInferenceBehavior::ForwardScanAlwaysInfer)
431+
<< "retain of type '" << NV("ValueType", sri->getOperand()->getType())
432+
<< "'";
432433
for (auto arg : inferredArgs) {
433434
remark << arg;
434435
}
@@ -446,10 +447,11 @@ void OptRemarkGeneratorInstructionVisitor::visitStrongReleaseInst(
446447
sri->getOperand(), inferredArgs);
447448
(void)foundArgs;
448449

449-
auto remark = RemarkMissed("memory", *sri,
450-
SourceLocInferenceBehavior::BackwardScanOnly)
451-
<< "release of type '"
452-
<< NV("ValueType", sri->getOperand()->getType()) << "'";
450+
auto remark =
451+
RemarkMissed("memory", *sri,
452+
SourceLocInferenceBehavior::BackwardScanAlwaysInfer)
453+
<< "release of type '" << NV("ValueType", sri->getOperand()->getType())
454+
<< "'";
453455
for (auto arg : inferredArgs) {
454456
remark << arg;
455457
}
@@ -466,10 +468,11 @@ void OptRemarkGeneratorInstructionVisitor::visitRetainValueInst(
466468
rvi->getOperand(), inferredArgs);
467469
(void)foundArgs;
468470
// Retains begin a lifetime scope, so we infer scan forwards.
469-
auto remark = RemarkMissed("memory", *rvi,
470-
SourceLocInferenceBehavior::ForwardScanOnly)
471-
<< "retain of type '"
472-
<< NV("ValueType", rvi->getOperand()->getType()) << "'";
471+
auto remark =
472+
RemarkMissed("memory", *rvi,
473+
SourceLocInferenceBehavior::ForwardScanAlwaysInfer)
474+
<< "retain of type '" << NV("ValueType", rvi->getOperand()->getType())
475+
<< "'";
473476
for (auto arg : inferredArgs) {
474477
remark << arg;
475478
}
@@ -487,10 +490,11 @@ void OptRemarkGeneratorInstructionVisitor::visitReleaseValueInst(
487490
(void)foundArgs;
488491

489492
// Releases end a lifetime scope so we infer scan backward.
490-
auto remark = RemarkMissed("memory", *rvi,
491-
SourceLocInferenceBehavior::BackwardScanOnly)
492-
<< "release of type '"
493-
<< NV("ValueType", rvi->getOperand()->getType()) << "'";
493+
auto remark =
494+
RemarkMissed("memory", *rvi,
495+
SourceLocInferenceBehavior::BackwardScanAlwaysInfer)
496+
<< "release of type '" << NV("ValueType", rvi->getOperand()->getType())
497+
<< "'";
494498
for (auto arg : inferredArgs) {
495499
remark << arg;
496500
}
@@ -508,8 +512,7 @@ void OptRemarkGeneratorInstructionVisitor::visitAllocRefInst(
508512
valueToDeclInferrer.infer(ArgumentKeyKind::Note, ari, inferredArgs);
509513
(void)foundArgs;
510514
auto resultRemark =
511-
RemarkPassed("memory", *ari,
512-
SourceLocInferenceBehavior::ForwardScanOnly)
515+
RemarkPassed("memory", *ari, SourceLocInferenceBehavior::ForwardScan)
513516
<< "stack allocated ref of type '" << NV("ValueType", ari->getType())
514517
<< "'";
515518
for (auto &arg : inferredArgs)
@@ -526,8 +529,7 @@ void OptRemarkGeneratorInstructionVisitor::visitAllocRefInst(
526529
(void)foundArgs;
527530

528531
auto resultRemark =
529-
RemarkMissed("memory", *ari,
530-
SourceLocInferenceBehavior::ForwardScanOnly)
532+
RemarkMissed("memory", *ari, SourceLocInferenceBehavior::ForwardScan)
531533
<< "heap allocated ref of type '" << NV("ValueType", ari->getType())
532534
<< "'";
533535
for (auto &arg : inferredArgs)
@@ -546,8 +548,7 @@ void OptRemarkGeneratorInstructionVisitor::visitAllocBoxInst(
546548
(void)foundArgs;
547549

548550
auto resultRemark =
549-
RemarkMissed("memory", *abi,
550-
SourceLocInferenceBehavior::ForwardScanOnly)
551+
RemarkMissed("memory", *abi, SourceLocInferenceBehavior::ForwardScan)
551552
<< "heap allocated box of type '" << NV("ValueType", abi->getType())
552553
<< "'";
553554
for (auto &arg : inferredArgs)

test/SILOptimizer/opt-remark-generator.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-sil-opt -optremarkgen-declless-debugvalue-use-sildebugvar-info -sil-opt-remark-generator -sil-remarks-missed=sil-opt-remark-gen -verify %s -o /dev/null
1+
// RUN: %target-sil-opt -sil-opt-remark-ignore-always-infer -optremarkgen-declless-debugvalue-use-sildebugvar-info -sil-opt-remark-generator -sil-remarks-missed=sil-opt-remark-gen -verify %s -o /dev/null
22

33
sil_stage canonical
44

test/SILOptimizer/opt-remark-generator.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,10 @@ func printKlassPairLHS(x : KlassPair) {
9090
// expected-remark @-3:16 {{release of type}}
9191
}
9292

93+
// We put the retain on the return here since it is part of the result
94+
// convention.
9395
func returnKlassPairLHS(x: KlassPair) -> Klass {
94-
return x.lhs // expected-remark @:14 {{retain of type 'Klass'}}
96+
return x.lhs // expected-remark @:5 {{retain of type 'Klass'}}
9597
// expected-note @-2:25 {{of 'x.lhs'}}
9698
}
9799

@@ -123,7 +125,7 @@ func printKlassTupleLHS(x : (Klass, Klass)) {
123125
}
124126

125127
func returnKlassTupleLHS(x: (Klass, Klass)) -> Klass {
126-
return x.0 // expected-remark @:12 {{retain of type 'Klass'}}
128+
return x.0 // expected-remark @:5 {{retain of type 'Klass'}}
127129
// expected-note @-2:26 {{of 'x'}}
128130
}
129131

0 commit comments

Comments
 (0)