From 5e25291b3c50873dbd0e2b3939b113bcff691460 Mon Sep 17 00:00:00 2001 From: vporpo Date: Thu, 5 Sep 2024 10:35:02 -0700 Subject: [PATCH] [SandboxIR][Bench] Initial patch for performance tracking (#107296) This patch adds a new benchmark suite for SandboxIR. It measures the performance of some of the most commonly used API functions and compares it against LLVM IR. --- llvm/benchmarks/CMakeLists.txt | 4 + llvm/benchmarks/SandboxIRBench.cpp | 115 +++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+) create mode 100644 llvm/benchmarks/SandboxIRBench.cpp diff --git a/llvm/benchmarks/CMakeLists.txt b/llvm/benchmarks/CMakeLists.txt index aa0cb7777334..1078efa55f49 100644 --- a/llvm/benchmarks/CMakeLists.txt +++ b/llvm/benchmarks/CMakeLists.txt @@ -1,5 +1,7 @@ set(LLVM_LINK_COMPONENTS + AsmParser Core + SandboxIR Support) add_benchmark(DummyYAML DummyYAML.cpp PARTIAL_SOURCES_INTENDED) @@ -7,3 +9,5 @@ add_benchmark(xxhash xxhash.cpp PARTIAL_SOURCES_INTENDED) add_benchmark(GetIntrinsicForClangBuiltin GetIntrinsicForClangBuiltin.cpp PARTIAL_SOURCES_INTENDED) add_benchmark(FormatVariadicBM FormatVariadicBM.cpp PARTIAL_SOURCES_INTENDED) add_benchmark(GetIntrinsicInfoTableEntriesBM GetIntrinsicInfoTableEntriesBM.cpp PARTIAL_SOURCES_INTENDED) +add_benchmark(SandboxIRBench SandboxIRBench.cpp PARTIAL_SOURCES_INTENDED) + diff --git a/llvm/benchmarks/SandboxIRBench.cpp b/llvm/benchmarks/SandboxIRBench.cpp new file mode 100644 index 000000000000..633de6db1f5e --- /dev/null +++ b/llvm/benchmarks/SandboxIRBench.cpp @@ -0,0 +1,115 @@ +//===- SandboxIRBench.cpp -------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// These tests measure the performance of some core SandboxIR functions and +// compare them against LLVM IR. +// +//===----------------------------------------------------------------------===// + +#include "benchmark/benchmark.h" +#include "llvm/AsmParser/Parser.h" +#include "llvm/IR/BasicBlock.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/Instruction.h" +#include "llvm/IR/Module.h" +#include "llvm/SandboxIR/SandboxIR.h" +#include "llvm/Support/SourceMgr.h" +#include + +using namespace llvm; + +static std::unique_ptr parseIR(LLVMContext &C, const char *IR) { + SMDiagnostic Err; + std::unique_ptr M = parseAssemblyString(IR, Err, C); + if (!M) + Err.print("SandboxIRBench", errs()); + return M; +} + +enum class IR { + LLVM, + SBox, +}; +// Traits to get llvm::BasicBlock/sandboxir::BasicBlock from IR::LLVM/IR::SBox. +template struct TypeSelect {}; +template <> struct TypeSelect { + using BasicBlock = llvm::BasicBlock; +}; +template <> struct TypeSelect { + using BasicBlock = sandboxir::BasicBlock; +}; + +template +static typename TypeSelect::BasicBlock * +genIR(std::unique_ptr &LLVMM, LLVMContext &LLVMCtx, + sandboxir::Context &Ctx, + std::function GenerateIRStr, + unsigned NumInstrs = 0u) { + std::string IRStr = GenerateIRStr(NumInstrs); + LLVMM = parseIR(LLVMCtx, IRStr.c_str()); + llvm::Function *LLVMF = &*LLVMM->getFunction("foo"); + llvm::BasicBlock *LLVMBB = &*LLVMF->begin(); + + sandboxir::Function *F = Ctx.createFunction(LLVMF); + sandboxir::BasicBlock *BB = &*F->begin(); + if constexpr (IRTy == IR::LLVM) + return LLVMBB; + else + return BB; +} + +static std::string generateBBWalkIR(unsigned Size) { + std::stringstream SS; + SS << "define void @foo(i32 %v1, i32 %v2) {\n"; + for (auto Cnt : seq(0, Size)) + SS << " %add" << Cnt << " = add i32 %v1, %v2\n"; + SS << "ret void"; + SS << "}"; + return SS.str(); +} + +template static void BBWalk(benchmark::State &State) { + LLVMContext LLVMCtx; + sandboxir::Context Ctx(LLVMCtx); + unsigned NumInstrs = State.range(0); + std::unique_ptr LLVMM; + auto *BB = genIR(LLVMM, LLVMCtx, Ctx, generateBBWalkIR, NumInstrs); + for (auto _ : State) { + // Walk LLVM Instructions. + for (auto &I : *BB) + benchmark::DoNotOptimize(I); + } +} + +static std::string generateGetTypeIR(unsigned Size) { + return R"IR( +define void @foo(i32 %v1, i32 %v2) { + %add = add i32 %v1, %v2 + ret void +} +)IR"; +} + +template static void GetType(benchmark::State &State) { + LLVMContext LLVMCtx; + sandboxir::Context Ctx(LLVMCtx); + std::unique_ptr LLVMM; + auto *BB = genIR(LLVMM, LLVMCtx, Ctx, generateGetTypeIR); + auto *I = &*BB->begin(); + for (auto _ : State) + benchmark::DoNotOptimize(I->getType()); +} + +BENCHMARK(GetType); +BENCHMARK(GetType); + +BENCHMARK(BBWalk)->Args({1024}); +BENCHMARK(BBWalk)->Args({1024}); + +BENCHMARK_MAIN();