summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Frontend/Utils.h6
-rw-r--r--clang/lib/CodeGen/BackendUtil.cpp4
-rw-r--r--clang/lib/CodeGen/CodeGenAction.cpp18
-rw-r--r--clang/lib/Frontend/CMakeLists.txt1
-rw-r--r--clang/lib/Frontend/FrontendTiming.cpp20
-rw-r--r--clang/test/Frontend/ftime-report-template-decl.cpp159
6 files changed, 197 insertions, 11 deletions
diff --git a/clang/include/clang/Frontend/Utils.h b/clang/include/clang/Frontend/Utils.h
index 47a5e9118f2..67912a8dfcd 100644
--- a/clang/include/clang/Frontend/Utils.h
+++ b/clang/include/clang/Frontend/Utils.h
@@ -234,6 +234,12 @@ template <typename T> void BuryPointer(std::unique_ptr<T> Ptr) {
BuryPointer(Ptr.release());
}
+// Frontend timing utils
+
+/// If the user specifies the -ftime-report argument on an Clang command line
+/// then the value of this boolean will be true, otherwise false.
+extern bool FrontendTimesIsEnabled;
+
} // namespace clang
#endif // LLVM_CLANG_FRONTEND_UTILS_H
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index cf0251b46e4..0b1c30d4bb1 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -728,7 +728,7 @@ bool EmitAssemblyHelper::AddEmitPasses(legacy::PassManager &CodeGenPasses,
void EmitAssemblyHelper::EmitAssembly(BackendAction Action,
std::unique_ptr<raw_pwrite_stream> OS) {
- TimeRegion Region(llvm::TimePassesIsEnabled ? &CodeGenerationTime : nullptr);
+ TimeRegion Region(FrontendTimesIsEnabled ? &CodeGenerationTime : nullptr);
setCommandLineOpts(CodeGenOpts);
@@ -858,7 +858,7 @@ static PassBuilder::OptimizationLevel mapToLevel(const CodeGenOptions &Opts) {
/// `EmitAssembly` at some point in the future when the default switches.
void EmitAssemblyHelper::EmitAssemblyWithNewPassManager(
BackendAction Action, std::unique_ptr<raw_pwrite_stream> OS) {
- TimeRegion Region(llvm::TimePassesIsEnabled ? &CodeGenerationTime : nullptr);
+ TimeRegion Region(FrontendTimesIsEnabled ? &CodeGenerationTime : nullptr);
setCommandLineOpts(CodeGenOpts);
// The new pass manager always makes a target machine available to passes
diff --git a/clang/lib/CodeGen/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp
index ac2548e6a52..93e95a2dd88 100644
--- a/clang/lib/CodeGen/CodeGenAction.cpp
+++ b/clang/lib/CodeGen/CodeGenAction.cpp
@@ -126,7 +126,7 @@ namespace clang {
Gen(CreateLLVMCodeGen(Diags, InFile, HeaderSearchOpts, PPOpts,
CodeGenOpts, C, CoverageInfo)),
LinkModules(std::move(LinkModules)) {
- llvm::TimePassesIsEnabled = TimePasses;
+ FrontendTimesIsEnabled = TimePasses;
}
llvm::Module *getModule() const { return Gen->GetModule(); }
std::unique_ptr<llvm::Module> takeModule() {
@@ -144,12 +144,12 @@ namespace clang {
Context = &Ctx;
- if (llvm::TimePassesIsEnabled)
+ if (FrontendTimesIsEnabled)
LLVMIRGeneration.startTimer();
Gen->Initialize(Ctx);
- if (llvm::TimePassesIsEnabled)
+ if (FrontendTimesIsEnabled)
LLVMIRGeneration.stopTimer();
}
@@ -159,7 +159,7 @@ namespace clang {
"LLVM IR generation of declaration");
// Recurse.
- if (llvm::TimePassesIsEnabled) {
+ if (FrontendTimesIsEnabled) {
LLVMIRGenerationRefCount += 1;
if (LLVMIRGenerationRefCount == 1)
LLVMIRGeneration.startTimer();
@@ -167,7 +167,7 @@ namespace clang {
Gen->HandleTopLevelDecl(D);
- if (llvm::TimePassesIsEnabled) {
+ if (FrontendTimesIsEnabled) {
LLVMIRGenerationRefCount -= 1;
if (LLVMIRGenerationRefCount == 0)
LLVMIRGeneration.stopTimer();
@@ -180,12 +180,12 @@ namespace clang {
PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
Context->getSourceManager(),
"LLVM IR generation of inline function");
- if (llvm::TimePassesIsEnabled)
+ if (FrontendTimesIsEnabled)
LLVMIRGeneration.startTimer();
Gen->HandleInlineFunctionDefinition(D);
- if (llvm::TimePassesIsEnabled)
+ if (FrontendTimesIsEnabled)
LLVMIRGeneration.stopTimer();
}
@@ -227,7 +227,7 @@ namespace clang {
void HandleTranslationUnit(ASTContext &C) override {
{
PrettyStackTraceString CrashInfo("Per-file LLVM IR generation");
- if (llvm::TimePassesIsEnabled) {
+ if (FrontendTimesIsEnabled) {
LLVMIRGenerationRefCount += 1;
if (LLVMIRGenerationRefCount == 1)
LLVMIRGeneration.startTimer();
@@ -235,7 +235,7 @@ namespace clang {
Gen->HandleTranslationUnit(C);
- if (llvm::TimePassesIsEnabled) {
+ if (FrontendTimesIsEnabled) {
LLVMIRGenerationRefCount -= 1;
if (LLVMIRGenerationRefCount == 0)
LLVMIRGeneration.stopTimer();
diff --git a/clang/lib/Frontend/CMakeLists.txt b/clang/lib/Frontend/CMakeLists.txt
index ba3bd7d28c7..6161b46a9dc 100644
--- a/clang/lib/Frontend/CMakeLists.txt
+++ b/clang/lib/Frontend/CMakeLists.txt
@@ -29,6 +29,7 @@ add_clang_library(clangFrontend
FrontendAction.cpp
FrontendActions.cpp
FrontendOptions.cpp
+ FrontendTiming.cpp
HeaderIncludeGen.cpp
InitHeaderSearch.cpp
InitPreprocessor.cpp
diff --git a/clang/lib/Frontend/FrontendTiming.cpp b/clang/lib/Frontend/FrontendTiming.cpp
new file mode 100644
index 00000000000..9ea7347e779
--- /dev/null
+++ b/clang/lib/Frontend/FrontendTiming.cpp
@@ -0,0 +1,20 @@
+//===- FronendTiming.cpp - Implements Frontend timing utils --------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file keps implementation of frontend timing utils.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/Utils.h"
+
+namespace clang {
+
+bool FrontendTimesIsEnabled = false;
+
+}
diff --git a/clang/test/Frontend/ftime-report-template-decl.cpp b/clang/test/Frontend/ftime-report-template-decl.cpp
new file mode 100644
index 00000000000..c4086281d66
--- /dev/null
+++ b/clang/test/Frontend/ftime-report-template-decl.cpp
@@ -0,0 +1,159 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -ftime-report 2>&1 | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -o - -fdelayed-template-parsing -DDELAYED_TEMPLATE_PARSING -ftime-report 2>&1 | FileCheck %s
+
+// Template function declarations
+template <typename T>
+void foo();
+template <typename T, typename U>
+void foo();
+
+// Template function definitions.
+template <typename T>
+void foo() {}
+
+// Template class (forward) declarations
+template <typename T>
+struct A;
+template <typename T, typename U>
+struct b;
+template <typename>
+struct C;
+template <typename, typename>
+struct D;
+
+// Forward declarations with default parameters?
+template <typename T = int>
+class X1;
+template <typename = int>
+class X2;
+
+// Forward declarations w/template template parameters
+template <template <typename> class T>
+class TTP1;
+template <template <typename> class>
+class TTP2;
+template <template <typename X, typename Y> class T>
+class TTP5;
+
+// Forward declarations with non-type params
+template <int>
+class NTP0;
+template <int N>
+class NTP1;
+template <int N = 5>
+class NTP2;
+template <int = 10>
+class NTP3;
+template <unsigned int N = 12u>
+class NTP4;
+template <unsigned int = 12u>
+class NTP5;
+template <unsigned = 15u>
+class NTP6;
+template <typename T, T Obj>
+class NTP7;
+
+// Template class declarations
+template <typename T>
+struct A {};
+template <typename T, typename U>
+struct B {};
+
+namespace PR6184 {
+namespace N {
+template <typename T>
+void bar(typename T::x);
+}
+
+template <typename T>
+void N::bar(typename T::x) {}
+}
+
+// This PR occurred only in template parsing mode.
+namespace PR17637 {
+template <int>
+struct L {
+ template <typename T>
+ struct O {
+ template <typename U>
+ static void Fun(U);
+ };
+};
+
+template <int k>
+template <typename T>
+template <typename U>
+void L<k>::O<T>::Fun(U) {}
+
+void Instantiate() { L<0>::O<int>::Fun(0); }
+}
+
+namespace explicit_partial_specializations {
+typedef char (&oneT)[1];
+typedef char (&twoT)[2];
+typedef char (&threeT)[3];
+typedef char (&fourT)[4];
+typedef char (&fiveT)[5];
+typedef char (&sixT)[6];
+
+char one[1];
+char two[2];
+char three[3];
+char four[4];
+char five[5];
+char six[6];
+
+template <bool b>
+struct bool_ { typedef int type; };
+template <>
+struct bool_<false> {};
+
+#define XCAT(x, y) x##y
+#define CAT(x, y) XCAT(x, y)
+#define sassert(_b_) bool_<(_b_)>::type CAT(var, __LINE__);
+
+template <int>
+struct L {
+ template <typename T>
+ struct O {
+ template <typename U>
+ static oneT Fun(U);
+ };
+};
+template <int k>
+template <typename T>
+template <typename U>
+oneT L<k>::O<T>::Fun(U) { return one; }
+
+template <>
+template <>
+template <typename U>
+oneT L<0>::O<char>::Fun(U) { return one; }
+
+void Instantiate() {
+ sassert(sizeof(L<0>::O<int>::Fun(0)) == sizeof(one));
+ sassert(sizeof(L<0>::O<char>::Fun(0)) == sizeof(one));
+}
+}
+
+template <class>
+struct Foo {
+ template <class _Other>
+ using rebind_alloc = _Other;
+};
+template <class _Alloc>
+struct _Wrap_alloc {
+ template <class _Other>
+ using rebind_alloc = typename Foo<_Alloc>::template rebind_alloc<_Other>;
+ template <class>
+ using rebind = _Wrap_alloc;
+};
+_Wrap_alloc<int>::rebind<int> w;
+
+// CHECK: Miscellaneous Ungrouped Timers
+// CHECK: LLVM IR Generation Time
+// CHECK: Code Generation Time
+// CHECK: Total
+// CHECK: Clang front-end time report
+// CHECK: Clang front-end timer
+// CHECK: Total
OpenPOWER on IntegriCloud