diff --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt --- a/clang/CMakeLists.txt +++ b/clang/CMakeLists.txt @@ -892,6 +892,10 @@ process_llvm_pass_plugins() endif() +if(LLVM_INCLUDE_BENCHMARKS) + add_subdirectory(benchmarks) +endif() + configure_file( ${CLANG_SOURCE_DIR}/include/clang/Config/config.h.cmake ${CLANG_BINARY_DIR}/include/clang/Config/config.h) diff --git a/clang/benchmarks/CMakeLists.txt b/clang/benchmarks/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/clang/benchmarks/CMakeLists.txt @@ -0,0 +1,41 @@ +add_benchmark(CompilerInvocationBench + CompilerInvocationBench.cpp + ${CLANG_SOURCE_DIR}/tools/driver/cc1_main.cpp) + +foreach(llvm_target ${LLVM_TARGETS_TO_BUILD}) + set(target_codegen "LLVM${llvm_target}CodeGen") + if(TARGET "${target_codegen}") + list(APPEND llvm_target_libraries "${target_codegen}") + endif() + + set(target_asm_parser "LLVM${llvm_target}AsmParser") + if(TARGET "${target_asm_parser}") + list(APPEND llvm_target_libraries "${target_asm_parser}") + endif() +endforeach() + +target_link_libraries(CompilerInvocationBench PRIVATE + clangBasic + clangCodeGen + clangDriver + clangFrontend + clangFrontendTool + clangSerialization + + ${llvm_target_libraries} + LLVMAnalysis + LLVMCodeGen + LLVMCore +# LLVMIPO + LLVMAggressiveInstCombine + LLVMInstCombine + LLVMInstrumentation + LLVMMC + LLVMMCParser + LLVMObjCARCOpts + LLVMOption + LLVMScalarOpts + LLVMSupport + LLVMTarget + LLVMTransformUtils + LLVMVectorize) diff --git a/clang/benchmarks/CompilerInvocationBench.cpp b/clang/benchmarks/CompilerInvocationBench.cpp new file mode 100644 --- /dev/null +++ b/clang/benchmarks/CompilerInvocationBench.cpp @@ -0,0 +1,101 @@ +//===-- CompilerInvocationBench.cpp - Argument parsing benchmark ----------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/CompilerInvocation.h" +#include "clang/Frontend/TextDiagnosticBuffer.h" + +#include "benchmark/benchmark.h" + +using namespace llvm; +using namespace clang; + +int cc1_main(ArrayRef Argv, const char *Argv0, void *MainAddr); + +// After '--' in Argv. +static const char **Begin; + +// The end of Argv. +static const char **End; + +static const char *RoundTrip = "-round-trip-args"; +static const char *NoRoundTrip = "-no-round-trip-args"; + +static void BM_CompilerInvocationCreate(benchmark::State &State) { + SmallVector Args{Begin, End}; + Args.emplace_back(State.range(0) ? RoundTrip : NoRoundTrip); + + auto Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions, + new TextDiagnosticBuffer); + + for (auto _ : State) { + CompilerInvocation Invocation; + CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); + benchmark::DoNotOptimize(Invocation); + } + + assert(Diags->getNumErrors() == 0); + assert(Diags->getNumWarnings() == 0); +} + +static void BM_Preprocess(benchmark::State &State) { + SmallVector Args{Begin, End}; + Args.emplace_back(State.range(0) ? RoundTrip : NoRoundTrip); + Args.emplace_back("-E"); + + for (auto _ : State) { + int ExitCode = cc1_main(Args, "clang", nullptr); + benchmark::DoNotOptimize(ExitCode); + } +} + +static void BM_Compile(benchmark::State &State) { + SmallVector Args{Begin, End}; + Args.emplace_back(State.range(0) ? RoundTrip : NoRoundTrip); + Args.emplace_back("-emit-obj"); + + for (auto _ : State) { + int ExitCode = cc1_main(Args, "clang", nullptr); + benchmark::DoNotOptimize(ExitCode); + } +} + +BENCHMARK(BM_CompilerInvocationCreate)->Arg(false); +BENCHMARK(BM_CompilerInvocationCreate)->Arg(true); + +BENCHMARK(BM_Preprocess)->Arg(false); +BENCHMARK(BM_Preprocess)->Arg(true); + +BENCHMARK(BM_Compile)->Arg(false); +BENCHMARK(BM_Compile)->Arg(true); + +// USAGE: +// CompilerInvocationBench [ Google Benchmark arguments ... ] \ +// -- [ Clang CC1 arguments ... ] +int main(int Argc, const char *Argv[]) { + // Find the '--' argument. + int DashDashIndex = 0; + for (int i = 0; i < Argc; ++i) + if (StringRef(Argv[i]) == "--") + DashDashIndex = i; + + if (DashDashIndex == 0) { + llvm::errs() << "USAGE:\n" + << " " << Argv[0] << " [ Google Benchmark options ... ] -- " + << "[ CompilerInvocation::CreateFromArgs arguments ... ]\n"; + return 1; + } + + Begin = Argv + DashDashIndex + 1; + End = Argv + Argc; + + int BenchmarkArgc = DashDashIndex - Argc; + + benchmark::Initialize(&BenchmarkArgc, const_cast(Argv)); + benchmark::RunSpecifiedBenchmarks(); +}