[CodeGen] Handle recursion in LLVMIRGeneration Timer.

This can happen when emitting a local decl, which triggers
loading a decl imported from an AST file, which we then
hand to the AST consumer. Timer is not allowed to recurse
so an assertion fire. Keep a reference counter to avoid this
problem. LGTM'd by Richard Smith on IRC.

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

llvm-svn: 276242
This commit is contained in:
Davide Italiano 2016-07-21 06:28:48 +00:00
parent 187db16996
commit b99fabd4ec
1 changed files with 23 additions and 8 deletions

View File

@ -49,6 +49,7 @@ namespace clang {
ASTContext *Context; ASTContext *Context;
Timer LLVMIRGeneration; Timer LLVMIRGeneration;
unsigned LLVMIRGenerationRefCount;
std::unique_ptr<CodeGenerator> Gen; std::unique_ptr<CodeGenerator> Gen;
@ -73,6 +74,7 @@ namespace clang {
TargetOpts(TargetOpts), LangOpts(LangOpts), TargetOpts(TargetOpts), LangOpts(LangOpts),
AsmOutStream(std::move(OS)), Context(nullptr), AsmOutStream(std::move(OS)), Context(nullptr),
LLVMIRGeneration("LLVM IR Generation Time"), LLVMIRGeneration("LLVM IR Generation Time"),
LLVMIRGenerationRefCount(0),
Gen(CreateLLVMCodeGen(Diags, InFile, HeaderSearchOpts, PPOpts, Gen(CreateLLVMCodeGen(Diags, InFile, HeaderSearchOpts, PPOpts,
CodeGenOpts, C, CoverageInfo)) { CodeGenOpts, C, CoverageInfo)) {
llvm::TimePassesIsEnabled = TimePasses; llvm::TimePassesIsEnabled = TimePasses;
@ -112,13 +114,20 @@ namespace clang {
Context->getSourceManager(), Context->getSourceManager(),
"LLVM IR generation of declaration"); "LLVM IR generation of declaration");
if (llvm::TimePassesIsEnabled) // Recurse.
LLVMIRGeneration.startTimer(); if (llvm::TimePassesIsEnabled) {
LLVMIRGenerationRefCount += 1;
if (LLVMIRGenerationRefCount == 1)
LLVMIRGeneration.startTimer();
}
Gen->HandleTopLevelDecl(D); Gen->HandleTopLevelDecl(D);
if (llvm::TimePassesIsEnabled) if (llvm::TimePassesIsEnabled) {
LLVMIRGeneration.stopTimer(); LLVMIRGenerationRefCount -= 1;
if (LLVMIRGenerationRefCount == 0)
LLVMIRGeneration.stopTimer();
}
return true; return true;
} }
@ -139,13 +148,19 @@ namespace clang {
void HandleTranslationUnit(ASTContext &C) override { void HandleTranslationUnit(ASTContext &C) override {
{ {
PrettyStackTraceString CrashInfo("Per-file LLVM IR generation"); PrettyStackTraceString CrashInfo("Per-file LLVM IR generation");
if (llvm::TimePassesIsEnabled) if (llvm::TimePassesIsEnabled) {
LLVMIRGeneration.startTimer(); LLVMIRGenerationRefCount += 1;
if (LLVMIRGenerationRefCount == 1)
LLVMIRGeneration.startTimer();
}
Gen->HandleTranslationUnit(C); Gen->HandleTranslationUnit(C);
if (llvm::TimePassesIsEnabled) if (llvm::TimePassesIsEnabled) {
LLVMIRGeneration.stopTimer(); LLVMIRGenerationRefCount -= 1;
if (LLVMIRGenerationRefCount == 0)
LLVMIRGeneration.stopTimer();
}
} }
// Silently ignore if we weren't initialized for some reason. // Silently ignore if we weren't initialized for some reason.