Skip to content

Commit 41c65c1

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 c3656af commit 41c65c1

File tree

6 files changed

+267
-171
lines changed

6 files changed

+267
-171
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: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "llvm/Support/MemoryBuffer.h"
2020
#include "llvm/Support/Mustache.h"
2121
#include "llvm/Support/Path.h"
22+
#include "llvm/Support/TimeProfiler.h"
2223

2324
using namespace llvm;
2425
using namespace llvm::json;
@@ -125,13 +126,18 @@ static Error setupTemplateFiles(const clang::doc::ClangDocContext &CDCtx) {
125126
Error MustacheHTMLGenerator::generateDocs(
126127
StringRef RootDir, StringMap<std::unique_ptr<doc::Info>> Infos,
127128
const clang::doc::ClangDocContext &CDCtx) {
128-
if (auto Err = setupTemplateFiles(CDCtx))
129-
return Err;
129+
{
130+
llvm::TimeTraceScope TS("Setup Templates");
131+
if (auto Err = setupTemplateFiles(CDCtx))
132+
return Err;
133+
}
134+
130135
// Track which directories we already tried to create.
131136
StringSet<> CreatedDirs;
132137
// Collect all output by file name and create the necessary directories.
133138
StringMap<std::vector<doc::Info *>> FileToInfos;
134139
for (const auto &Group : Infos) {
140+
llvm::TimeTraceScope TS("setup directories");
135141
doc::Info *Info = Group.getValue().get();
136142

137143
SmallString<128> Path;
@@ -148,15 +154,19 @@ Error MustacheHTMLGenerator::generateDocs(
148154
FileToInfos[Path].push_back(Info);
149155
}
150156

151-
for (const auto &Group : FileToInfos) {
152-
std::error_code FileErr;
153-
raw_fd_ostream InfoOS(Group.getKey(), FileErr, sys::fs::OF_None);
154-
if (FileErr)
155-
return createFileOpenError(Group.getKey(), FileErr);
156-
157-
for (const auto &Info : Group.getValue())
158-
if (Error Err = generateDocForInfo(Info, InfoOS, CDCtx))
159-
return Err;
157+
{
158+
llvm::TimeTraceScope TS("Generate Docs");
159+
for (const auto &Group : FileToInfos) {
160+
llvm::TimeTraceScope TS("Info to Doc");
161+
std::error_code FileErr;
162+
raw_fd_ostream InfoOS(Group.getKey(), FileErr, sys::fs::OF_None);
163+
if (FileErr)
164+
return createFileOpenError(Group.getKey(), FileErr);
165+
166+
for (const auto &Info : Group.getValue())
167+
if (Error Err = generateDocForInfo(Info, InfoOS, CDCtx))
168+
return Err;
169+
}
160170
}
161171
return Error::success();
162172
}

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
@@ -524,10 +524,13 @@ struct ClangDocContext {
524524
ClangDocContext(tooling::ExecutionContext *ECtx, StringRef ProjectName,
525525
bool PublicOnly, StringRef OutDirectory, StringRef SourceRoot,
526526
StringRef RepositoryUrl, StringRef RepositoryCodeLinePrefix,
527-
StringRef Base, std::vector<std::string> UserStylesheets);
527+
StringRef Base, std::vector<std::string> UserStylesheets,
528+
bool FTimeTrace = false);
528529
tooling::ExecutionContext *ECtx;
529530
std::string ProjectName; // Name of project clang-doc is documenting.
530531
bool PublicOnly; // Indicates if only public declarations are documented.
532+
bool FTimeTrace; // Indicates if ftime trace is turned on
533+
int Granularity; // Granularity of ftime trace
531534
std::string OutDirectory; // Directory for outputting generated files.
532535
std::string SourceRoot; // Directory where processed files are stored. Links
533536
// to definition locations will only be generated if

0 commit comments

Comments
 (0)