[PATCH] D19678: Annotated-source optimization reports (a.k.a. "listing" files)

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Thu Apr 28 13:15:13 PDT 2016


rsmith added a comment.

You give this example:

>   343     |     Loc = ConvertBackendLocation(D, Context->getSourceManager());

>       I   |           ^

>       I   |                                     ^


How does this look for a case like `p->Foo()->Bar()` (where one or both of the calls are inlined)? Can we get the source location to point at the function name instead of the start of the expression to reduce the scope for ambiguity?


================
Comment at: lib/CodeGen/CodeGenAction.cpp:665-761
@@ +664,99 @@
+
+void BackendConsumer::GenerateListingFile() {
+  if (CodeGenOpts.ListingFile.empty())
+    return;
+
+  std::error_code EC;
+  llvm::raw_fd_ostream OS(CodeGenOpts.ListingFile, EC,
+              llvm::sys::fs::F_Text);
+  if (EC) {
+    Diags.Report(diag::err_fe_error_opening) << CodeGenOpts.ListingFile <<
+                                                EC.message();
+    return;
+  }
+
+  SourceManager &SourceMgr = Context->getSourceManager();
+  std::set<FileID> FileIDs;
+  for (auto &I : ListingInfo)
+    FileIDs.insert(SourceMgr.getFileID(I.first));
+
+  for (auto &FID : FileIDs) {
+    SourceLocation FirstLoc = SourceMgr.getLocForStartOfFile(FID);
+    OS << "< " << SourceMgr.getFilename(FirstLoc) << "\n";
+
+    auto I = ListingInfo.lower_bound(FirstLoc);
+    StringRef MB = SourceMgr.getBufferData(FID);
+    const SrcMgr::ContentCache *
+      Content = SourceMgr.getSLocEntry(FID).getFile().getContentCache();
+    unsigned LNDigits = llvm::utostr(Content->NumLines).size();
+    for (unsigned L = 0; L < Content->NumLines - 1; ++L) {
+      unsigned LStartOff = Content->SourceLineCache[L];
+      unsigned LEndOff = (L == Content->NumLines) ?
+                         Content->getSize() :
+                         Content->SourceLineCache[L + 1];
+
+      std::map<unsigned, ListingLineInfo> ColsInfo;
+      unsigned InlinedCols = 0, UnrolledCols = 0, VectorizedCols = 0;
+
+      ListingLineInfo LLI;
+      if (I != ListingInfo.end()) {
+        auto DI = SourceMgr.getDecomposedLoc(I->first);
+        while (I != ListingInfo.end() && DI.first == FID &&
+               DI.second < LStartOff) {
+          ++I;
+          if (I != ListingInfo.end())
+            DI = SourceMgr.getDecomposedLoc(I->first);
+        }
+
+        while (I != ListingInfo.end() && DI.first == FID &&
+            DI.second >= LStartOff && DI.second < LEndOff) {
+          unsigned Col = SourceMgr.getColumnNumber(FID, DI.second);
+          ColsInfo[Col] = I->second;
+          InlinedCols += I->second.Inlined.Analyzed;
+          UnrolledCols += I->second.Unrolled.Analyzed;
+          VectorizedCols += I->second.Vectorized.Analyzed;
+          LLI |= I->second;
+
+          ++I;
+          if (I != ListingInfo.end())
+            DI = SourceMgr.getDecomposedLoc(I->first);
+        }
+      }
+
+      // We try to keep the output as concise as possible. If only one thing on
+      // a given line could have been inlined, vectorized, etc. then we can put
+      // the marker on the source line itself. If there are multiple options
+      // then we want to distinguish them by placing the marker for each
+      // transformation on a separate line following the source line. When we
+      // do this, we use a '^' character to point to the appropriate column in
+      // the source line.
+
+      OS << llvm::format_decimal(L + 1, LNDigits) << " ";
+      OS << (LLI.Inlined.Transformed && InlinedCols < 2 ? "I" : " ");
+      OS << (LLI.Unrolled.Transformed && UnrolledCols < 2 ? "U" : " ");
+      OS << (LLI.Vectorized.Transformed && VectorizedCols < 2 ? "V" : " ");
+
+      OS << " | " << MB.slice(LStartOff, LEndOff);
+
+      for (auto &J : ColsInfo) {
+        if ((J.second.Inlined.Transformed && InlinedCols > 1) ||
+            (J.second.Unrolled.Transformed && UnrolledCols > 1) ||
+            (J.second.Vectorized.Transformed && VectorizedCols > 1)) {
+          OS << std::string(LNDigits + 1, ' ');
+          OS << (J.second.Inlined.Transformed &&
+                 InlinedCols > 1 ? "I" : " ");
+          OS << (J.second.Unrolled.Transformed &&
+                 UnrolledCols > 1 ? "U" : " ");
+          OS << (J.second.Vectorized.Transformed &&
+                 VectorizedCols > 1 ? "V" : " ");
+
+          OS << " | " << std::string(J.first - 1, ' ') << "^\n";
+        }
+      }
+
+      if (LEndOff == Content->getSize())
+        OS << "\n";
+    }
+  }
+}
+
----------------
I'd like this to be factored out and moved somewhere more appropriate (such as Frontend). It seems appropriate for CodeGen to generate the data structure here, but it should not be deciding how to format the report nor doing file IO to put it somewhere.

I would hope that we can combine this report information with the static analyzer's existing support for generating syntax-highlighted, annotated source code as HTML as a future extension.


http://reviews.llvm.org/D19678





More information about the cfe-commits mailing list