Skip to content

Commit 7ac1e05

Browse files
committed
[clang-doc] Reenable time trace support
This patch re-enables -ftime-trace support in clang-doc. Initial support in #97644 was reverted, and never relanded. This patch adds back the command line option, and leverages the RAII tracing infrastructure more thoroughly.
1 parent 317c932 commit 7ac1e05

File tree

6 files changed

+268
-163
lines changed

6 files changed

+268
-163
lines changed

clang-tools-extra/clang-doc/BitcodeReader.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "BitcodeReader.h"
1010
#include "llvm/ADT/IndexedMap.h"
1111
#include "llvm/Support/Error.h"
12+
#include "llvm/Support/TimeProfiler.h"
1213
#include "llvm/Support/raw_ostream.h"
1314
#include <optional>
1415

@@ -672,6 +673,7 @@ llvm::Error ClangDocBitcodeReader::readRecord(unsigned ID, T I) {
672673

673674
template <>
674675
llvm::Error ClangDocBitcodeReader::readRecord(unsigned ID, Reference *I) {
676+
llvm::TimeTraceScope("Reducing infos", "readRecord");
675677
Record R;
676678
llvm::StringRef Blob;
677679
llvm::Expected<unsigned> MaybeRecID = Stream.readRecord(ID, R, &Blob);
@@ -683,6 +685,7 @@ llvm::Error ClangDocBitcodeReader::readRecord(unsigned ID, Reference *I) {
683685
// Read a block of records into a single info.
684686
template <typename T>
685687
llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, T I) {
688+
llvm::TimeTraceScope("Reducing infos", "readBlock");
686689
if (llvm::Error Err = Stream.EnterSubBlock(ID))
687690
return Err;
688691

@@ -713,6 +716,7 @@ llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, T I) {
713716

714717
template <typename T>
715718
llvm::Error ClangDocBitcodeReader::readSubBlock(unsigned ID, T I) {
719+
llvm::TimeTraceScope("Reducing infos", "readSubBlock");
716720
switch (ID) {
717721
// Blocks can only have certain types of sub blocks.
718722
case BI_COMMENT_BLOCK_ID: {
@@ -819,6 +823,7 @@ llvm::Error ClangDocBitcodeReader::readSubBlock(unsigned ID, T I) {
819823

820824
ClangDocBitcodeReader::Cursor
821825
ClangDocBitcodeReader::skipUntilRecordOrBlock(unsigned &BlockOrRecordID) {
826+
llvm::TimeTraceScope("Reducing infos", "skipUntilRecordOrBlock");
822827
BlockOrRecordID = 0;
823828

824829
while (!Stream.AtEndOfStream()) {
@@ -880,6 +885,7 @@ llvm::Error ClangDocBitcodeReader::validateStream() {
880885
}
881886

882887
llvm::Error ClangDocBitcodeReader::readBlockInfoBlock() {
888+
llvm::TimeTraceScope("Reducing infos", "readBlockInfoBlock");
883889
Expected<std::optional<llvm::BitstreamBlockInfo>> MaybeBlockInfo =
884890
Stream.ReadBlockInfoBlock();
885891
if (!MaybeBlockInfo)
@@ -895,6 +901,7 @@ llvm::Error ClangDocBitcodeReader::readBlockInfoBlock() {
895901
template <typename T>
896902
llvm::Expected<std::unique_ptr<Info>>
897903
ClangDocBitcodeReader::createInfo(unsigned ID) {
904+
llvm::TimeTraceScope("Reducing infos", "createInfo");
898905
std::unique_ptr<Info> I = std::make_unique<T>();
899906
if (auto Err = readBlock(ID, static_cast<T *>(I.get())))
900907
return std::move(Err);
@@ -903,6 +910,7 @@ ClangDocBitcodeReader::createInfo(unsigned ID) {
903910

904911
llvm::Expected<std::unique_ptr<Info>>
905912
ClangDocBitcodeReader::readBlockToInfo(unsigned ID) {
913+
llvm::TimeTraceScope("Reducing infos", "readBlockToInfo");
906914
switch (ID) {
907915
case BI_NAMESPACE_BLOCK_ID:
908916
return createInfo<NamespaceInfo>(ID);

clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#include "llvm/Support/Error.h"
1919
#include "llvm/Support/MemoryBuffer.h"
2020
#include "llvm/Support/Mustache.h"
21+
#include "llvm/Support/Path.h"
22+
#include "llvm/Support/TimeProfiler.h"
2123

2224
using namespace llvm;
2325
using namespace llvm::json;
@@ -81,13 +83,18 @@ static Error setupTemplateFiles(const clang::doc::ClangDocContext &CDCtx) {
8183
Error MustacheHTMLGenerator::generateDocs(
8284
StringRef RootDir, StringMap<std::unique_ptr<doc::Info>> Infos,
8385
const clang::doc::ClangDocContext &CDCtx) {
84-
if (auto Err = setupTemplateFiles(CDCtx))
85-
return Err;
86+
{
87+
llvm::TimeTraceScope TS("Setup Templates");
88+
if (auto Err = setupTemplateFiles(CDCtx))
89+
return Err;
90+
}
91+
8692
// Track which directories we already tried to create.
8793
StringSet<> CreatedDirs;
8894
// Collect all output by file name and create the necessary directories.
8995
StringMap<std::vector<doc::Info *>> FileToInfos;
9096
for (const auto &Group : Infos) {
97+
llvm::TimeTraceScope TS("setup directories");
9198
doc::Info *Info = Group.getValue().get();
9299

93100
SmallString<128> Path;
@@ -104,15 +111,19 @@ Error MustacheHTMLGenerator::generateDocs(
104111
FileToInfos[Path].push_back(Info);
105112
}
106113

107-
for (const auto &Group : FileToInfos) {
108-
std::error_code FileErr;
109-
raw_fd_ostream InfoOS(Group.getKey(), FileErr, sys::fs::OF_None);
110-
if (FileErr)
111-
return createFileOpenError(Group.getKey(), FileErr);
112-
113-
for (const auto &Info : Group.getValue())
114-
if (Error Err = generateDocForInfo(Info, InfoOS, CDCtx))
115-
return Err;
114+
{
115+
llvm::TimeTraceScope TS("Generate Docs");
116+
for (const auto &Group : FileToInfos) {
117+
llvm::TimeTraceScope TS("Info to Doc");
118+
std::error_code FileErr;
119+
raw_fd_ostream InfoOS(Group.getKey(), FileErr, sys::fs::OF_None);
120+
if (FileErr)
121+
return createFileOpenError(Group.getKey(), FileErr);
122+
123+
for (const auto &Info : Group.getValue())
124+
if (Error Err = generateDocForInfo(Info, InfoOS, CDCtx))
125+
return Err;
126+
}
116127
}
117128
return Error::success();
118129
}

clang-tools-extra/clang-doc/Mapper.cpp

Lines changed: 52 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
#include "clang/Index/USRGeneration.h"
1414
#include "llvm/ADT/StringExtras.h"
1515
#include "llvm/ADT/StringSet.h"
16+
#include "llvm/Support/Error.h"
1617
#include "llvm/Support/Mutex.h"
18+
#include "llvm/Support/TimeProfiler.h"
1719

1820
namespace clang {
1921
namespace doc {
@@ -40,48 +42,66 @@ Location MapASTVisitor::getDeclLocation(const NamedDecl *D) const {
4042
}
4143

4244
void MapASTVisitor::HandleTranslationUnit(ASTContext &Context) {
45+
if (CDCtx.FTimeTrace)
46+
llvm::timeTraceProfilerInitialize(200, "clang-doc");
4347
TraverseDecl(Context.getTranslationUnitDecl());
48+
if (CDCtx.FTimeTrace)
49+
llvm::timeTraceProfilerFinishThread();
4450
}
4551

4652
template <typename T>
4753
bool MapASTVisitor::mapDecl(const T *D, bool IsDefinition) {
48-
// If we're looking a decl not in user files, skip this decl.
49-
if (D->getASTContext().getSourceManager().isInSystemHeader(D->getLocation()))
50-
return true;
54+
llvm::TimeTraceScope TS("Mapping declaration");
55+
{
56+
llvm::TimeTraceScope TS("Preamble");
57+
// If we're looking a decl not in user files, skip this decl.
58+
if (D->getASTContext().getSourceManager().isInSystemHeader(
59+
D->getLocation()))
60+
return true;
5161

52-
// Skip function-internal decls.
53-
if (D->getParentFunctionOrMethod())
54-
return true;
62+
// Skip function-internal decls.
63+
if (D->getParentFunctionOrMethod())
64+
return true;
65+
}
66+
67+
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>> CP;
5568

56-
llvm::SmallString<128> USR;
57-
// If there is an error generating a USR for the decl, skip this decl.
58-
if (index::generateUSRForDecl(D, USR))
59-
return true;
60-
// Prevent Visiting USR twice
6169
{
62-
llvm::sys::SmartScopedLock<true> Guard(USRVisitedGuard);
63-
StringRef Visited = USR.str();
64-
if (USRVisited.count(Visited) && !isTypedefAnonRecord<T>(D))
70+
llvm::TimeTraceScope TS("emit info from astnode");
71+
llvm::SmallString<128> USR;
72+
// If there is an error generating a USR for the decl, skip this decl.
73+
if (index::generateUSRForDecl(D, USR))
6574
return true;
66-
// We considered a USR to be visited only when its defined
67-
if (IsDefinition)
68-
USRVisited.insert(Visited);
75+
// Prevent Visiting USR twice
76+
{
77+
llvm::sys::SmartScopedLock<true> Guard(USRVisitedGuard);
78+
StringRef Visited = USR.str();
79+
if (USRVisited.count(Visited) && !isTypedefAnonRecord<T>(D))
80+
return true;
81+
// We considered a USR to be visited only when its defined
82+
if (IsDefinition)
83+
USRVisited.insert(Visited);
84+
}
85+
bool IsFileInRootDir;
86+
llvm::SmallString<128> File =
87+
getFile(D, D->getASTContext(), CDCtx.SourceRoot, IsFileInRootDir);
88+
CP = serialize::emitInfo(D, getComment(D, D->getASTContext()),
89+
getDeclLocation(D), CDCtx.PublicOnly);
90+
}
91+
92+
auto &[Child, Parent] = CP;
93+
94+
{
95+
llvm::TimeTraceScope TS("serialized info into bitcode");
96+
// A null in place of a valid Info indicates that the serializer is skipping
97+
// this decl for some reason (e.g. we're only reporting public decls).
98+
if (Child)
99+
CDCtx.ECtx->reportResult(llvm::toHex(llvm::toStringRef(Child->USR)),
100+
serialize::serialize(Child));
101+
if (Parent)
102+
CDCtx.ECtx->reportResult(llvm::toHex(llvm::toStringRef(Parent->USR)),
103+
serialize::serialize(Parent));
69104
}
70-
bool IsFileInRootDir;
71-
llvm::SmallString<128> File =
72-
getFile(D, D->getASTContext(), CDCtx.SourceRoot, IsFileInRootDir);
73-
auto [Child, Parent] =
74-
serialize::emitInfo(D, getComment(D, D->getASTContext()),
75-
getDeclLocation(D), CDCtx.PublicOnly);
76-
77-
// A null in place of a valid Info indicates that the serializer is skipping
78-
// this decl for some reason (e.g. we're only reporting public decls).
79-
if (Child)
80-
CDCtx.ECtx->reportResult(llvm::toHex(llvm::toStringRef(Child->USR)),
81-
serialize::serialize(Child));
82-
if (Parent)
83-
CDCtx.ECtx->reportResult(llvm::toHex(llvm::toStringRef(Parent->USR)),
84-
serialize::serialize(Parent));
85105
return true;
86106
}
87107

clang-tools-extra/clang-doc/Representation.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -369,9 +369,11 @@ ClangDocContext::ClangDocContext(tooling::ExecutionContext *ECtx,
369369
StringRef OutDirectory, StringRef SourceRoot,
370370
StringRef RepositoryUrl,
371371
StringRef RepositoryLinePrefix, StringRef Base,
372-
std::vector<std::string> UserStylesheets)
372+
std::vector<std::string> UserStylesheets,
373+
bool FTimeTrace)
373374
: ECtx(ECtx), ProjectName(ProjectName), PublicOnly(PublicOnly),
374-
OutDirectory(OutDirectory), UserStylesheets(UserStylesheets), Base(Base) {
375+
FTimeTrace(FTimeTrace), OutDirectory(OutDirectory),
376+
UserStylesheets(UserStylesheets), Base(Base) {
375377
llvm::SmallString<128> SourceRootDir(SourceRoot);
376378
if (SourceRoot.empty())
377379
// If no SourceRoot was provided the current path is used as the default

clang-tools-extra/clang-doc/Representation.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -518,10 +518,13 @@ struct ClangDocContext {
518518
ClangDocContext(tooling::ExecutionContext *ECtx, StringRef ProjectName,
519519
bool PublicOnly, StringRef OutDirectory, StringRef SourceRoot,
520520
StringRef RepositoryUrl, StringRef RepositoryCodeLinePrefix,
521-
StringRef Base, std::vector<std::string> UserStylesheets);
521+
StringRef Base, std::vector<std::string> UserStylesheets,
522+
bool FTimeTrace = false);
522523
tooling::ExecutionContext *ECtx;
523524
std::string ProjectName; // Name of project clang-doc is documenting.
524525
bool PublicOnly; // Indicates if only public declarations are documented.
526+
bool FTimeTrace; // Indicates if ftime trace is turned on
527+
int Granularity; // Granularity of ftime trace
525528
std::string OutDirectory; // Directory for outputting generated files.
526529
std::string SourceRoot; // Directory where processed files are stored. Links
527530
// to definition locations will only be generated if

0 commit comments

Comments
 (0)