reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
//===-- 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 <memory>

#include "BenchmarkCode.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<MCInst> 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<unsigned> 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<unsigned> getRegistersSetUp() const;

private:
  BasicBlockFiller Entry;
  // The set of registers that are set up in the basic block.
  std::vector<unsigned> RegistersSetUp;
};

// A callback that fills a function.
using FillFunction = std::function<void(FunctionFiller &)>;

// 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.
void assembleToStream(const ExegesisTarget &ET,
                      std::unique_ptr<LLVMTargetMachine> TM,
                      ArrayRef<unsigned> LiveIns,
                      ArrayRef<RegisterValue> 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<object::ObjectFile> getObjectFromBuffer(StringRef Buffer);

// Loads the content of Filename as on ObjectFile and returns it.
object::OwningBinary<object::ObjectFile> getObjectFromFile(StringRef Filename);

// Consumes an ObjectFile containing a `void foo(char*)` function and make it
// executable.
struct ExecutableFunction {
  explicit ExecutableFunction(
      std::unique_ptr<LLVMTargetMachine> TM,
      object::OwningBinary<object::ObjectFile> &&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<LLVMContext> Context;
  std::unique_ptr<ExecutionEngine> 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