aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/llvm16/tools/llvm-exegesis/lib/Assembler.h
blob: 2a83344b751e597b2bb79363197955a436704d0e (plain) (blame)
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
132
//===-- 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 "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<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.
Error 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