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