Home | History | Annotate | Line # | Download | only in lib
      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.
     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.
    112   StringRef getFunctionBytes() const { return FunctionBytes; }
    113 
    114   // Executes the function.
    115   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