brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.0 KiB · 45f3526 Raw
244 lines · cpp
1//===- SandboxIRBench.cpp -------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// These tests measure the performance of some core SandboxIR functions and10// compare them against LLVM IR.11//12//===----------------------------------------------------------------------===//13 14#include "benchmark/benchmark.h"15#include "llvm/AsmParser/Parser.h"16#include "llvm/IR/BasicBlock.h"17#include "llvm/IR/DataLayout.h"18#include "llvm/IR/Function.h"19#include "llvm/IR/Instruction.h"20#include "llvm/IR/Module.h"21#include "llvm/SandboxIR/Function.h"22#include "llvm/SandboxIR/Instruction.h"23#include "llvm/SandboxIR/Module.h"24#include "llvm/Support/SourceMgr.h"25#include <memory>26#include <sstream>27 28using namespace llvm;29 30static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {31  SMDiagnostic Err;32  std::unique_ptr<Module> M = parseAssemblyString(IR, Err, C);33  if (!M)34    Err.print("SandboxIRBench", errs());35  return M;36}37 38enum class IR {39  LLVM,           ///> LLVM IR40  SBoxNoTracking, ///> Sandbox IR with tracking disabled41  SBoxTracking,   ///> Sandbox IR with tracking enabled42};43// Traits to get llvm::BasicBlock/sandboxir::BasicBlock from IR::LLVM/IR::SBox.44template <IR IRTy> struct TypeSelect {};45template <> struct TypeSelect<IR::LLVM> {46  using BasicBlock = llvm::BasicBlock;47};48template <> struct TypeSelect<IR::SBoxNoTracking> {49  using BasicBlock = sandboxir::BasicBlock;50};51template <> struct TypeSelect<IR::SBoxTracking> {52  using BasicBlock = sandboxir::BasicBlock;53};54 55template <IR IRTy>56static typename TypeSelect<IRTy>::BasicBlock *57genIR(std::unique_ptr<llvm::Module> &LLVMM, LLVMContext &LLVMCtx,58      sandboxir::Context &Ctx,59      std::function<std::string(unsigned)> GenerateIRStr,60      unsigned NumInstrs = 0u) {61  std::string IRStr = GenerateIRStr(NumInstrs);62  LLVMM = parseIR(LLVMCtx, IRStr.c_str());63  llvm::Function *LLVMF = &*LLVMM->getFunction("foo");64  llvm::BasicBlock *LLVMBB = &*LLVMF->begin();65 66  sandboxir::Function *F = Ctx.createFunction(LLVMF);67  sandboxir::BasicBlock *BB = &*F->begin();68  // Start tracking if we are testing with tracking enabled.69  if constexpr (IRTy == IR::SBoxTracking)70    Ctx.save();71 72  if constexpr (IRTy == IR::LLVM)73    return LLVMBB;74  else75    return BB;76}77 78template <IR IRTy> static void finalize(sandboxir::Context &Ctx) {79  // Accept changes if we are tracking.80  if constexpr (IRTy == IR::SBoxTracking)81    Ctx.accept();82}83 84static std::string generateBBWalkIR(unsigned Size) {85  std::stringstream SS;86  SS << "define void @foo(i32 %v1, i32 %v2) {\n";87  for (auto Cnt : seq<unsigned>(0, Size))88    SS << "  %add" << Cnt << " = add i32 %v1, %v2\n";89  SS << "ret void";90  SS << "}";91  return SS.str();92}93 94template <IR IRTy> static void SBoxIRCreation(benchmark::State &State) {95  static_assert(IRTy != IR::LLVM, "Expected SBoxTracking or SBoxNoTracking");96  LLVMContext LLVMCtx;97  unsigned NumInstrs = State.range(0);98  std::unique_ptr<llvm::Module> LLVMM;99  std::string IRStr = generateBBWalkIR(NumInstrs);100  LLVMM = parseIR(LLVMCtx, IRStr.c_str());101  llvm::Function *LLVMF = &*LLVMM->getFunction("foo");102 103  for (auto _ : State) {104    State.PauseTiming();105    sandboxir::Context Ctx(LLVMCtx);106    if constexpr (IRTy == IR::SBoxTracking)107      Ctx.save();108    State.ResumeTiming();109 110    sandboxir::Function *F = Ctx.createFunction(LLVMF);111    benchmark::DoNotOptimize(F);112    State.PauseTiming();113    if constexpr (IRTy == IR::SBoxTracking)114      Ctx.accept();115    State.ResumeTiming();116  }117}118 119template <IR IRTy> static void BBWalk(benchmark::State &State) {120  LLVMContext LLVMCtx;121  sandboxir::Context Ctx(LLVMCtx);122  unsigned NumInstrs = State.range(0);123  std::unique_ptr<llvm::Module> LLVMM;124  auto *BB = genIR<IRTy>(LLVMM, LLVMCtx, Ctx, generateBBWalkIR, NumInstrs);125  for (auto _ : State) {126    // Walk LLVM Instructions.127    for (auto &I : *BB)128      benchmark::DoNotOptimize(I);129  }130}131 132static std::string generateGetTypeIR(unsigned Size) {133  return R"IR(134define void @foo(i32 %v1, i32 %v2) {135  %add = add i32 %v1, %v2136  ret void137}138)IR";139}140 141template <IR IRTy> static void GetType(benchmark::State &State) {142  LLVMContext LLVMCtx;143  sandboxir::Context Ctx(LLVMCtx);144  std::unique_ptr<llvm::Module> LLVMM;145  auto *BB = genIR<IRTy>(LLVMM, LLVMCtx, Ctx, generateGetTypeIR);146  auto *I = &*BB->begin();147  for (auto _ : State)148    benchmark::DoNotOptimize(I->getType());149}150 151static std::string generateRAUWIR(unsigned Size) {152  std::stringstream SS;153  SS << "define void @foo(i32 %v1, i32 %v2) {\n";154  SS << "  %def1 = add i32 %v1, %v2\n";155  SS << "  %def2 = add i32 %v1, %v2\n";156  for (auto Cnt : seq<unsigned>(0, Size))157    SS << "  %add" << Cnt << " = add i32 %def1, %def1\n";158  SS << "ret void";159  SS << "}";160  return SS.str();161}162 163template <IR IRTy> static void RAUW(benchmark::State &State) {164  LLVMContext LLVMCtx;165  sandboxir::Context Ctx(LLVMCtx);166  std::unique_ptr<llvm::Module> LLVMM;167  unsigned NumInstrs = State.range(0);168  auto *BB = genIR<IRTy>(LLVMM, LLVMCtx, Ctx, generateRAUWIR, NumInstrs);169  auto It = BB->begin();170  auto *Def1 = &*It++;171  auto *Def2 = &*It++;172  for (auto _ : State) {173    Def1->replaceAllUsesWith(Def2);174    Def2->replaceAllUsesWith(Def1);175  }176  finalize<IRTy>(Ctx);177}178 179static std::string generateRUOWIR(unsigned NumOperands) {180  std::stringstream SS;181  auto GenOps = [&SS, NumOperands]() {182    for (auto Cnt : seq<unsigned>(0, NumOperands)) {183      SS << "i8 %arg" << Cnt;184      bool IsLast = Cnt + 1 == NumOperands;185      if (!IsLast)186        SS << ", ";187    }188  };189 190  SS << "define void @foo(";191  GenOps();192  SS << ") {\n";193 194  SS << "   call void @foo(";195  GenOps();196  SS << ")\n";197  SS << "ret void";198  SS << "}";199  return SS.str();200}201 202template <IR IRTy> static void RUOW(benchmark::State &State) {203  LLVMContext LLVMCtx;204  sandboxir::Context Ctx(LLVMCtx);205  std::unique_ptr<llvm::Module> LLVMM;206  unsigned NumOperands = State.range(0);207  auto *BB = genIR<IRTy>(LLVMM, LLVMCtx, Ctx, generateRUOWIR, NumOperands);208 209  auto It = BB->begin();210  auto *F = BB->getParent();211  auto *Arg0 = F->getArg(0);212  auto *Arg1 = F->getArg(1);213  auto *Call = &*It++;214  for (auto _ : State)215    Call->replaceUsesOfWith(Arg0, Arg1);216  finalize<IRTy>(Ctx);217}218 219// Measure the time it takes to create Sandbox IR without/with tracking.220BENCHMARK(SBoxIRCreation<IR::SBoxNoTracking>)221    ->Args({10})222    ->Args({100})223    ->Args({1000});224BENCHMARK(SBoxIRCreation<IR::SBoxTracking>)225    ->Args({10})226    ->Args({100})227    ->Args({1000});228 229BENCHMARK(GetType<IR::LLVM>);230BENCHMARK(GetType<IR::SBoxNoTracking>);231 232BENCHMARK(BBWalk<IR::LLVM>)->Args({1024});233BENCHMARK(BBWalk<IR::SBoxTracking>)->Args({1024});234 235BENCHMARK(RAUW<IR::LLVM>)->Args({512});236BENCHMARK(RAUW<IR::SBoxNoTracking>)->Args({512});237BENCHMARK(RAUW<IR::SBoxTracking>)->Args({512});238 239BENCHMARK(RUOW<IR::LLVM>)->Args({4096});240BENCHMARK(RUOW<IR::SBoxNoTracking>)->Args({4096});241BENCHMARK(RUOW<IR::SBoxTracking>)->Args({4096});242 243BENCHMARK_MAIN();244