This is an archive of the discontinued LLVM Phabricator instance.

Add second fast path for DiagnosticsEngine::GetDiagStatePointForLoc
AbandonedPublic

Authored by djasper on Jan 1 2017, 12:43 AM.

Details

Reviewers
rsmith
Summary

In many translation units I have tested, many of the calls to DiagnosticsEngine::GetDiagStatePointForLoc are for source locations before the first diag state point. AFAICT, this happens frequently for locations in the STL and other base libraries. This patch adds a fast path for this case to avoid the costly binary search. This binary search is costly, because the relatively slow SourceManager::isBeforeInTranslationUnit() is used to compare DiagStatePoints.

Diff Detail

Event Timeline

djasper updated this revision to Diff 82782.Jan 1 2017, 12:43 AM
djasper retitled this revision from to Add second fast path for DiagnosticsEngine::GetDiagStatePointForLoc.
djasper updated this object.
djasper added a reviewer: rsmith.
djasper added a subscriber: cfe-commits.
rsmith added inline comments.Jan 2 2017, 2:57 PM
lib/Basic/Diagnostic.cpp
179

It's surprising to me that this would be particularly frequent.

I suspect what you're actually seeing is a consequence of a bug in how we manage DiagStatePoints with modules. It looks like ASTReader::InitializeContext is called once per top-level PCM file that we load, and its call to ReadPragmaDiagnosticMappings adds entries to the DiagStatePoints list regardless of whether they've already been added. So, we'll end up with duplicates in the DiagStatePoints list, and it won't even be in translation unit order.

Can you take a look at the DiagStatePoints list for a translation unit where you see a performance problem and check whether it seems reasonable?

djasper added inline comments.Jan 3 2017, 12:32 AM
lib/Basic/Diagnostic.cpp
179

I looked at the DiagStatePoints and they do look somewhat sane but suspicious.

The translation unit I am looking at has (AFAICT) only includes that get translated to modules. DiagStatePoints only has entries for the translation unit itself, not a single one coming from any of the modules. So DiagStatePoints looks like:

[0]: <<invalid>>  (for the command line)
[1]: myfile.cc:100
[2]: myfile.cc:100
...
[2500]: myfile.cc:2800

And because of that, the new fast path is hit every single time when a source location coming from a module is queried. There are always two entries for a line of myfile.cc which always seem to denote entering and exiting a macro.

So, specific questions:

  • Should there by DiagStatePoints from modules?
  • Should there really be a DiagStatePoint entry (or actually two) for every macro invocation in myfile.cc?
rsmith added inline comments.Jan 4 2017, 2:31 PM
lib/Basic/Diagnostic.cpp
179

Yes, there should be DiagStatePoints from modules, but support for that seems to basically be unimplemented at this point.

I believe the DiagStatePoints for macros are coming from a _Pragma("clang diagnostic ...") within the macro expansion. Doesn't look like there's any other way we'd create them.

djasper added inline comments.Jan 4 2017, 2:51 PM
lib/Basic/Diagnostic.cpp
179

Ah yes, you are right. I can probably fix that and I presume then this patch won't help as much anymore.

djasper abandoned this revision.Jan 9 2017, 1:22 AM