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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// 9 /// \file 10 /// Defines classes to assemble functions composed of a single basic block of 11 /// MCInsts. 12 /// 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_TOOLS_LLVM_EXEGESIS_ASSEMBLER_H 16 #define LLVM_TOOLS_LLVM_EXEGESIS_ASSEMBLER_H 17 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/ExecutionEngine.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 35 namespace llvm { 36 namespace exegesis { 37 38 class ExegesisTarget; 39 40 // Gather the set of reserved registers (depends on function's calling 41 // convention and target machine). 42 BitVector getFunctionReservedRegs(const TargetMachine &TM); 43 44 // Helper to fill in a basic block. 45 class BasicBlockFiller { 46 public: 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 DebugLoc &DL = DebugLoc()); 54 55 MachineFunction &MF; 56 MachineBasicBlock *const MBB; 57 const MCInstrInfo *const MCII; 58 }; 59 60 // Helper to fill in a function. 61 class FunctionFiller { 62 public: 63 FunctionFiller(MachineFunction &MF, std::vector<unsigned> RegistersSetUp); 64 65 // Adds a basic block to the function. 66 BasicBlockFiller addBasicBlock(); 67 68 // Returns the function entry point. getEntry()69 BasicBlockFiller getEntry() { return Entry; } 70 71 MachineFunction &MF; 72 const MCInstrInfo *const MCII; 73 74 // Returns the set of registers in the snippet setup code. 75 ArrayRef<unsigned> getRegistersSetUp() const; 76 77 private: 78 BasicBlockFiller Entry; 79 // The set of registers that are set up in the basic block. 80 std::vector<unsigned> RegistersSetUp; 81 }; 82 83 // A callback that fills a function. 84 using FillFunction = std::function<void(FunctionFiller &)>; 85 86 // Creates a temporary `void foo(char*)` function containing the provided 87 // Instructions. Runs a set of llvm Passes to provide correct prologue and 88 // epilogue. Once the MachineFunction is ready, it is assembled for TM to 89 // AsmStream, the temporary function is eventually discarded. 90 Error assembleToStream(const ExegesisTarget &ET, 91 std::unique_ptr<LLVMTargetMachine> TM, 92 ArrayRef<unsigned> LiveIns, 93 ArrayRef<RegisterValue> RegisterInitialValues, 94 const FillFunction &Fill, raw_pwrite_stream &AsmStream); 95 96 // Creates an ObjectFile in the format understood by the host. 97 // Note: the resulting object keeps a copy of Buffer so it can be discarded once 98 // this function returns. 99 object::OwningBinary<object::ObjectFile> getObjectFromBuffer(StringRef Buffer); 100 101 // Loads the content of Filename as on ObjectFile and returns it. 102 object::OwningBinary<object::ObjectFile> getObjectFromFile(StringRef Filename); 103 104 // Consumes an ObjectFile containing a `void foo(char*)` function and make it 105 // executable. 106 struct ExecutableFunction { 107 explicit ExecutableFunction( 108 std::unique_ptr<LLVMTargetMachine> TM, 109 object::OwningBinary<object::ObjectFile> &&ObjectFileHolder); 110 111 // Retrieves the function as an array of bytes. getFunctionBytesExecutableFunction112 StringRef getFunctionBytes() const { return FunctionBytes; } 113 114 // Executes the function. operatorExecutableFunction115 void operator()(char *Memory) const { 116 ((void (*)(char *))(intptr_t)FunctionBytes.data())(Memory); 117 } 118 119 std::unique_ptr<LLVMContext> Context; 120 std::unique_ptr<ExecutionEngine> ExecEngine; 121 StringRef FunctionBytes; 122 }; 123 124 // Creates a void(int8*) MachineFunction. 125 MachineFunction &createVoidVoidPtrMachineFunction(StringRef FunctionID, 126 Module *Module, 127 MachineModuleInfo *MMI); 128 129 } // namespace exegesis 130 } // namespace llvm 131 132 #endif // LLVM_TOOLS_LLVM_EXEGESIS_ASSEMBLER_H 133