//===-- Assembler.h ---------------------------------------------*- C++ -*-===// // // 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 // //===----------------------------------------------------------------------===// /// /// \file /// Defines classes to assemble functions composed of a single basic block of /// MCInsts. /// //===----------------------------------------------------------------------===// #ifndef LLVM_TOOLS_LLVM_EXEGESIS_ASSEMBLER_H #define LLVM_TOOLS_LLVM_EXEGESIS_ASSEMBLER_H #include #include "BenchmarkCode.h" #include "Error.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/BitVector.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/ExecutionEngine/ExecutionEngine.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/MC/MCInst.h" #include "llvm/Object/Binary.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetMachine.h" namespace llvm { namespace exegesis { class ExegesisTarget; // Gather the set of reserved registers (depends on function's calling // convention and target machine). BitVector getFunctionReservedRegs(const TargetMachine &TM); // Helper to fill in a basic block. class BasicBlockFiller { public: BasicBlockFiller(MachineFunction &MF, MachineBasicBlock *MBB, const MCInstrInfo *MCII); void addInstruction(const MCInst &Inst, const DebugLoc &DL = DebugLoc()); void addInstructions(ArrayRef Insts, const DebugLoc &DL = DebugLoc()); void addReturn(const DebugLoc &DL = DebugLoc()); MachineFunction &MF; MachineBasicBlock *const MBB; const MCInstrInfo *const MCII; }; // Helper to fill in a function. class FunctionFiller { public: FunctionFiller(MachineFunction &MF, std::vector RegistersSetUp); // Adds a basic block to the function. BasicBlockFiller addBasicBlock(); // Returns the function entry point. BasicBlockFiller getEntry() { return Entry; } MachineFunction &MF; const MCInstrInfo *const MCII; // Returns the set of registers in the snippet setup code. ArrayRef getRegistersSetUp() const; private: BasicBlockFiller Entry; // The set of registers that are set up in the basic block. std::vector RegistersSetUp; }; // A callback that fills a function. using FillFunction = std::function; // Creates a temporary `void foo(char*)` function containing the provided // Instructions. Runs a set of llvm Passes to provide correct prologue and // epilogue. Once the MachineFunction is ready, it is assembled for TM to // AsmStream, the temporary function is eventually discarded. Error assembleToStream(const ExegesisTarget &ET, std::unique_ptr TM, ArrayRef LiveIns, ArrayRef RegisterInitialValues, const FillFunction &Fill, raw_pwrite_stream &AsmStream); // Creates an ObjectFile in the format understood by the host. // Note: the resulting object keeps a copy of Buffer so it can be discarded once // this function returns. object::OwningBinary getObjectFromBuffer(StringRef Buffer); // Loads the content of Filename as on ObjectFile and returns it. object::OwningBinary getObjectFromFile(StringRef Filename); // Consumes an ObjectFile containing a `void foo(char*)` function and make it // executable. struct ExecutableFunction { explicit ExecutableFunction( std::unique_ptr TM, object::OwningBinary &&ObjectFileHolder); // Retrieves the function as an array of bytes. StringRef getFunctionBytes() const { return FunctionBytes; } // Executes the function. void operator()(char *Memory) const { ((void (*)(char *))(intptr_t)FunctionBytes.data())(Memory); } std::unique_ptr Context; std::unique_ptr ExecEngine; StringRef FunctionBytes; }; // Creates a void(int8*) MachineFunction. MachineFunction &createVoidVoidPtrMachineFunction(StringRef FunctionID, Module *Module, MachineModuleInfo *MMI); } // namespace exegesis } // namespace llvm #endif // LLVM_TOOLS_LLVM_EXEGESIS_ASSEMBLER_H