GNU Octave  4.2.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
jit-util.h
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2012-2017 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 the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 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 <http://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 Twine;
64  class GlobalVariable;
65  class TerminatorInst;
66  class PHINode;
67 
68  class ConstantFolder;
69 
70  template <bool preserveNames>
72 
73  template <bool preserveNames, typename T, typename Inserter>
74  class IRBuilder;
75 
78 }
79 
80 class octave_base_value;
81 class octave_builtin;
82 class octave_value;
83 class tree;
84 class tree_expression;
85 
86 // thrown when we should give up on JIT and interpret
87 class jit_fail_exception : public std::runtime_error
88 {
89 public:
90  jit_fail_exception (void) : std::runtime_error ("unknown"), mknown (false) { }
91  jit_fail_exception (const std::string& reason) : std::runtime_error (reason),
92  mknown (true)
93  { }
94 
95  bool known (void) const { return mknown; }
96 private:
97  bool mknown;
98 };
99 
100 // llvm doesn't provide this, and it's really useful for debugging
101 std::ostream& operator<< (std::ostream& os, const llvm::Value& v);
102 
103 template <typename HOLDER_T, typename SUB_T>
105 
106 // jit_internal_list and jit_internal_node implement generic embedded doubly
107 // linked lists. List items extend from jit_internal_list, and can be placed
108 // in nodes of type jit_internal_node. We use CRTP twice.
109 template <typename LIST_T, typename NODE_T>
110 class
112 {
113  friend class jit_internal_node<LIST_T, NODE_T>;
114 public:
115  jit_internal_list (void) : use_head (0), use_tail (0), muse_count (0) { }
116 
117  virtual ~jit_internal_list (void)
118  {
119  while (use_head)
120  use_head->stash_value (0);
121  }
122 
123  NODE_T *first_use (void) const { return use_head; }
124 
125  size_t use_count (void) const { return muse_count; }
126 private:
127  NODE_T *use_head;
128  NODE_T *use_tail;
129  size_t muse_count;
130 };
131 
132 // a node for internal linked lists
133 template <typename LIST_T, typename NODE_T>
134 class
136 {
137 public:
139 
140  jit_internal_node (void) : mvalue (0), mnext (0), mprev (0) { }
141 
142  ~jit_internal_node (void) { remove (); }
143 
144  LIST_T *value (void) const { return mvalue; }
145 
146  void stash_value (LIST_T *avalue)
147  {
148  remove ();
149 
150  mvalue = avalue;
151 
152  if (mvalue)
153  {
154  jit_ilist *ilist = mvalue;
155  NODE_T *sthis = static_cast<NODE_T *> (this);
156  if (ilist->use_head)
157  {
158  ilist->use_tail->mnext = sthis;
159  mprev = ilist->use_tail;
160  }
161  else
162  ilist->use_head = sthis;
163 
164  ilist->use_tail = sthis;
165  ++ilist->muse_count;
166  }
167  }
168 
169  NODE_T *next (void) const { return mnext; }
170 
171  NODE_T *prev (void) const { return mprev; }
172 private:
173  void remove ()
174  {
175  if (mvalue)
176  {
177  jit_ilist *ilist = mvalue;
178  if (mprev)
179  mprev->mnext = mnext;
180  else
181  // we are the use_head
182  ilist->use_head = mnext;
183 
184  if (mnext)
185  mnext->mprev = mprev;
186  else
187  // we are the use tail
188  ilist->use_tail = mprev;
189 
190  mnext = mprev = 0;
191  --ilist->muse_count;
192  mvalue = 0;
193  }
194  }
195 
196  LIST_T *mvalue;
197  NODE_T *mnext;
198  NODE_T *mprev;
199 };
200 
201 // Use like: isa<jit_phi> (value)
202 // basically just a short cut type typing dyanmic_cast.
203 template <typename T, typename U>
204 bool isa (U *value)
205 {
206  return dynamic_cast<T *> (value);
207 }
208 
209 #define JIT_ASSIGN_ARG(i) the_args[i] = arg ## i;
210 #define JIT_EXPAND(ret, fname, type, isconst, N) \
211  ret fname (JIT_PARAM_ARGS OCT_MAKE_DECL_LIST (type, arg, N)) isconst \
212  { \
213  std::vector<type> the_args (N); \
214  OCT_ITERATE_MACRO (JIT_ASSIGN_ARG, N); \
215  return fname (JIT_PARAMS the_args); \
216  }
217 
218 #endif
219 #endif
std::ostream & operator<<(std::ostream &os, const llvm::Value &v)
Definition: jit-util.cc:44
Definition: jit-util.h:43
LIST_T * mvalue
Definition: jit-util.h:196
jit_internal_node(void)
Definition: jit-util.h:140
STL namespace.
NODE_T * mprev
Definition: jit-util.h:198
void stash_value(LIST_T *avalue)
Definition: jit-util.h:146
bool known(void) const
Definition: jit-util.h:95
NODE_T * use_tail
Definition: jit-util.h:128
jit_fail_exception(void)
Definition: jit-util.h:90
NODE_T * use_head
Definition: jit-util.h:127
jit_internal_list(void)
Definition: jit-util.h:115
is false
Definition: cellfun.cc:398
bool isa(U *value)
Definition: jit-util.h:204
jit_internal_list< LIST_T, NODE_T > jit_ilist
Definition: jit-util.h:138
NODE_T * mnext
Definition: jit-util.h:197
LIST_T * value(void) const
Definition: jit-util.h:144
size_t use_count(void) const
Definition: jit-util.h:125
NODE_T * first_use(void) const
Definition: jit-util.h:123
OCTAVE_EXPORT octave_value_list or N dimensional array whose elements are all equal to the IEEE symbol zero divided by nd tex zero divided by nd ifnottex and any operation involving another NaN value(5+NaN).Note that NaN always compares not equal to NaN(NaN!
Definition: pt.h:39
~jit_internal_node(void)
Definition: jit-util.h:142
NODE_T * prev(void) const
Definition: jit-util.h:171
size_t muse_count
Definition: jit-util.h:129
NODE_T * next(void) const
Definition: jit-util.h:169
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:854
jit_fail_exception(const std::string &reason)
Definition: jit-util.h:91
IRBuilder< true, ConstantFolder, IRBuilderDefaultInserter< true > > IRBuilderD
Definition: jit-util.h:74
virtual ~jit_internal_list(void)
Definition: jit-util.h:117