diff --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt --- a/clang/CMakeLists.txt +++ b/clang/CMakeLists.txt @@ -879,6 +879,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,7 @@ +add_benchmark(CompilerInvocationBench CompilerInvocationBench.cpp) + +target_link_libraries(CompilerInvocationBench + PRIVATE + clangFrontend + LLVMSupport + ) 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,77 @@ +#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; + +// Pointer to '--' in Argv that got replaced by '-round-trip-args'. +static const char **Begin; + +// Pointer to the end of Argv. +static const char **End; + +// Returns a dummy DiagnosticsEngine. +static DiagnosticsEngine &Diags() { + static IntrusiveRefCntPtr Diags = + CompilerInstance::createDiagnostics(new DiagnosticOptions, + new TextDiagnosticBuffer); + return *Diags; +} + +// Parses the command line arguments starting **after** the injected +// '-round-trip-args', resulting in a parse **without** round-trip. +static void BM_CompilerInvocationNoRoundTrip(benchmark::State &State) { + for (auto _ : State) { + CompilerInvocation Invocation; + CompilerInvocation::CreateFromArgs(Invocation, {Begin + 1, End}, Diags()); + } +} + +// Parses the command line arguments starting **at** the injected +// '-round-trip-args', resulting in a parse **with** round-trip. +static void BM_CompilerInvocationDoRoundTrip(benchmark::State &State) { + for (auto _ : State) { + CompilerInvocation Invocation; + CompilerInvocation::CreateFromArgs(Invocation, {Begin, End}, Diags()); + } +} + +BENCHMARK(BM_CompilerInvocationNoRoundTrip); +BENCHMARK(BM_CompilerInvocationDoRoundTrip); + +// USAGE: +// ./CompilerInvocationBench [ Google Benchmark options ... ] \ +// -- [ CompilerInvocation::CreateFromArgs 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; + } + + // Remove all '-round-trip-args' occurrences. + for (int i = DashDashIndex + 1; i < Argc; ++i) + if (StringRef(Argv[i]) == "-round-trip-args") + Argv[i] = ""; + + // Inject '-round-trip-args' in place of '--'. + Argv[DashDashIndex] = "-round-trip-args"; + + Begin = Argv + DashDashIndex; + End = Argv + Argc; + + int BenchmarkArgc = DashDashIndex - Argc; + + ::benchmark::Initialize(&BenchmarkArgc, const_cast(Argv)); + ::benchmark::RunSpecifiedBenchmarks(); +}