llir-opt  0.0.1
Low-Level Post-Link Optimiser for OCaml and C
parser.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 <llvm/ADT/StringRef.h>
8 
9 #include <fstream>
10 #include <list>
11 #include <optional>
12 #include <stack>
13 #include <string>
14 #include <unordered_map>
15 #include <unordered_set>
16 
17 #include "core/adt/hash.h"
18 #include "core/adt/sexp.h"
19 #include "core/calling_conv.h"
20 #include "core/error.h"
21 #include "core/inst.h"
22 #include "core/lexer.h"
23 #include "core/visibility.h"
24 #include "core/xtor.h"
25 
26 class Atom;
27 class Block;
28 class Context;
29 class Data;
30 class Const;
31 class Func;
32 class Prog;
33 class Object;
34 
35 
36 
40 class Parser final {
41 private:
43  using Token = Lexer::Token;
45  using VRegMap = std::unordered_map<ConstRef<Inst>, unsigned>;
46 
47  struct Section {
49  std::optional<unsigned> Align;
51  Data *D = nullptr;
53  Object *O = nullptr;
55  Atom *A = nullptr;
57  Func *F = nullptr;
59  VRegMap VRegs;
60 
61  Section(Data *data) : D(data) {}
62  };
63 
64 public:
70  Parser(llvm::StringRef buf, std::string_view ident);
71 
75  ~Parser();
76 
80  std::unique_ptr<Prog> Parse();
81 
82 private:
84  void ParseDirective(const std::string_view op);
85  // Segment directives.
86  void ParseSection(bool push);
87  // Other directives.
88  void ParseAlign();
89  void ParseP2Align();
90  void ParseEnd();
91  void ParseSpace();
92  void ParseAscii();
93  void ParseAsciz();
94  void ParseItem(Type ty);
95  void ParseItems(Type ty);
96  void ParseComm(Visibility visibility);
97  void ParseDouble();
98  // Function and segment attributes.
99  void ParseFeatures();
100  void ParseStackObject();
101  void ParseCall();
102  void ParseArgs();
103  void ParsePersonality();
104  void ParseVararg();
105  void ParseVisibility();
106  void ParseNoInline();
107  void ParseGlobl();
108  void ParseHidden();
109  void ParseWeak();
110  void ParseThreadLocal();
111  void ParsePopSection();
112  // Ignored directives.
113  void ParseFile();
114  void ParseLocal();
115  void ParseIdent();
116  void ParseAddrsig();
117  void ParseAddrsigSym();
118  void ParseProtected();
120  void ParseSet();
121  void ParseExtern();
123  void ParseXtor(Xtor::Kind kind);
124 
126  void CreateBlock(Func *func, const std::string_view name);
127 
129  Section &GetSection();
131  Object *GetOrCreateObject();
133  Atom *GetOrCreateAtom();
135  Func *GetFunction();
137  void EndFunction();
139  void Align(int64_t alignment);
141  void End();
142 
144  [[nodiscard]] static llvm::Error PhiPlacement(Func &func, VRegMap vregs);
145 
147  template<typename T>
148  T ParseToken(
149  const std::vector<std::pair<const char *, T>> &options,
150  const std::string_view str
151  );
152 
154  int64_t Number();
156  Type ParseType(std::string_view str);
158  TypeFlag ParseTypeFlags(const std::string_view op);
160  CallingConv ParseCallingConv(const std::string_view str);
162  Visibility ParseVisibility(const std::string_view str);
164  std::string_view ParseName(std::string_view ident);
165 
166 private:
168  class Operand {
169  public:
170  enum class Kind {
171  REGISTER,
172  VALUE,
173  };
174 
175  public:
176 
177  Operand(Register reg) : kind_(Kind::REGISTER), reg_(reg) {}
178  Operand(Value *val) : kind_(Kind::VALUE), val_(val) {}
179 
180  std::optional<uintptr_t> ToVReg() const
181  {
182  if (kind_ == Kind::VALUE) {
183  auto val = reinterpret_cast<uintptr_t>(val_);
184  return (val & 1) == 1 ? std::optional<uintptr_t>(val) : std::nullopt;
185  }
186  return {};
187  }
188 
189  std::optional<Value *> ToVal() const
190  {
191  if (kind_ == Kind::VALUE) return val_;
192  return {};
193  }
194 
195  std::optional<Register> ToReg() const
196  {
197  if (kind_ == Kind::REGISTER) return reg_;
198  return {};
199  }
200 
201  private:
202  Kind kind_;
203 
204  union {
205  Value *val_;
206  Register reg_;
207  };
208  };
209 
211  void ParseInstruction(
212  const std::string_view op,
213  Func *func,
214  VRegMap &vregs
215  );
217  Inst *CreateInst(
218  Func *func,
219  Block *block,
220  const std::string &op,
221  const std::vector<Operand> &ops,
222  const std::vector<std::pair<unsigned, TypeFlag>> &flags,
223  const std::optional<Cond> &ccs,
224  const std::optional<size_t> &sizes,
225  const std::vector<Type> &ts,
226  const std::optional<CallingConv> &conv,
227  bool strict,
228  AnnotSet &&annot
229  );
231  void ParseAnnotation(const std::string_view name, AnnotSet &annot);
232 
233 private:
235  Lexer l_;
237  std::unique_ptr<Prog> prog_;
239  uint64_t nextLabel_;
241  std::unordered_set<std::string> globls_;
243  std::unordered_set<std::string> hidden_;
245  std::unordered_set<std::string> weak_;
247  std::stack<Section> stk_;
248 };
Inst
Definition: inst.h:53
Parser::Parse
std::unique_ptr< Prog > Parse()
Definition: parser.cpp:43
Func
Definition: func.h:30
Atom
Definition: atom.h:23
Parser::~Parser
~Parser()
Definition: parser.cpp:38
Value
Definition: value.h:22
Data
Definition: data.h:47
AnnotSet
Definition: annot.h:69
Object
Definition: object.h:43
Lexer::Token
Token
Enumeration of tokens extracted from the stream.
Definition: lexer.h:27
Xtor::Kind
Kind
Constructor/destructor kinds.
Definition: xtor.h:23
Lexer
Definition: lexer.h:24
TypeFlag
Definition: type.h:32
Prog
Definition: prog.h:33
Parser
Definition: parser.h:40
Parser::Parser
Parser(llvm::StringRef buf, std::string_view ident)
Definition: parser.cpp:29
Block
Definition: block.h:29