[clang] e6a76a4 - [Clang][CoverageMapping] Fix compile time explosions by adjusting only appropriated skipped ranges

Bruno Cardoso Lopes via cfe-commits cfe-commits at lists.llvm.org
Wed Jun 8 23:13:58 PDT 2022


Author: Bruno Cardoso Lopes
Date: 2022-06-08T23:13:39-07:00
New Revision: e6a76a49356efd11f5f36690181f0f60cecb2e01

URL: https://github.com/llvm/llvm-project/commit/e6a76a49356efd11f5f36690181f0f60cecb2e01
DIFF: https://github.com/llvm/llvm-project/commit/e6a76a49356efd11f5f36690181f0f60cecb2e01.diff

LOG: [Clang][CoverageMapping] Fix compile time explosions by adjusting only appropriated skipped ranges

D83592 added comments to be part of skipped regions, and as part of that, it
also shrinks a skipped range if it spans a line that contains a non-comment
token. This is done by `adjustSkippedRange`.

The `adjustSkippedRange` currently runs on skipped regions that are not
comments, causing a 5min regression while building a big C++ files without any
comments.

Fix the compile time introduced in D83592 by tagging SkippedRange with kind
information and use that to decide what needs additional processing.

Differential Revision: https://reviews.llvm.org/D127338

Added: 
    

Modified: 
    clang/lib/CodeGen/CoverageMappingGen.cpp
    clang/lib/CodeGen/CoverageMappingGen.h

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp
index 8952125eeefcb..d1cbe109a6cf8 100644
--- a/clang/lib/CodeGen/CoverageMappingGen.cpp
+++ b/clang/lib/CodeGen/CoverageMappingGen.cpp
@@ -60,26 +60,27 @@ CoverageMappingModuleGen::setUpCoverageCallbacks(Preprocessor &PP) {
   return CoverageInfo;
 }
 
-void CoverageSourceInfo::AddSkippedRange(SourceRange Range) {
+void CoverageSourceInfo::AddSkippedRange(SourceRange Range,
+                                         SkippedRange::Kind RangeKind) {
   if (EmptyLineCommentCoverage && !SkippedRanges.empty() &&
       PrevTokLoc == SkippedRanges.back().PrevTokLoc &&
       SourceMgr.isWrittenInSameFile(SkippedRanges.back().Range.getEnd(),
                                     Range.getBegin()))
     SkippedRanges.back().Range.setEnd(Range.getEnd());
   else
-    SkippedRanges.push_back({Range, PrevTokLoc});
+    SkippedRanges.push_back({Range, RangeKind, PrevTokLoc});
 }
 
 void CoverageSourceInfo::SourceRangeSkipped(SourceRange Range, SourceLocation) {
-  AddSkippedRange(Range);
+  AddSkippedRange(Range, SkippedRange::PPIfElse);
 }
 
 void CoverageSourceInfo::HandleEmptyline(SourceRange Range) {
-  AddSkippedRange(Range);
+  AddSkippedRange(Range, SkippedRange::EmptyLine);
 }
 
 bool CoverageSourceInfo::HandleComment(Preprocessor &PP, SourceRange Range) {
-  AddSkippedRange(Range);
+  AddSkippedRange(Range, SkippedRange::Comment);
   return false;
 }
 
@@ -335,6 +336,8 @@ class CoverageMappingBuilder {
   /// This shrinks the skipped range if it spans a line that contains a
   /// non-comment token. If shrinking the skipped range would make it empty,
   /// this returns None.
+  /// Note this function can potentially be expensive because
+  /// getSpellingLineNumber uses getLineNumber, which is expensive.
   Optional<SpellingRegion> adjustSkippedRange(SourceManager &SM,
                                               SourceLocation LocStart,
                                               SourceLocation LocEnd,
@@ -382,8 +385,13 @@ class CoverageMappingBuilder {
       auto CovFileID = getCoverageFileID(LocStart);
       if (!CovFileID)
         continue;
-      Optional<SpellingRegion> SR =
-          adjustSkippedRange(SM, LocStart, LocEnd, I.PrevTokLoc, I.NextTokLoc);
+      Optional<SpellingRegion> SR;
+      if (I.isComment())
+        SR = adjustSkippedRange(SM, LocStart, LocEnd, I.PrevTokLoc,
+                                I.NextTokLoc);
+      else if (I.isPPIfElse() || I.isEmptyLine())
+        SR = {SM, LocStart, LocEnd};
+
       if (!SR.hasValue())
         continue;
       auto Region = CounterMappingRegion::makeSkipped(

diff  --git a/clang/lib/CodeGen/CoverageMappingGen.h b/clang/lib/CodeGen/CoverageMappingGen.h
index ae4f435d4ff34..f5282601b6406 100644
--- a/clang/lib/CodeGen/CoverageMappingGen.h
+++ b/clang/lib/CodeGen/CoverageMappingGen.h
@@ -31,15 +31,29 @@ class Decl;
 class Stmt;
 
 struct SkippedRange {
+  enum Kind {
+    PPIfElse, // Preprocessor #if/#else ...
+    EmptyLine,
+    Comment,
+  };
+
   SourceRange Range;
   // The location of token before the skipped source range.
   SourceLocation PrevTokLoc;
   // The location of token after the skipped source range.
   SourceLocation NextTokLoc;
+  // The nature of this skipped range
+  Kind RangeKind;
+
+  bool isComment() { return RangeKind == Comment; }
+  bool isEmptyLine() { return RangeKind == EmptyLine; }
+  bool isPPIfElse() { return RangeKind == PPIfElse; }
 
-  SkippedRange(SourceRange Range, SourceLocation PrevTokLoc = SourceLocation(),
+  SkippedRange(SourceRange Range, Kind K,
+               SourceLocation PrevTokLoc = SourceLocation(),
                SourceLocation NextTokLoc = SourceLocation())
-      : Range(Range), PrevTokLoc(PrevTokLoc), NextTokLoc(NextTokLoc) {}
+      : Range(Range), PrevTokLoc(PrevTokLoc), NextTokLoc(NextTokLoc),
+        RangeKind(K) {}
 };
 
 /// Stores additional source code information like skipped ranges which
@@ -62,7 +76,7 @@ class CoverageSourceInfo : public PPCallbacks,
 
   std::vector<SkippedRange> &getSkippedRanges() { return SkippedRanges; }
 
-  void AddSkippedRange(SourceRange Range);
+  void AddSkippedRange(SourceRange Range, SkippedRange::Kind RangeKind);
 
   void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) override;
 


        


More information about the cfe-commits mailing list