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 "llvm/ADT/ArrayRef.h" 22 #include "llvm/ADT/BitVector.h" 23 #include "llvm/CodeGen/MachineFunction.h" 24 #include "llvm/CodeGen/MachineModuleInfo.h" 25 #include "llvm/ExecutionEngine/ExecutionEngine.h" 26 #include "llvm/IR/LLVMContext.h" 27 #include "llvm/IR/Module.h" 28 #include "llvm/MC/MCInst.h" 29 #include "llvm/Object/Binary.h" 30 #include "llvm/Object/ObjectFile.h" 31 #include "llvm/Support/raw_ostream.h" 32 #include "llvm/Target/TargetMachine.h" 33 34 namespace llvm { 35 namespace exegesis { 36 37 class ExegesisTarget; 38 39 // Gather the set of reserved registers (depends on function's calling 40 // convention and target machine). 41 BitVector getFunctionReservedRegs(const TargetMachine &TM); 42 43 // Helper to fill in a basic block. 44 class BasicBlockFiller { 45 public: 46 BasicBlockFiller(MachineFunction &MF, MachineBasicBlock *MBB, 47 const MCInstrInfo *MCII); 48 49 void addInstruction(const MCInst &Inst, const DebugLoc &DL = DebugLoc()); 50 void addInstructions(ArrayRef<MCInst> Insts, const DebugLoc &DL = DebugLoc()); 51 52 void addReturn(const DebugLoc &DL = DebugLoc()); 53 54 MachineFunction &MF; 55 MachineBasicBlock *const MBB; 56 const MCInstrInfo *const MCII; 57 }; 58 59 // Helper to fill in a function. 60 class FunctionFiller { 61 public: 62 FunctionFiller(MachineFunction &MF, std::vector<unsigned> RegistersSetUp); 63 64 // Adds a basic block to the function. 65 BasicBlockFiller addBasicBlock(); 66 67 // Returns the function entry point. getEntry()68 BasicBlockFiller getEntry() { return Entry; } 69 70 MachineFunction &MF; 71 const MCInstrInfo *const MCII; 72 73 // Returns the set of registers in the snippet setup code. 74 ArrayRef<unsigned> getRegistersSetUp() const; 75 76 private: 77 BasicBlockFiller Entry; 78 // The set of registers that are set up in the basic block. 79 std::vector<unsigned> RegistersSetUp; 80 }; 81 82 // A callback that fills a function. 83 using FillFunction = std::function<void(FunctionFiller &)>; 84 85 // Creates a temporary `void foo(char*)` function containing the provided 86 // Instructions. Runs a set of llvm Passes to provide correct prologue and 87 // epilogue. Once the MachineFunction is ready, it is assembled for TM to 88 // AsmStream, the temporary function is eventually discarded. 89 void assembleToStream(const ExegesisTarget &ET, 90 std::unique_ptr<LLVMTargetMachine> TM, 91 ArrayRef<unsigned> LiveIns, 92 ArrayRef<RegisterValue> RegisterInitialValues, 93 const FillFunction &Fill, raw_pwrite_stream &AsmStream); 94 95 // Creates an ObjectFile in the format understood by the host. 96 // Note: the resulting object keeps a copy of Buffer so it can be discarded once 97 // this function returns. 98 object::OwningBinary<object::ObjectFile> getObjectFromBuffer(StringRef Buffer); 99 100 // Loads the content of Filename as on ObjectFile and returns it. 101 object::OwningBinary<object::ObjectFile> getObjectFromFile(StringRef Filename); 102 103 // Consumes an ObjectFile containing a `void foo(char*)` function and make it 104 // executable. 105 struct ExecutableFunction { 106 explicit ExecutableFunction( 107 std::unique_ptr<LLVMTargetMachine> TM, 108 object::OwningBinary<object::ObjectFile> &&ObjectFileHolder); 109 110 // Retrieves the function as an array of bytes. getFunctionBytesExecutableFunction111 StringRef getFunctionBytes() const { return FunctionBytes; } 112 113 // Executes the function. operatorExecutableFunction114 void operator()(char *Memory) const { 115 ((void (*)(char *))(intptr_t)FunctionBytes.data())(Memory); 116 } 117 118 std::unique_ptr<LLVMContext> Context; 119 std::unique_ptr<ExecutionEngine> ExecEngine; 120 StringRef FunctionBytes; 121 }; 122 123 // Creates a void(int8*) MachineFunction. 124 MachineFunction &createVoidVoidPtrMachineFunction(StringRef FunctionID, 125 Module *Module, 126 MachineModuleInfo *MMI); 127 128 } // namespace exegesis 129 } // namespace llvm 130 131 #endif // LLVM_TOOLS_LLVM_EXEGESIS_ASSEMBLER_H 132