GNU Octave  4.0.0
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-2015 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 #ifdef HAVE_LLVM
31 
32 #include <stdexcept>
33 
34 #if defined(HAVE_LLVM_IR_DATALAYOUT_H) || defined(HAVE_LLVM_DATALAYOUT_H)
35 #define HAVE_LLVM_DATALAYOUT
36 #endif
37 
38 // we don't want to include llvm headers here, as they require
39 // __STDC_LIMIT_MACROS and __STDC_CONSTANT_MACROS be defined in the entire
40 // compilation unit
41 namespace llvm
42 {
43  class Value;
44  class Module;
45 #ifdef LEGACY_PASSMANAGER
46  namespace legacy {
47  class FunctionPassManager;
48  class PassManager;
49  }
50 #else
51  class FunctionPassManager;
52  class PassManager;
53 #endif
54  class ExecutionEngine;
55  class Function;
56  class BasicBlock;
57  class LLVMContext;
58  class Type;
59  class StructType;
60  class Twine;
61  class GlobalVariable;
62  class TerminatorInst;
63  class PHINode;
64 
65  class ConstantFolder;
66 
67  template <bool preserveNames>
69 
70  template <bool preserveNames, typename T, typename Inserter>
71  class IRBuilder;
72 
75 }
76 
77 class octave_base_value;
78 class octave_builtin;
79 class octave_value;
80 class tree;
81 class tree_expression;
82 
83 // thrown when we should give up on JIT and interpret
84 class jit_fail_exception : public std::runtime_error
85 {
86 public:
87  jit_fail_exception (void) : std::runtime_error ("unknown"), mknown (false) { }
88  jit_fail_exception (const std::string& reason) : std::runtime_error (reason),
89  mknown (true)
90  { }
91 
92  bool known (void) const { return mknown; }
93 private:
94  bool mknown;
95 };
96 
97 // llvm doesn't provide this, and it's really useful for debugging
98 std::ostream& operator<< (std::ostream& os, const llvm::Value& v);
99 
100 template <typename HOLDER_T, typename SUB_T>
102 
103 // jit_internal_list and jit_internal_node implement generic embedded doubly
104 // linked lists. List items extend from jit_internal_list, and can be placed
105 // in nodes of type jit_internal_node. We use CRTP twice.
106 template <typename LIST_T, typename NODE_T>
107 class
109 {
110  friend class jit_internal_node<LIST_T, NODE_T>;
111 public:
112  jit_internal_list (void) : use_head (0), use_tail (0), muse_count (0) { }
113 
114  virtual ~jit_internal_list (void)
115  {
116  while (use_head)
117  use_head->stash_value (0);
118  }
119 
120  NODE_T *first_use (void) const { return use_head; }
121 
122  size_t use_count (void) const { return muse_count; }
123 private:
124  NODE_T *use_head;
125  NODE_T *use_tail;
126  size_t muse_count;
127 };
128 
129 // a node for internal linked lists
130 template <typename LIST_T, typename NODE_T>
131 class
133 {
134 public:
136 
137  jit_internal_node (void) : mvalue (0), mnext (0), mprev (0) { }
138 
139  ~jit_internal_node (void) { remove (); }
140 
141  LIST_T *value (void) const { return mvalue; }
142 
143  void stash_value (LIST_T *avalue)
144  {
145  remove ();
146 
147  mvalue = avalue;
148 
149  if (mvalue)
150  {
151  jit_ilist *ilist = mvalue;
152  NODE_T *sthis = static_cast<NODE_T *> (this);
153  if (ilist->use_head)
154  {
155  ilist->use_tail->mnext = sthis;
156  mprev = ilist->use_tail;
157  }
158  else
159  ilist->use_head = sthis;
160 
161  ilist->use_tail = sthis;
162  ++ilist->muse_count;
163  }
164  }
165 
166  NODE_T *next (void) const { return mnext; }
167 
168  NODE_T *prev (void) const { return mprev; }
169 private:
170  void remove ()
171  {
172  if (mvalue)
173  {
174  jit_ilist *ilist = mvalue;
175  if (mprev)
176  mprev->mnext = mnext;
177  else
178  // we are the use_head
179  ilist->use_head = mnext;
180 
181  if (mnext)
182  mnext->mprev = mprev;
183  else
184  // we are the use tail
185  ilist->use_tail = mprev;
186 
187  mnext = mprev = 0;
188  --ilist->muse_count;
189  mvalue = 0;
190  }
191  }
192 
193  LIST_T *mvalue;
194  NODE_T *mnext;
195  NODE_T *mprev;
196 };
197 
198 // Use like: isa<jit_phi> (value)
199 // basically just a short cut type typing dyanmic_cast.
200 template <typename T, typename U>
201 bool isa (U *value)
202 {
203  return dynamic_cast<T *> (value);
204 }
205 
206 #define JIT_ASSIGN_ARG(i) the_args[i] = arg ## i;
207 #define JIT_EXPAND(ret, fname, type, isconst, N) \
208  ret fname (JIT_PARAM_ARGS OCT_MAKE_DECL_LIST (type, arg, N)) isconst \
209  { \
210  std::vector<type> the_args (N); \
211  OCT_ITERATE_MACRO (JIT_ASSIGN_ARG, N); \
212  return fname (JIT_PARAMS the_args); \
213  }
214 
215 #endif
216 #endif
std::ostream & operator<<(std::ostream &os, const llvm::Value &v)
Definition: jit-util.cc:44
Definition: jit-util.h:41
LIST_T * mvalue
Definition: jit-util.h:193
jit_internal_node(void)
Definition: jit-util.h:137
STL namespace.
NODE_T * mprev
Definition: jit-util.h:195
void stash_value(LIST_T *avalue)
Definition: jit-util.h:143
bool known(void) const
Definition: jit-util.h:92
NODE_T * use_tail
Definition: jit-util.h:125
jit_fail_exception(void)
Definition: jit-util.h:87
NODE_T * use_head
Definition: jit-util.h:124
jit_internal_list(void)
Definition: jit-util.h:112
bool isa(U *value)
Definition: jit-util.h:201
jit_internal_list< LIST_T, NODE_T > jit_ilist
Definition: jit-util.h:135
NODE_T * mnext
Definition: jit-util.h:194
LIST_T * value(void) const
Definition: jit-util.h:141
size_t use_count(void) const
Definition: jit-util.h:122
NODE_T * first_use(void) const
Definition: jit-util.h:120
Definition: pt.h:35
~jit_internal_node(void)
Definition: jit-util.h:139
NODE_T * prev(void) const
Definition: jit-util.h:168
size_t muse_count
Definition: jit-util.h:126
NODE_T * next(void) const
Definition: jit-util.h:166
jit_fail_exception(const std::string &reason)
Definition: jit-util.h:88
IRBuilder< true, ConstantFolder, IRBuilderDefaultInserter< true > > IRBuilderD
Definition: jit-util.h:71
virtual ~jit_internal_list(void)
Definition: jit-util.h:114