GNU Octave  6.2.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
jit-util.h
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 2012-2021 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 // Some utility classes and functions used throughout jit
27 
28 #if ! defined (octave_jit_util_h)
29 #define octave_jit_util_h 1
30 
31 #include "octave-config.h"
32 
33 #if defined (HAVE_LLVM)
34 
35 #include <stdexcept>
36 
37 #if defined (HAVE_LLVM_IR_DATALAYOUT_H) || defined (HAVE_LLVM_DATALAYOUT_H)
38 # define HAVE_LLVM_DATALAYOUT
39 #endif
40 
41 // we don't want to include llvm headers here, as they require
42 // __STDC_LIMIT_MACROS and __STDC_CONSTANT_MACROS be defined in the entire
43 // compilation unit
44 namespace llvm
45 {
46  class Value;
47  class Module;
48  class ExecutionEngine;
49  class Function;
50  class BasicBlock;
51  class LLVMContext;
52  class Type;
53  class StructType;
54  class FunctionType;
55  class Twine;
56  class GlobalValue;
57  class GlobalVariable;
58  class TerminatorInst;
59  class PHINode;
60  class TargetMachine;
61 
62  class ConstantFolder;
63 
64 #if defined LLVM_IRBUILDER_HAS_TWO_TEMPLATE_ARGS
65 
67 
68  template <typename T, typename Inserter>
69  class IRBuilder;
70 
72  IRBuilderD;
73 
74 #else
75 
76  template <bool preserveNames>
78 
79  template <bool preserveNames, typename T, typename Inserter>
80  class IRBuilder;
81 
84 
85 #endif
86 }
87 
88 // some octave classes that are not (yet) in the octave namespace
89 class octave_base_value;
90 class octave_builtin;
91 class octave_value;
92 class tree;
93 class tree_expression;
94 
95 namespace octave
96 {
97  // thrown when we should give up on JIT and interpret
98  class jit_fail_exception : public std::runtime_error
99  {
100  public:
101 
103  : std::runtime_error ("unknown"), m_known (false)
104  { }
105 
106  jit_fail_exception (const std::string& reason)
107  : std::runtime_error (reason), m_known (true)
108  { }
109 
110  bool known (void) const { return m_known; }
111 
112  private:
113 
114  bool m_known;
115  };
116 
117  // llvm doesn't provide this, and it's really useful for debugging
118  std::ostream& operator<< (std::ostream& os, const llvm::Value& v);
119 
120  template <typename HOLDER_T, typename SUB_T>
121  class jit_internal_node;
122 
123  // jit_internal_list and jit_internal_node implement generic embedded doubly
124  // linked lists. List items extend from jit_internal_list, and can be placed
125  // in nodes of type jit_internal_node. We use CRTP twice.
126 
127  template <typename LIST_T, typename NODE_T>
128  class
130  {
131  friend class jit_internal_node<LIST_T, NODE_T>;
132 
133  public:
134 
136  : m_use_head (0), m_use_tail (0), m_use_count (0)
137  { }
138 
139  virtual ~jit_internal_list (void)
140  {
141  while (m_use_head)
142  m_use_head->stash_value (0);
143  }
144 
145  NODE_T * first_use (void) const { return m_use_head; }
146 
147  size_t use_count (void) const { return m_use_count; }
148 
149  private:
150 
151  NODE_T *m_use_head;
152  NODE_T *m_use_tail;
153  size_t m_use_count;
154  };
155 
156  // a node for internal linked lists
157  template <typename LIST_T, typename NODE_T>
158  class
160  {
161  public:
162 
164 
166  : m_value (nullptr), m_next (nullptr), m_prev (nullptr)
167  { }
168 
169  ~jit_internal_node (void) { remove (); }
170 
171  LIST_T * value (void) const { return m_value; }
172 
173  void stash_value (LIST_T *avalue)
174  {
175  remove ();
176 
177  m_value = avalue;
178 
179  if (m_value)
180  {
181  jit_ilist *ilist = m_value;
182  NODE_T *sthis = static_cast<NODE_T *> (this);
183  if (ilist->m_use_head)
184  {
185  ilist->m_use_tail->m_next = sthis;
186  m_prev = ilist->m_use_tail;
187  }
188  else
189  ilist->m_use_head = sthis;
190 
191  ilist->m_use_tail = sthis;
192  ++ilist->m_use_count;
193  }
194  }
195 
196  NODE_T * next (void) const { return m_next; }
197 
198  NODE_T * prev (void) const { return m_prev; }
199 
200  private:
201 
202  void remove (void)
203  {
204  if (m_value)
205  {
206  jit_ilist *ilist = m_value;
207  if (m_prev)
208  m_prev->m_next = m_next;
209  else
210  // we are the use_head
211  ilist->m_use_head = m_next;
212 
213  if (m_next)
214  m_next->m_prev = m_prev;
215  else
216  // we are the use tail
217  ilist->m_use_tail = m_prev;
218 
219  m_next = m_prev = 0;
220  --ilist->m_use_count;
221  m_value = 0;
222  }
223  }
224 
225  LIST_T *m_value;
226  NODE_T *m_next;
227  NODE_T *m_prev;
228  };
229 
230  // Use like: isa<jit_phi> (value)
231  // basically just a short cut type typing dyanmic_cast.
232  template <typename T, typename U>
233  bool isa (U *value)
234  {
235  return dynamic_cast<T *> (value);
236  }
237 
238 }
239 
240 #endif
241 #endif
bool known(void) const
Definition: jit-util.h:110
jit_fail_exception(const std::string &reason)
Definition: jit-util.h:106
virtual ~jit_internal_list(void)
Definition: jit-util.h:139
NODE_T * first_use(void) const
Definition: jit-util.h:145
size_t use_count(void) const
Definition: jit-util.h:147
LIST_T * value(void) const
Definition: jit-util.h:171
NODE_T * next(void) const
Definition: jit-util.h:196
void stash_value(LIST_T *avalue)
Definition: jit-util.h:173
jit_internal_list< LIST_T, NODE_T > jit_ilist
Definition: jit-util.h:163
NODE_T * prev(void) const
Definition: jit-util.h:198
Definition: jit-util.h:45
IRBuilder< true, ConstantFolder, IRBuilderDefaultInserter< true > > IRBuilderD
Definition: jit-util.h:80
std::ostream & operator<<(std::ostream &os, const jit_block_list &blocks)
Definition: jit-ir.cc:134
bool isa(U *value)
Definition: jit-util.h:233