[opt-remark] Infer the source loc retain, release even if they have non-inlined locs.

The reason why is that due to ARCCodeMotion, they could have moved enough that
the SourceLoc on them is incorrect. That is why you can see in the tests that I
had to update, I am moving the retain to the return statement from the body of
the function since the retain was now right before the return.

I also went in and cleaned up the logic here a little bit. What we do now is
that we have a notion of instructions that we /always/ infer SourceLocs for (rr)
and ones that if we have a valid non-inlined location we use (e.x.:
allocations).

This mucked a little bit with my ability to run SIL tests since the SIL tests
were relying on this not happening to rr so that we would emit remarks on the rr
instructions themselves. I added an option that disables the always infer
behavior for this test.

That being said at this point to me it seems like the SourceLoc inference stuff
is really tied to OptRemarkGenerator and I am going to see if I can move it to
there. But that is for a future commit on another day.
This commit is contained in:
Michael Gottesman
2020-09-04 20:08:40 -07:00
parent a7e8dbf469
commit c54fb33911
5 changed files with 71 additions and 67 deletions

View File

@@ -182,59 +182,48 @@ static SourceLoc inferOptRemarkSearchBackwards(SILInstruction &i) {
return SourceLoc();
}
static llvm::cl::opt<bool> IgnoreAlwaysInferForTesting(
"sil-opt-remark-ignore-always-infer", llvm::cl::Hidden,
llvm::cl::init(false),
llvm::cl::desc(
"Disables always infer source loc behavior for testing purposes"));
// Attempt to infer a SourceLoc for \p i using heuristics specified by \p
// inferBehavior.
//
// NOTE: We distinguish in between situations where we always must infer
// (retain, release) and other situations where we are ok with original source
// locs if we are not inlined (alloc_ref, alloc_stack).
SourceLoc swift::OptRemark::inferOptRemarkSourceLoc(
SILInstruction &i, SourceLocInferenceBehavior inferBehavior) {
// Do a quick check if we already have a valid loc and it isnt an inline
// loc. In such a case, just return. Otherwise, we try to infer using one of
// our heuristics below.
// If we are only supposed to infer in inline contexts, see if we have a valid
// loc and if that loc is an inlined call site.
auto loc = i.getLoc();
if (loc.getSourceLoc().isValid()) {
// Before we do anything, if we do not have an inlined call site, just
// return our loc.
if (!i.getDebugScope() || !i.getDebugScope()->InlinedCallSite)
return loc.getSourceLoc();
}
if (loc.getSourceLoc().isValid() &&
!(bool(inferBehavior & SourceLocInferenceBehavior::AlwaysInfer) &&
!IgnoreAlwaysInferForTesting) &&
!(i.getDebugScope() && i.getDebugScope()->InlinedCallSite))
return loc.getSourceLoc();
// Otherwise, try to handle the individual behavior cases, returning loc at
// the end of each case (its invalid, so it will get ignored). If loc is not
// returned, we hit an assert at the end to make it easy to identify a case
// was missed.
switch (inferBehavior) {
case SourceLocInferenceBehavior::None:
return SourceLoc();
case SourceLocInferenceBehavior::ForwardScanOnly: {
if (bool(inferBehavior & SourceLocInferenceBehavior::ForwardScan)) {
SourceLoc newLoc = inferOptRemarkSearchForwards(i);
if (newLoc.isValid())
return newLoc;
return SourceLoc();
}
case SourceLocInferenceBehavior::BackwardScanOnly: {
if (bool(inferBehavior & SourceLocInferenceBehavior::BackwardScan)) {
SourceLoc newLoc = inferOptRemarkSearchBackwards(i);
if (newLoc.isValid())
return newLoc;
return SourceLoc();
}
case SourceLocInferenceBehavior::ForwardThenBackward: {
if (bool(inferBehavior & SourceLocInferenceBehavior::ForwardScan2nd)) {
SourceLoc newLoc = inferOptRemarkSearchForwards(i);
if (newLoc.isValid())
return newLoc;
newLoc = inferOptRemarkSearchBackwards(i);
if (newLoc.isValid())
return newLoc;
return SourceLoc();
}
case SourceLocInferenceBehavior::BackwardThenForward: {
SourceLoc newLoc = inferOptRemarkSearchBackwards(i);
if (newLoc.isValid())
return newLoc;
newLoc = inferOptRemarkSearchForwards(i);
if (newLoc.isValid())
return newLoc;
return SourceLoc();
}
}
llvm_unreachable("Covered switch isn't covered?!");
return SourceLoc();
}
template <typename RemarkT, typename... ArgTypes>