llir-opt  0.0.1
Low-Level Post-Link Optimiser for OCaml and C
annot_printer.h
1 // This file if part of the llir-opt project.
2 // Licensing information can be found in the LICENSE file.
3 // (C) 2018 Nandor Licker. All rights reserved.
4 
5 #pragma once
6 
7 #include <optional>
8 #include <set>
9 
10 #include <llvm/Pass.h>
11 #include <llvm/IR/DataLayout.h>
12 #include <llvm/MC/MCStreamer.h>
13 #include <llvm/MC/MCObjectFileInfo.h>
14 #include <llvm/Target/TargetMachine.h>
15 #include <llvm/CodeGen/MachineFunctionPass.h>
16 #include <llvm/CodeGen/TargetSubtargetInfo.h>
17 
18 #include "core/adt/hash.h"
19 #include "core/annot.h"
20 
21 class Prog;
22 class MovInst;
23 class X86ISel;
24 class ISelMapping;
25 
26 
27 
47 class AnnotPrinter : public llvm::ModulePass {
48 public:
51  char &ID,
52  llvm::MCContext *ctx,
53  llvm::MCStreamer *os,
54  const llvm::MCObjectFileInfo *objInfo,
55  const llvm::DataLayout &layout,
56  const ISelMapping &mapping,
57  bool shared
58  );
59 
60 protected:
62  virtual std::optional<unsigned> GetRegisterIndex(llvm::Register reg) = 0;
64  virtual llvm::StringRef GetRegisterName(unsigned reg) = 0;
66  virtual llvm::Register GetStackPointer() = 0;
68  virtual unsigned GetImplicitStackSize() const = 0;
69 
71  virtual int64_t GetFrameOffset(const llvm::MachineInstr &MI) const
72  {
73  return 0;
74  }
75 
76 private:
78  bool runOnModule(llvm::Module &M) override;
80  void getAnalysisUsage(llvm::AnalysisUsage &AU) const override;
81 
82 private:
84  struct FrameInfo {
86  llvm::MCSymbol *Label;
88  int64_t Offset;
90  int16_t FrameSize;
92  std::set<uint16_t> Live;
94  std::vector<size_t> Allocs;
96  std::vector<llvm::MCSymbol *> Debug;
97  };
98 
100  struct RootInfo {
102  llvm::MCSymbol *Label;
104  int64_t Offset;
105 
106  RootInfo(llvm::MCSymbol *label, int64_t offset)
107  : Label(label), Offset(offset)
108  {
109  }
110  };
111 
113  struct DebugKey {
115  const CamlFrame::DebugInfos &Debug;
116 
117  bool operator==(const DebugKey &that) const {
118  return Debug == that.Debug;
119  }
120  };
121 
123  struct DebugKeyHash {
124  size_t operator() (const DebugKey &key) const {
125  size_t hash = 0;
126  for (const auto &debug : key.Debug) {
127  ::hash_combine(hash, std::hash<int64_t>{}(debug.Location));
128  ::hash_combine(hash, std::hash<std::string>{}(debug.File));
129  ::hash_combine(hash, std::hash<std::string>{}(debug.Definition));
130  }
131  return hash;
132  }
133  };
134 
136  struct DebugInfo {
137  llvm::MCSymbol *Definition;
138  int64_t Location;
139  };
140 
142  struct DebugInfos {
143  llvm::MCSymbol *Symbol;
144  std::vector<DebugInfo> Debug;
145  };
146 
148  struct DefinitionInfo {
149  llvm::MCSymbol *Symbol;
150  llvm::MCSymbol *File;
151  std::string Definition;
152  };
153 
155  void LowerFrame(const FrameInfo &frame);
157  llvm::MCSymbol *LowerSymbol(const std::string_view name);
159  llvm::MCSymbol *RecordDebug(const CamlFrame::DebugInfos &debug);
161  llvm::MCSymbol *RecordDefinition(
162  const std::string &file,
163  const std::string &def
164  );
166  llvm::MCSymbol *RecordFile(const std::string &file);
168  void EmitDiff(llvm::MCSymbol *symbol, unsigned size = 4);
170  void EmitOffset(llvm::MCSymbol *symbol, int64_t off);
171 
172 protected:
176  llvm::MCContext *ctx_;
178  llvm::MCStreamer *os_;
180  const llvm::MCObjectFileInfo *objInfo_;
182  const llvm::DataLayout layout_;
184  std::vector<FrameInfo> frames_;
186  std::vector<RootInfo> roots_;
188  std::unordered_map<DebugKey, DebugInfos, DebugKeyHash> debug_;
190  std::unordered_map<
191  std::pair<std::string, std::string>,
192  DefinitionInfo
193  > defs_;
195  std::unordered_map<std::string, llvm::MCSymbol *> files_;
197  bool shared_;
198 };
AnnotPrinter::GetRegisterName
virtual llvm::StringRef GetRegisterName(unsigned reg)=0
Returns the name of a register.
CamlFrame::DebugInfos
std::vector< DebugInfo > DebugInfos
Debug information bundle.
Definition: annot.h:231
AnnotPrinter::roots_
std::vector< RootInfo > roots_
List of root frames.
Definition: annot_printer.h:186
AnnotPrinter::GetStackPointer
virtual llvm::Register GetStackPointer()=0
Returns the stack pointer of the target.
AnnotPrinter::shared_
bool shared_
Flag to indicate whether a shared library is emitted.
Definition: annot_printer.h:197
ISelMapping
Definition: isel_mapping.h:22
AnnotPrinter::defs_
std::unordered_map< std::pair< std::string, std::string >, DefinitionInfo > defs_
Mapping from definitions to labels.
Definition: annot_printer.h:193
AnnotPrinter::GetImplicitStackSize
virtual unsigned GetImplicitStackSize() const =0
Returns the implicit stack size, besides the frame adjustment.
AnnotPrinter
Definition: annot_printer.h:47
ID
Definition: id.h:19
AnnotPrinter::frames_
std::vector< FrameInfo > frames_
List of frames to emit information for.
Definition: annot_printer.h:184
AnnotPrinter::debug_
std::unordered_map< DebugKey, DebugInfos, DebugKeyHash > debug_
Mapping of debug objects.
Definition: annot_printer.h:188
AnnotPrinter::GetRegisterIndex
virtual std::optional< unsigned > GetRegisterIndex(llvm::Register reg)=0
Returns the GC index of a register.
MovInst
Definition: mov.h:17
AnnotPrinter::objInfo_
const llvm::MCObjectFileInfo * objInfo_
Object-file specific information.
Definition: annot_printer.h:180
AnnotPrinter::files_
std::unordered_map< std::string, llvm::MCSymbol * > files_
Mapping from file names to labels.
Definition: annot_printer.h:195
X86ISel
Definition: x86isel.h:61
Prog
Definition: prog.h:33
AnnotPrinter::os_
llvm::MCStreamer * os_
Streamer to emit output to.
Definition: annot_printer.h:178
AnnotPrinter::mapping_
const ISelMapping & mapping_
Instruction selector pass containing info for annotations.
Definition: annot_printer.h:174
AnnotPrinter::AnnotPrinter
AnnotPrinter(char &ID, llvm::MCContext *ctx, llvm::MCStreamer *os, const llvm::MCObjectFileInfo *objInfo, const llvm::DataLayout &layout, const ISelMapping &mapping, bool shared)
Initialises the pass which prints data sections.
Definition: annot_printer.cpp:40
AnnotPrinter::layout_
const llvm::DataLayout layout_
Data layout.
Definition: annot_printer.h:182
AnnotPrinter::ctx_
llvm::MCContext * ctx_
LLVM context.
Definition: annot_printer.h:176
AnnotPrinter::GetFrameOffset
virtual int64_t GetFrameOffset(const llvm::MachineInstr &MI) const
Return the offset to apply to a label.
Definition: annot_printer.h:71