llir-opt  0.0.1
Low-Level Post-Link Optimiser for OCaml and C
inst.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 <vector>
8 #include <optional>
9 
10 #include <llvm/ADT/ilist_node.h>
11 #include <llvm/ADT/ilist.h>
12 
13 #include "core/annot.h"
14 #include "core/constant.h"
15 #include "core/cond.h"
16 #include "core/expr.h"
17 #include "core/type.h"
18 #include "core/register.h"
19 #include "core/value.h"
20 #include "core/calling_conv.h"
21 
22 class Block;
23 class Func;
24 class Inst;
25 class Context;
26 class Symbol;
27 
28 
29 
33 template <> struct llvm::ilist_traits<Inst> {
34 private:
35  using instr_iterator = simple_ilist<Inst>::iterator;
36 
37 public:
38  void deleteNode(Inst *inst);
39  void addNodeToList(Inst *inst);
40  void removeNodeFromList(Inst *inst);
41  void transferNodesFromList(
42  ilist_traits &from,
43  instr_iterator first,
44  instr_iterator last
45  );
46 
47  Block *getParent();
48 };
49 
53 class Inst
54  : public llvm::ilist_node_with_parent<Inst, Block>
55  , public User
56 {
57 public:
59  static constexpr Value::Kind kValueKind = Value::Kind::INST;
60 
61 public:
65  enum class Kind : uint8_t {
66  #define GET_INST(kind, type, name, sort) kind,
67  #include "instructions.def"
68  };
69 
71  virtual ~Inst();
72 
74  unsigned GetOrder() const { return order_; }
75 
77  void removeFromParent();
79  void eraseFromParent();
80 
82  Kind GetKind() const { return kind_; }
84  bool Is(Kind kind) const { return GetKind() == kind; }
86  Block *getParent() const { return parent_; }
88  virtual unsigned GetNumRets() const { return 0; }
90  virtual Type GetType(unsigned i) const { llvm_unreachable("missing type"); }
91 
93  bool IsVoid() const { return GetNumRets() == 0; }
94 
96  virtual bool IsReturn() const { return false; }
98  virtual bool IsConstant() const { return false; }
100  virtual bool IsTerminator() const { return false; }
102  virtual bool HasSideEffects() const { return false; }
103 
105  template<typename T>
106  bool HasAnnot() const { return annot_.Has<T>(); }
107 
109  template<typename T>
110  bool ClearAnnot() { return annot_.Clear<T>(); }
111 
113  template<typename T>
114  const T *GetAnnot() const { return annot_.Get<T>(); }
115 
117  template<typename T, typename... Args>
118  bool SetAnnot(Args&&... args)
119  {
120  return annot_.Set<T, Args...>(std::forward<Args>(args)...);
121  }
122 
124  bool AddAnnot(const Annot &annot) { return annot_.Add(annot); }
126  const AnnotSet &GetAnnots() const { return annot_; }
128  size_t annot_size() const { return annot_.size(); }
130  bool annot_empty() const { return annot_.empty(); }
132  llvm::iterator_range<AnnotSet::const_iterator> annots() const
133  {
134  return llvm::make_range(annot_.begin(), annot_.end());
135  }
136 
138  Ref<Inst> GetSubValue(unsigned i) { return Ref(this, i); }
140  ConstRef<Inst> GetSubValue(unsigned i) const { return ConstRef(this, i); }
141 
143  void replaceAllUsesWith(Value *v) override;
145  void replaceAllUsesWith(llvm::ArrayRef<Ref<Inst>> v);
146 
148  template <typename T>
149  typename std::enable_if<std::is_base_of<Inst, T>::value>::type
150  replaceAllUsesWith(llvm::ArrayRef<Ref<T>> insts)
151  {
152  std::vector<Ref<Inst>> values;
153  for (Ref<T> inst : insts) {
154  values.push_back(inst);
155  }
156  return replaceAllUsesWith(values);
157  }
158 
160  void dump(llvm::raw_ostream &os = llvm::errs()) const;
161 
162 protected:
164  Inst(Kind kind, unsigned numOps, AnnotSet &&annot);
166  Inst(Kind kind, unsigned numOps, const AnnotSet &annot);
167 
168 private:
169  friend struct llvm::ilist_traits<Inst>;
171  void setParent(Block *parent) { parent_ = parent; }
172 
173 private:
175  const Kind kind_;
177  AnnotSet annot_;
178 
179 protected:
183  unsigned order_;
184 };
185 
187 llvm::raw_ostream &operator<<(llvm::raw_ostream &os, Inst::Kind kind);
188 
190 inline llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const Inst &inst)
191 {
192  inst.dump(os);
193  return os;
194 }
195 
196 #define GET_BASE_INTF
197 #include "instructions.def"
Inst::SetAnnot
bool SetAnnot(Args &&... args)
Sets an annotation.
Definition: inst.h:118
Inst::kValueKind
static constexpr Value::Kind kValueKind
Kind of the instruction.
Definition: inst.h:59
Inst::IsReturn
virtual bool IsReturn() const
Checks if the instruction returns from the function.
Definition: inst.h:96
Inst::order_
unsigned order_
Unique number for stable ordering.
Definition: inst.h:183
Inst
Definition: inst.h:53
Func
Definition: func.h:30
Inst::HasSideEffects
virtual bool HasSideEffects() const
Checks if the instruction has side effects.
Definition: inst.h:102
Inst::GetSubValue
ConstRef< Inst > GetSubValue(unsigned i) const
Returns the ith sub-value.
Definition: inst.h:140
Inst::replaceAllUsesWith
std::enable_if< std::is_base_of< Inst, T >::value >::type replaceAllUsesWith(llvm::ArrayRef< Ref< T >> insts)
Replaces all uses of a multi-type value.
Definition: inst.h:150
AnnotSet::Has
bool Has() const
Definition: annot.h:94
Inst::Kind
Kind
Definition: inst.h:65
ConstRef< Inst >
Inst::IsTerminator
virtual bool IsTerminator() const
Checks if the instruction is a terminator.
Definition: inst.h:100
Inst::AddAnnot
bool AddAnnot(const Annot &annot)
Adds an annotation.
Definition: inst.h:124
Value
Definition: value.h:22
Inst::GetAnnots
const AnnotSet & GetAnnots() const
Returns the instruction's annotation.
Definition: inst.h:126
Inst::GetType
virtual Type GetType(unsigned i) const
Returns the type of the ith return value.
Definition: inst.h:90
AnnotSet::empty
bool empty() const
Checks if there are any annotations set.
Definition: annot.h:183
Inst::removeFromParent
void removeFromParent()
Removes an instruction from the parent.
Definition: inst.cpp:46
Inst::GetOrder
unsigned GetOrder() const
Returns a unique, stable identifier for the instruction.
Definition: inst.h:74
Inst::GetKind
Kind GetKind() const
Returns the instruction kind.
Definition: inst.h:82
Inst::GetSubValue
Ref< Inst > GetSubValue(unsigned i)
Returns the ith sub-value.
Definition: inst.h:138
AnnotSet
Definition: annot.h:69
AnnotSet::Add
bool Add(const Annot &annot)
Definition: annot.cpp:66
AnnotSet::size
size_t size() const
Returns the number of set annotations.
Definition: annot.h:181
Inst::ClearAnnot
bool ClearAnnot()
Removes an annotation.
Definition: inst.h:110
Inst::annot_size
size_t annot_size() const
Returns the number of annotations.
Definition: inst.h:128
Inst::replaceAllUsesWith
void replaceAllUsesWith(Value *v) override
Replaces all uses of this value.
Definition: inst.cpp:58
Inst::Is
bool Is(Kind kind) const
Checks if the instruction is of a specific kind.
Definition: inst.h:84
Inst::~Inst
virtual ~Inst()
Destroys an instruction.
Definition: inst.cpp:41
Inst::IsVoid
bool IsVoid() const
Checks if the instruction is void.
Definition: inst.h:93
Inst::dump
void dump(llvm::raw_ostream &os=llvm::errs()) const
Dumps the textual representation of the instruction.
Definition: inst.cpp:81
Value::Kind
Kind
Enumeration of value types.
Definition: value.h:133
AnnotSet::Clear
bool Clear()
Definition: annot.h:126
AnnotSet::end
iterator end()
Iterator past the last annotation.
Definition: annot.h:187
Inst::annots
llvm::iterator_range< AnnotSet::const_iterator > annots() const
Iterator over annotations.
Definition: inst.h:132
Inst::eraseFromParent
void eraseFromParent()
Removes an instruction from the parent and deletes it.
Definition: inst.cpp:52
Inst::parent_
Block * parent_
Parent node.
Definition: inst.h:181
Inst::Inst
Inst(Kind kind, unsigned numOps, AnnotSet &&annot)
Constructs an instruction of a given type.
Definition: inst.cpp:21
Inst::getParent
Block * getParent() const
Returns the parent node.
Definition: inst.h:86
Ref
Definition: ref.h:63
Inst::IsConstant
virtual bool IsConstant() const
Checks if the instruction is constant.
Definition: inst.h:98
Inst::annot_empty
bool annot_empty() const
Checks if any flags are set.
Definition: inst.h:130
AnnotSet::Set
bool Set(Args &&... args)
Definition: annot.h:110
Block
Definition: block.h:29
Inst::GetNumRets
virtual unsigned GetNumRets() const
Returns the number of returned values.
Definition: inst.h:88
Annot
Definition: annot.h:15
User
Definition: user.h:20
AnnotSet::begin
iterator begin()
Iterator to the first annotation.
Definition: annot.h:185
Inst::HasAnnot
bool HasAnnot() const
Checks if a flag is set.
Definition: inst.h:106
Inst::GetAnnot
const T * GetAnnot() const
Returns an annotation.
Definition: inst.h:114
AnnotSet::Get
const T * Get() const
Definition: annot.h:142