blob: c646ba6290daffe0886fffc24bf99c04b98e0799 [file] [log] [blame] [edit]
//===- 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 <memory>
#include <sstream>
using namespace llvm;
static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {
SMDiagnostic Err;
std::unique_ptr<Module> 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 <IR IRTy> struct TypeSelect {};
template <> struct TypeSelect<IR::LLVM> {
using BasicBlock = llvm::BasicBlock;
};
template <> struct TypeSelect<IR::SBox> {
using BasicBlock = sandboxir::BasicBlock;
};
template <IR IRTy>
static typename TypeSelect<IRTy>::BasicBlock *
genIR(std::unique_ptr<llvm::Module> &LLVMM, LLVMContext &LLVMCtx,
sandboxir::Context &Ctx,
std::function<std::string(unsigned)> 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<unsigned>(0, Size))
SS << " %add" << Cnt << " = add i32 %v1, %v2\n";
SS << "ret void";
SS << "}";
return SS.str();
}
template <IR IRTy> static void BBWalk(benchmark::State &State) {
LLVMContext LLVMCtx;
sandboxir::Context Ctx(LLVMCtx);
unsigned NumInstrs = State.range(0);
std::unique_ptr<llvm::Module> LLVMM;
auto *BB = genIR<IRTy>(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 <IR IRTy> static void GetType(benchmark::State &State) {
LLVMContext LLVMCtx;
sandboxir::Context Ctx(LLVMCtx);
std::unique_ptr<llvm::Module> LLVMM;
auto *BB = genIR<IRTy>(LLVMM, LLVMCtx, Ctx, generateGetTypeIR);
auto *I = &*BB->begin();
for (auto _ : State)
benchmark::DoNotOptimize(I->getType());
}
static std::string generateRAUWIR(unsigned Size) {
std::stringstream SS;
SS << "define void @foo(i32 %v1, i32 %v2) {\n";
SS << " %def1 = add i32 %v1, %v2\n";
SS << " %def2 = add i32 %v1, %v2\n";
for (auto Cnt : seq<unsigned>(0, Size))
SS << " %add" << Cnt << " = add i32 %def1, %def1\n";
SS << "ret void";
SS << "}";
return SS.str();
}
template <IR IRTy> static void RAUW(benchmark::State &State) {
LLVMContext LLVMCtx;
sandboxir::Context Ctx(LLVMCtx);
std::unique_ptr<llvm::Module> LLVMM;
unsigned NumInstrs = State.range(0);
auto *BB = genIR<IRTy>(LLVMM, LLVMCtx, Ctx, generateRAUWIR, NumInstrs);
auto It = BB->begin();
auto *Def1 = &*It++;
auto *Def2 = &*It++;
for (auto _ : State) {
Def1->replaceAllUsesWith(Def2);
Def2->replaceAllUsesWith(Def1);
}
}
BENCHMARK(GetType<IR::LLVM>);
BENCHMARK(GetType<IR::SBox>);
BENCHMARK(BBWalk<IR::LLVM>)->Args({1024});
BENCHMARK(BBWalk<IR::SBox>)->Args({1024});
BENCHMARK(RAUW<IR::LLVM>)->Args({512});
BENCHMARK(RAUW<IR::SBox>)->Args({512});
BENCHMARK_MAIN();