144 lines · c
1//===-- Assembler.h ---------------------------------------------*- C++ -*-===//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/// \file10/// Defines classes to assemble functions composed of a single basic block of11/// MCInsts.12///13//===----------------------------------------------------------------------===//14 15#ifndef LLVM_TOOLS_LLVM_EXEGESIS_ASSEMBLER_H16#define LLVM_TOOLS_LLVM_EXEGESIS_ASSEMBLER_H17 18#include <memory>19 20#include "BenchmarkCode.h"21#include "Error.h"22#include "llvm/ADT/ArrayRef.h"23#include "llvm/ADT/BitVector.h"24#include "llvm/CodeGen/MachineFunction.h"25#include "llvm/CodeGen/MachineModuleInfo.h"26#include "llvm/ExecutionEngine/Orc/LLJIT.h"27#include "llvm/IR/LLVMContext.h"28#include "llvm/IR/Module.h"29#include "llvm/MC/MCInst.h"30#include "llvm/Object/Binary.h"31#include "llvm/Object/ObjectFile.h"32#include "llvm/Support/raw_ostream.h"33#include "llvm/Target/TargetMachine.h"34 35namespace llvm {36namespace exegesis {37 38class ExegesisTarget;39 40// Gather the set of reserved registers (depends on function's calling41// convention and target machine).42BitVector getFunctionReservedRegs(const TargetMachine &TM);43 44// Helper to fill in a basic block.45class BasicBlockFiller {46public:47 BasicBlockFiller(MachineFunction &MF, MachineBasicBlock *MBB,48 const MCInstrInfo *MCII);49 50 void addInstruction(const MCInst &Inst, const DebugLoc &DL = DebugLoc());51 void addInstructions(ArrayRef<MCInst> Insts, const DebugLoc &DL = DebugLoc());52 53 void addReturn(const ExegesisTarget &ET, bool SubprocessCleanup,54 const DebugLoc &DL = DebugLoc());55 56 MachineFunction &MF;57 MachineBasicBlock *const MBB;58 const MCInstrInfo *const MCII;59};60 61// Helper to fill in a function.62class FunctionFiller {63public:64 FunctionFiller(MachineFunction &MF, std::vector<MCRegister> RegistersSetUp);65 66 // Adds a basic block to the function.67 BasicBlockFiller addBasicBlock();68 69 // Returns the function entry point.70 BasicBlockFiller getEntry() { return Entry; }71 72 MachineFunction &MF;73 const MCInstrInfo *const MCII;74 75 // Returns the set of registers in the snippet setup code.76 ArrayRef<MCRegister> getRegistersSetUp() const;77 78private:79 BasicBlockFiller Entry;80 // The set of registers that are set up in the basic block.81 std::vector<MCRegister> RegistersSetUp;82};83 84// A callback that fills a function.85using FillFunction = std::function<void(FunctionFiller &)>;86 87// Creates a temporary `void foo(char*)` function containing the provided88// Instructions. Runs a set of llvm Passes to provide correct prologue and89// epilogue. Once the MachineFunction is ready, it is assembled for TM to90// AsmStream, the temporary function is eventually discarded.91Error assembleToStream(const ExegesisTarget &ET,92 std::unique_ptr<TargetMachine> TM,93 ArrayRef<MCRegister> LiveIns, const FillFunction &Fill,94 raw_pwrite_stream &AsmStreamm, const BenchmarkKey &Key,95 bool GenerateMemoryInstructions);96 97// Creates an ObjectFile in the format understood by the host.98// Note: the resulting object keeps a copy of Buffer so it can be discarded once99// this function returns.100object::OwningBinary<object::ObjectFile> getObjectFromBuffer(StringRef Buffer);101 102// Loads the content of Filename as on ObjectFile and returns it.103object::OwningBinary<object::ObjectFile> getObjectFromFile(StringRef Filename);104 105// Consumes an ObjectFile containing a `void foo(char*)` function and make it106// executable.107class ExecutableFunction {108public:109 static Expected<ExecutableFunction>110 create(std::unique_ptr<TargetMachine> TM,111 object::OwningBinary<object::ObjectFile> &&ObjectFileHolder);112 113 // Retrieves the function as an array of bytes.114 StringRef getFunctionBytes() const { return FunctionBytes; }115 116 // Executes the function.117 void operator()(char *Memory) const {118 ((void (*)(char *))(uintptr_t)FunctionBytes.data())(Memory);119 }120 121 StringRef FunctionBytes;122 123private:124 ExecutableFunction(std::unique_ptr<LLVMContext> Ctx,125 std::unique_ptr<orc::LLJIT> EJIT, StringRef FunctionBytes);126 127 std::unique_ptr<LLVMContext> Context;128 std::unique_ptr<orc::LLJIT> ExecJIT;129};130 131// Copies benchmark function's bytes from benchmark object.132Error getBenchmarkFunctionBytes(const StringRef InputData,133 std::vector<uint8_t> &Bytes);134 135// Creates a void(int8*) MachineFunction.136MachineFunction &createVoidVoidPtrMachineFunction(StringRef FunctionID,137 Module *Module,138 MachineModuleInfo *MMI);139 140} // namespace exegesis141} // namespace llvm142 143#endif // LLVM_TOOLS_LLVM_EXEGESIS_ASSEMBLER_H144