Mercurial > octave-nkf
annotate libinterp/corefcn/jit-ir.h @ 20654:b65888ec820e draft default tip gccjit
dmalcom gcc jit import
author | Stefan Mahr <dac922@gmx.de> |
---|---|
date | Fri, 27 Feb 2015 16:59:36 +0100 |
parents | 1f9ed81bd173 |
children |
rev | line source |
---|---|
15016 | 1 /* |
2 | |
19731
4197fc428c7d
maint: Update copyright notices for 2015.
John W. Eaton <jwe@octave.org>
parents:
17787
diff
changeset
|
3 Copyright (C) 2012-2015 Max Brister |
15016 | 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 | |
16768 | 23 // Author: Max Brister <max@2bass.com> |
24 | |
15016 | 25 #if !defined (octave_jit_ir_h) |
26 #define octave_jit_ir_h 1 | |
27 | |
20654 | 28 #ifdef HAVE_JIT |
15016 | 29 |
30 #include <list> | |
31 #include <stack> | |
32 #include <set> | |
33 | |
34 #include "jit-typeinfo.h" | |
35 | |
36 // The low level octave jit ir | |
37 // this ir is close to llvm, but contains information for doing type inference. | |
38 // We convert the octave parse tree to this IR directly. | |
39 | |
40 #define JIT_VISIT_IR_NOTEMPLATE \ | |
41 JIT_METH(block); \ | |
42 JIT_METH(branch); \ | |
43 JIT_METH(cond_branch); \ | |
44 JIT_METH(call); \ | |
45 JIT_METH(extract_argument); \ | |
46 JIT_METH(store_argument); \ | |
15337
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
47 JIT_METH(return); \ |
15016 | 48 JIT_METH(phi); \ |
49 JIT_METH(variable); \ | |
50 JIT_METH(error_check); \ | |
51 JIT_METH(assign) \ | |
15056
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
52 JIT_METH(argument) \ |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
53 JIT_METH(magic_end) |
15016 | 54 |
55 #define JIT_VISIT_IR_CONST \ | |
56 JIT_METH(const_bool); \ | |
57 JIT_METH(const_scalar); \ | |
58 JIT_METH(const_complex); \ | |
59 JIT_METH(const_index); \ | |
60 JIT_METH(const_string); \ | |
61 JIT_METH(const_range) | |
62 | |
63 #define JIT_VISIT_IR_CLASSES \ | |
64 JIT_VISIT_IR_NOTEMPLATE \ | |
65 JIT_VISIT_IR_CONST | |
66 | |
67 // forward declare all ir classes | |
68 #define JIT_METH(cname) \ | |
69 class jit_ ## cname; | |
70 | |
71 JIT_VISIT_IR_NOTEMPLATE | |
72 | |
73 #undef JIT_METH | |
74 | |
75 // ABCs which aren't included in JIT_VISIT_IR_ALL | |
76 class jit_instruction; | |
77 class jit_terminator; | |
78 | |
79 template <typename T, jit_type *(*EXTRACT_T)(void), typename PASS_T = T, | |
80 bool QUOTE=false> | |
81 class jit_const; | |
82 | |
83 typedef jit_const<bool, jit_typeinfo::get_bool> jit_const_bool; | |
84 typedef jit_const<double, jit_typeinfo::get_scalar> jit_const_scalar; | |
85 typedef jit_const<Complex, jit_typeinfo::get_complex> jit_const_complex; | |
86 typedef jit_const<octave_idx_type, jit_typeinfo::get_index> jit_const_index; | |
87 | |
88 typedef jit_const<std::string, jit_typeinfo::get_string, const std::string&, | |
89 true> jit_const_string; | |
90 typedef jit_const<jit_range, jit_typeinfo::get_range, const jit_range&> | |
91 jit_const_range; | |
92 | |
93 class jit_ir_walker; | |
94 class jit_use; | |
95 | |
15182
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
96 // Creates and tracks memory for jit_value and subclasses. |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
97 // Memory managment is simple, all values that are created live as long as the |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
98 // factory. |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
99 class |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
100 jit_factory |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
101 { |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
102 typedef std::list<jit_value *> value_list; |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
103 public: |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
104 ~jit_factory (void); |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
105 |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
106 const value_list& constants (void) const { return mconstants; } |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
107 |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
108 template <typename T> |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
109 T *create (void) |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
110 { |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
111 T *ret = new T (); |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
112 track_value (ret); |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
113 return ret; |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
114 } |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
115 |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
116 #define DECL_ARG(n) const ARG ## n& arg ## n |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
117 #define JIT_CREATE(N) \ |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
118 template <typename T, OCT_MAKE_DECL_LIST (typename, ARG, N)> \ |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
119 T *create (OCT_MAKE_LIST (DECL_ARG, N)) \ |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
120 { \ |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
121 T *ret = new T (OCT_MAKE_ARG_LIST (arg, N)); \ |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
122 track_value (ret); \ |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
123 return ret; \ |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
124 } |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
125 |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
126 JIT_CREATE (1) |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
127 JIT_CREATE (2) |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
128 JIT_CREATE (3) |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
129 JIT_CREATE (4) |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
130 |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
131 #undef JIT_CREATE |
15191
ed4f4fb78586
Move type inference from jit_convert to jit_infer
Max Brister <max@2bass.com>
parents:
15182
diff
changeset
|
132 #undef DECL_ARG |
15182
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
133 private: |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
134 void track_value (jit_value *v); |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
135 |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
136 value_list all_values; |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
137 |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
138 value_list mconstants; |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
139 }; |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
140 |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
141 // A list of basic blocks (jit_block) which form some body of code. |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
142 // |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
143 // We do not directly inherit from std::list because we need to update the |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
144 // blocks stashed location in push_back and insert. |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
145 class |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
146 jit_block_list |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
147 { |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
148 public: |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
149 typedef std::list<jit_block *>::iterator iterator; |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
150 typedef std::list<jit_block *>::const_iterator const_iterator; |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
151 |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
152 jit_block *back (void) const { return mlist.back (); } |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
153 |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
154 iterator begin (void) { return mlist.begin (); } |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
155 |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
156 const_iterator begin (void) const { return mlist.begin (); } |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
157 |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
158 iterator end (void) { return mlist.end (); } |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
159 |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
160 const_iterator end (void) const { return mlist.end (); } |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
161 |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
162 iterator erase (iterator iter) { return mlist.erase (iter); } |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
163 |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
164 jit_block *front (void) const { return mlist.front (); } |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
165 |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
166 void insert_after (iterator iter, jit_block *ablock); |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
167 |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
168 void insert_after (jit_block *loc, jit_block *ablock); |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
169 |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
170 void insert_before (iterator iter, jit_block *ablock); |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
171 |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
172 void insert_before (jit_block *loc, jit_block *ablock); |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
173 |
15602
f3e339aee38f
Fix block labeling in JIT debug output
Max Brister <max@2bass.com>
parents:
15594
diff
changeset
|
174 void label (void); |
f3e339aee38f
Fix block labeling in JIT debug output
Max Brister <max@2bass.com>
parents:
15594
diff
changeset
|
175 |
15191
ed4f4fb78586
Move type inference from jit_convert to jit_infer
Max Brister <max@2bass.com>
parents:
15182
diff
changeset
|
176 std::ostream& print (std::ostream& os, const std::string& header) const; |
ed4f4fb78586
Move type inference from jit_convert to jit_infer
Max Brister <max@2bass.com>
parents:
15182
diff
changeset
|
177 |
ed4f4fb78586
Move type inference from jit_convert to jit_infer
Max Brister <max@2bass.com>
parents:
15182
diff
changeset
|
178 std::ostream& print_dom (std::ostream& os) const; |
ed4f4fb78586
Move type inference from jit_convert to jit_infer
Max Brister <max@2bass.com>
parents:
15182
diff
changeset
|
179 |
15182
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
180 void push_back (jit_block *b); |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
181 private: |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
182 std::list<jit_block *> mlist; |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
183 }; |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
184 |
15191
ed4f4fb78586
Move type inference from jit_convert to jit_infer
Max Brister <max@2bass.com>
parents:
15182
diff
changeset
|
185 std::ostream& operator<<(std::ostream& os, const jit_block_list& blocks); |
ed4f4fb78586
Move type inference from jit_convert to jit_infer
Max Brister <max@2bass.com>
parents:
15182
diff
changeset
|
186 |
15016 | 187 class |
188 jit_value : public jit_internal_list<jit_value, jit_use> | |
189 { | |
190 public: | |
20654 | 191 jit_value (void) : llvm_value (0), |
192 #ifdef HAVE_GCCJIT | |
193 m_gcc_lvalue (), m_gcc_rvalue (), | |
194 #endif | |
195 ty (0), mlast_use (0), | |
15016 | 196 min_worklist (false) {} |
197 | |
198 virtual ~jit_value (void); | |
199 | |
200 bool in_worklist (void) const | |
201 { | |
202 return min_worklist; | |
203 } | |
204 | |
205 void stash_in_worklist (bool ain_worklist) | |
206 { | |
207 min_worklist = ain_worklist; | |
208 } | |
209 | |
210 // The block of the first use which is not a jit_error_check | |
211 // So this is not necessarily first_use ()->parent (). | |
212 jit_block *first_use_block (void); | |
213 | |
214 // replace all uses with | |
215 virtual void replace_with (jit_value *value); | |
216 | |
217 jit_type *type (void) const { return ty; } | |
218 | |
20654 | 219 #if HAVE_LLVM |
15016 | 220 llvm::Type *type_llvm (void) const |
221 { | |
222 return ty ? ty->to_llvm () : 0; | |
223 } | |
20654 | 224 #endif |
225 | |
226 #if HAVE_GCCJIT | |
227 gccjit::type type_gccjit (void) const | |
228 { | |
229 return ty ? ty->to_gccjit () : gccjit::type (); | |
230 } | |
231 #endif | |
15016 | 232 |
233 const std::string& type_name (void) const | |
234 { | |
235 return ty->name (); | |
236 } | |
237 | |
238 void stash_type (jit_type *new_ty) { ty = new_ty; } | |
239 | |
240 std::string print_string (void) | |
241 { | |
242 std::stringstream ss; | |
243 print (ss); | |
244 return ss.str (); | |
245 } | |
246 | |
247 jit_instruction *last_use (void) const { return mlast_use; } | |
248 | |
249 void stash_last_use (jit_instruction *alast_use) | |
250 { | |
251 mlast_use = alast_use; | |
252 } | |
253 | |
254 virtual bool needs_release (void) const { return false; } | |
255 | |
256 virtual std::ostream& print (std::ostream& os, size_t indent = 0) const = 0; | |
257 | |
258 virtual std::ostream& short_print (std::ostream& os) const | |
259 { return print (os); } | |
260 | |
261 virtual void accept (jit_ir_walker& walker) = 0; | |
262 | |
20654 | 263 #if HAVE_LLVM |
15016 | 264 bool has_llvm (void) const |
265 { | |
266 return llvm_value; | |
267 } | |
268 | |
269 llvm::Value *to_llvm (void) const | |
270 { | |
271 assert (llvm_value); | |
272 return llvm_value; | |
273 } | |
274 | |
275 void stash_llvm (llvm::Value *compiled) | |
276 { | |
277 llvm_value = compiled; | |
278 } | |
20654 | 279 #endif |
280 | |
281 #if HAVE_GCCJIT | |
282 bool has_lvalue (void) const | |
283 { | |
284 return m_gcc_lvalue.get_inner_lvalue (); | |
285 } | |
286 bool has_rvalue (void) const | |
287 { | |
288 return m_gcc_rvalue.get_inner_rvalue (); | |
289 } | |
290 gccjit::lvalue as_lvalue (void) const | |
291 { | |
292 return m_gcc_lvalue; | |
293 } | |
294 gccjit::rvalue as_rvalue (void) const | |
295 { | |
296 return m_gcc_rvalue; | |
297 } | |
298 void stash_lvalue (gccjit::lvalue lvalue) | |
299 { | |
300 m_gcc_lvalue = lvalue; | |
301 } | |
302 void stash_rvalue (gccjit::rvalue rvalue) | |
303 { | |
304 m_gcc_rvalue = rvalue; | |
305 } | |
306 #endif | |
15016 | 307 |
308 protected: | |
309 std::ostream& print_indent (std::ostream& os, size_t indent = 0) const | |
310 { | |
311 for (size_t i = 0; i < indent * 8; ++i) | |
312 os << " "; | |
313 return os; | |
314 } | |
315 | |
20654 | 316 #if HAVE_LLVM |
15016 | 317 llvm::Value *llvm_value; |
20654 | 318 #endif |
319 #if HAVE_GCCJIT | |
320 gccjit::lvalue m_gcc_lvalue; | |
321 gccjit::rvalue m_gcc_rvalue; | |
322 #endif | |
15016 | 323 private: |
324 jit_type *ty; | |
325 jit_instruction *mlast_use; | |
326 bool min_worklist; | |
327 }; | |
328 | |
329 std::ostream& operator<< (std::ostream& os, const jit_value& value); | |
330 std::ostream& jit_print (std::ostream& os, jit_value *avalue); | |
331 | |
332 class | |
333 jit_use : public jit_internal_node<jit_value, jit_use> | |
334 { | |
335 public: | |
15231
8442131a391a
jit-ir.h (jit_use::stash_value): Explicitly specify parent template types
Max Brister <max@2bass.com>
parents:
15195
diff
changeset
|
336 // some compilers don't allow us to use jit_internal_node without template |
8442131a391a
jit-ir.h (jit_use::stash_value): Explicitly specify parent template types
Max Brister <max@2bass.com>
parents:
15195
diff
changeset
|
337 // paremeters |
8442131a391a
jit-ir.h (jit_use::stash_value): Explicitly specify parent template types
Max Brister <max@2bass.com>
parents:
15195
diff
changeset
|
338 typedef jit_internal_node<jit_value, jit_use> PARENT_T; |
8442131a391a
jit-ir.h (jit_use::stash_value): Explicitly specify parent template types
Max Brister <max@2bass.com>
parents:
15195
diff
changeset
|
339 |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
340 jit_use (void) : muser (0), mindex (0) { } |
15016 | 341 |
342 // we should really have a move operator, but not until c++11 :( | |
343 jit_use (const jit_use& use) : muser (0), mindex (0) | |
344 { | |
345 *this = use; | |
346 } | |
347 | |
348 jit_use& operator= (const jit_use& use) | |
349 { | |
350 stash_value (use.value (), use.user (), use.index ()); | |
351 return *this; | |
352 } | |
353 | |
354 size_t index (void) const { return mindex; } | |
355 | |
356 jit_instruction *user (void) const { return muser; } | |
357 | |
358 jit_block *user_parent (void) const; | |
359 | |
360 std::list<jit_block *> user_parent_location (void) const; | |
361 | |
362 void stash_value (jit_value *avalue, jit_instruction *auser = 0, | |
363 size_t aindex = -1) | |
364 { | |
15231
8442131a391a
jit-ir.h (jit_use::stash_value): Explicitly specify parent template types
Max Brister <max@2bass.com>
parents:
15195
diff
changeset
|
365 PARENT_T::stash_value (avalue); |
15016 | 366 mindex = aindex; |
367 muser = auser; | |
368 } | |
369 private: | |
370 jit_instruction *muser; | |
371 size_t mindex; | |
372 }; | |
373 | |
374 class | |
375 jit_instruction : public jit_value | |
376 { | |
377 public: | |
378 // FIXME: this code could be so much pretier with varadic templates... | |
379 jit_instruction (void) : mid (next_id ()), mparent (0) | |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
380 { } |
15016 | 381 |
382 jit_instruction (size_t nargs) : mid (next_id ()), mparent (0) | |
383 { | |
384 already_infered.reserve (nargs); | |
385 marguments.reserve (nargs); | |
386 } | |
387 | |
388 #define STASH_ARG(i) stash_argument (i, arg ## i); | |
389 #define JIT_INSTRUCTION_CTOR(N) \ | |
390 jit_instruction (OCT_MAKE_DECL_LIST (jit_value *, arg, N)) \ | |
391 : already_infered (N), marguments (N), mid (next_id ()), mparent (0) \ | |
392 { \ | |
393 OCT_ITERATE_MACRO (STASH_ARG, N); \ | |
394 } | |
395 | |
396 JIT_INSTRUCTION_CTOR(1) | |
397 JIT_INSTRUCTION_CTOR(2) | |
398 JIT_INSTRUCTION_CTOR(3) | |
399 JIT_INSTRUCTION_CTOR(4) | |
400 | |
401 #undef STASH_ARG | |
402 #undef JIT_INSTRUCTION_CTOR | |
403 | |
15056
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
404 jit_instruction (const std::vector<jit_value *>& aarguments) |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
405 : already_infered (aarguments.size ()), marguments (aarguments.size ()), |
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
406 mid (next_id ()), mparent (0) |
15056
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
407 { |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
408 for (size_t i = 0; i < aarguments.size (); ++i) |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
409 stash_argument (i, aarguments[i]); |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
410 } |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
411 |
15016 | 412 static void reset_ids (void) |
413 { | |
414 next_id (true); | |
415 } | |
416 | |
417 jit_value *argument (size_t i) const | |
418 { | |
419 return marguments[i].value (); | |
420 } | |
421 | |
20654 | 422 #if HAVE_LLVM |
15016 | 423 llvm::Value *argument_llvm (size_t i) const |
424 { | |
425 assert (argument (i)); | |
426 return argument (i)->to_llvm (); | |
427 } | |
20654 | 428 #endif |
15016 | 429 |
430 jit_type *argument_type (size_t i) const | |
431 { | |
432 return argument (i)->type (); | |
433 } | |
434 | |
20654 | 435 #if HAVE_LLVM |
15016 | 436 llvm::Type *argument_type_llvm (size_t i) const |
437 { | |
438 assert (argument (i)); | |
439 return argument_type (i)->to_llvm (); | |
440 } | |
20654 | 441 #endif |
15016 | 442 |
443 std::ostream& print_argument (std::ostream& os, size_t i) const | |
444 { | |
445 if (argument (i)) | |
446 return argument (i)->short_print (os); | |
447 else | |
448 return os << "NULL"; | |
449 } | |
450 | |
451 void stash_argument (size_t i, jit_value *arg) | |
452 { | |
453 marguments[i].stash_value (arg, this, i); | |
454 } | |
455 | |
456 void push_argument (jit_value *arg) | |
457 { | |
458 marguments.push_back (jit_use ()); | |
459 stash_argument (marguments.size () - 1, arg); | |
460 already_infered.push_back (0); | |
461 } | |
462 | |
463 size_t argument_count (void) const | |
464 { | |
465 return marguments.size (); | |
466 } | |
467 | |
468 void resize_arguments (size_t acount, jit_value *adefault = 0) | |
469 { | |
470 size_t old = marguments.size (); | |
471 marguments.resize (acount); | |
472 already_infered.resize (acount); | |
473 | |
474 if (adefault) | |
475 for (size_t i = old; i < acount; ++i) | |
476 stash_argument (i, adefault); | |
477 } | |
478 | |
479 const std::vector<jit_use>& arguments (void) const { return marguments; } | |
480 | |
481 // argument types which have been infered already | |
482 const std::vector<jit_type *>& argument_types (void) const | |
483 { return already_infered; } | |
484 | |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
485 virtual void push_variable (void) { } |
15016 | 486 |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
487 virtual void pop_variable (void) { } |
15016 | 488 |
489 virtual void construct_ssa (void) | |
490 { | |
491 do_construct_ssa (0, argument_count ()); | |
492 } | |
493 | |
494 virtual bool infer (void) { return false; } | |
495 | |
496 void remove (void); | |
497 | |
498 virtual std::ostream& short_print (std::ostream& os) const; | |
499 | |
500 jit_block *parent (void) const { return mparent; } | |
501 | |
502 std::list<jit_instruction *>::iterator location (void) const | |
503 { | |
504 return mlocation; | |
505 } | |
506 | |
20654 | 507 #if HAVE_LLVM |
15016 | 508 llvm::BasicBlock *parent_llvm (void) const; |
20654 | 509 #endif |
15016 | 510 |
511 void stash_parent (jit_block *aparent, | |
512 std::list<jit_instruction *>::iterator alocation) | |
513 { | |
514 mparent = aparent; | |
515 mlocation = alocation; | |
516 } | |
517 | |
518 size_t id (void) const { return mid; } | |
519 protected: | |
520 | |
521 // Do SSA replacement on arguments in [start, end) | |
522 void do_construct_ssa (size_t start, size_t end); | |
523 | |
524 std::vector<jit_type *> already_infered; | |
525 private: | |
526 static size_t next_id (bool reset = false) | |
527 { | |
528 static size_t ret = 0; | |
529 if (reset) | |
530 return ret = 0; | |
531 | |
532 return ret++; | |
533 } | |
534 | |
535 std::vector<jit_use> marguments; | |
536 | |
537 size_t mid; | |
538 jit_block *mparent; | |
539 std::list<jit_instruction *>::iterator mlocation; | |
540 }; | |
541 | |
542 // defnie accept methods for subclasses | |
543 #define JIT_VALUE_ACCEPT \ | |
544 virtual void accept (jit_ir_walker& walker); | |
545 | |
546 // for use as a dummy argument during conversion to LLVM | |
547 class | |
548 jit_argument : public jit_value | |
549 { | |
550 public: | |
20654 | 551 jit_argument (jit_type *atype/*, llvm::Value *avalue*/) |
15016 | 552 { |
553 stash_type (atype); | |
20654 | 554 //stash_llvm (avalue); |
15016 | 555 } |
556 | |
557 virtual std::ostream& print (std::ostream& os, size_t indent = 0) const | |
558 { | |
559 print_indent (os, indent); | |
560 return jit_print (os, type ()) << ": DUMMY"; | |
561 } | |
562 | |
563 JIT_VALUE_ACCEPT; | |
564 }; | |
565 | |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
566 template <typename T, jit_type *(*EXTRACT_T)(void), typename PASS_T, bool QUOTE> |
15016 | 567 class |
568 jit_const : public jit_value | |
569 { | |
570 public: | |
571 typedef PASS_T pass_t; | |
572 | |
573 jit_const (PASS_T avalue) : mvalue (avalue) | |
574 { | |
575 stash_type (EXTRACT_T ()); | |
576 } | |
577 | |
578 PASS_T value (void) const { return mvalue; } | |
579 | |
580 virtual std::ostream& print (std::ostream& os, size_t indent = 0) const | |
581 { | |
582 print_indent (os, indent); | |
583 jit_print (os, type ()) << ": "; | |
584 if (QUOTE) | |
585 os << "\""; | |
586 os << mvalue; | |
587 if (QUOTE) | |
588 os << "\""; | |
589 return os; | |
590 } | |
591 | |
592 JIT_VALUE_ACCEPT; | |
593 private: | |
594 T mvalue; | |
595 }; | |
596 | |
597 class jit_phi_incomming; | |
598 | |
599 class | |
600 jit_block : public jit_value, public jit_internal_list<jit_block, | |
601 jit_phi_incomming> | |
602 { | |
603 typedef jit_internal_list<jit_block, jit_phi_incomming> ILIST_T; | |
604 public: | |
605 typedef std::list<jit_instruction *> instruction_list; | |
606 typedef instruction_list::iterator iterator; | |
607 typedef instruction_list::const_iterator const_iterator; | |
608 | |
609 typedef std::set<jit_block *> df_set; | |
610 typedef df_set::const_iterator df_iterator; | |
611 | |
612 static const size_t NO_ID = static_cast<size_t> (-1); | |
613 | |
614 jit_block (const std::string& aname, size_t avisit_count = 0) | |
615 : mvisit_count (avisit_count), mid (NO_ID), idom (0), mname (aname), | |
616 malive (false) | |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
617 { } |
15016 | 618 |
619 virtual void replace_with (jit_value *value); | |
620 | |
621 void replace_in_phi (jit_block *ablock, jit_block *with); | |
622 | |
20132
1f9ed81bd173
maint: Fix spelling and grammar mistakes in docs and comments (bug #44878)
Rafael Laboissiere <rafael@laboissiere.net>
parents:
19731
diff
changeset
|
623 // we have a new internal list, but we want to stay compatible with jit_value |
15016 | 624 jit_use *first_use (void) const { return jit_value::first_use (); } |
625 | |
626 size_t use_count (void) const { return jit_value::use_count (); } | |
627 | |
628 // if a block is alive, then it might be visited during execution | |
629 bool alive (void) const { return malive; } | |
630 | |
631 void mark_alive (void) { malive = true; } | |
632 | |
633 // If we can merge with a successor, do so and return the now empty block | |
634 jit_block *maybe_merge (); | |
635 | |
636 // merge another block into this block, leaving the merge block empty | |
637 void merge (jit_block& merge); | |
638 | |
639 const std::string& name (void) const { return mname; } | |
640 | |
20654 | 641 std::string name_and_id (void) const |
642 { | |
643 std::ostringstream os; | |
644 short_print (os); | |
645 return os.str (); | |
646 } | |
647 | |
15016 | 648 jit_instruction *prepend (jit_instruction *instr); |
649 | |
650 jit_instruction *prepend_after_phi (jit_instruction *instr); | |
651 | |
652 template <typename T> | |
653 T *append (T *instr) | |
654 { | |
655 internal_append (instr); | |
656 return instr; | |
657 } | |
658 | |
659 jit_instruction *insert_before (iterator loc, jit_instruction *instr); | |
660 | |
661 jit_instruction *insert_before (jit_instruction *loc, jit_instruction *instr) | |
662 { | |
663 return insert_before (loc->location (), instr); | |
664 } | |
665 | |
666 jit_instruction *insert_after (iterator loc, jit_instruction *instr); | |
667 | |
668 jit_instruction *insert_after (jit_instruction *loc, jit_instruction *instr) | |
669 { | |
670 return insert_after (loc->location (), instr); | |
671 } | |
672 | |
673 iterator remove (iterator iter) | |
674 { | |
675 jit_instruction *instr = *iter; | |
676 iter = instructions.erase (iter); | |
677 instr->stash_parent (0, instructions.end ()); | |
678 return iter; | |
679 } | |
680 | |
681 jit_terminator *terminator (void) const; | |
682 | |
683 // is the jump from pred alive? | |
684 bool branch_alive (jit_block *asucc) const; | |
685 | |
686 jit_block *successor (size_t i) const; | |
687 | |
688 size_t successor_count (void) const; | |
689 | |
690 iterator begin (void) { return instructions.begin (); } | |
691 | |
692 const_iterator begin (void) const { return instructions.begin (); } | |
693 | |
694 iterator end (void) { return instructions.end (); } | |
695 | |
696 const_iterator end (void) const { return instructions.end (); } | |
697 | |
698 iterator phi_begin (void); | |
699 | |
700 iterator phi_end (void); | |
701 | |
702 iterator nonphi_begin (void); | |
703 | |
704 // must label before id is valid | |
705 size_t id (void) const { return mid; } | |
706 | |
707 // dominance frontier | |
708 const df_set& df (void) const { return mdf; } | |
709 | |
710 df_iterator df_begin (void) const { return mdf.begin (); } | |
711 | |
712 df_iterator df_end (void) const { return mdf.end (); } | |
713 | |
714 // label with a RPO walk | |
715 void label (void) | |
716 { | |
717 size_t number = 0; | |
718 label (mvisit_count, number); | |
719 } | |
720 | |
15602
f3e339aee38f
Fix block labeling in JIT debug output
Max Brister <max@2bass.com>
parents:
15594
diff
changeset
|
721 void label (size_t avisit_count, size_t& number); |
15016 | 722 |
723 // See for idom computation algorithm | |
724 // Cooper, Keith D.; Harvey, Timothy J; and Kennedy, Ken (2001). | |
725 // "A Simple, Fast Dominance Algorithm" | |
15191
ed4f4fb78586
Move type inference from jit_convert to jit_infer
Max Brister <max@2bass.com>
parents:
15182
diff
changeset
|
726 void compute_idom (jit_block& entry_block) |
15016 | 727 { |
728 bool changed; | |
15191
ed4f4fb78586
Move type inference from jit_convert to jit_infer
Max Brister <max@2bass.com>
parents:
15182
diff
changeset
|
729 entry_block.idom = &entry_block; |
15016 | 730 do |
731 changed = update_idom (mvisit_count); | |
732 while (changed); | |
733 } | |
734 | |
735 // compute dominance frontier | |
736 void compute_df (void) | |
737 { | |
738 compute_df (mvisit_count); | |
739 } | |
740 | |
741 void create_dom_tree (void) | |
742 { | |
743 create_dom_tree (mvisit_count); | |
744 } | |
745 | |
746 jit_block *dom_successor (size_t idx) const | |
747 { | |
748 return dom_succ[idx]; | |
749 } | |
750 | |
751 size_t dom_successor_count (void) const | |
752 { | |
753 return dom_succ.size (); | |
754 } | |
755 | |
756 // call pop_varaible on all instructions | |
757 void pop_all (void); | |
758 | |
15602
f3e339aee38f
Fix block labeling in JIT debug output
Max Brister <max@2bass.com>
parents:
15594
diff
changeset
|
759 virtual std::ostream& print (std::ostream& os, size_t indent = 0) const; |
15016 | 760 |
15182
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
761 jit_block *maybe_split (jit_factory& factory, jit_block_list& blocks, |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
762 jit_block *asuccessor); |
15016 | 763 |
15182
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
764 jit_block *maybe_split (jit_factory& factory, jit_block_list& blocks, |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
765 jit_block& asuccessor) |
15016 | 766 { |
15182
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
767 return maybe_split (factory, blocks, &asuccessor); |
15016 | 768 } |
769 | |
770 // print dominator infomration | |
771 std::ostream& print_dom (std::ostream& os) const; | |
772 | |
773 virtual std::ostream& short_print (std::ostream& os) const | |
774 { | |
775 os << mname; | |
776 if (mid != NO_ID) | |
777 os << mid; | |
15602
f3e339aee38f
Fix block labeling in JIT debug output
Max Brister <max@2bass.com>
parents:
15594
diff
changeset
|
778 else |
f3e339aee38f
Fix block labeling in JIT debug output
Max Brister <max@2bass.com>
parents:
15594
diff
changeset
|
779 os << "!"; |
15016 | 780 return os; |
781 } | |
782 | |
20654 | 783 #if HAVE_LLVM |
15016 | 784 llvm::BasicBlock *to_llvm (void) const; |
20654 | 785 #endif |
15016 | 786 |
787 std::list<jit_block *>::iterator location (void) const | |
788 { return mlocation; } | |
789 | |
790 void stash_location (std::list<jit_block *>::iterator alocation) | |
791 { mlocation = alocation; } | |
792 | |
793 // used to prevent visiting the same node twice in the graph | |
794 size_t visit_count (void) const { return mvisit_count; } | |
795 | |
796 // check if this node has been visited yet at the given visit count. If we | |
797 // have not been visited yet, mark us as visited. | |
798 bool visited (size_t avisit_count) | |
799 { | |
800 if (mvisit_count <= avisit_count) | |
801 { | |
802 mvisit_count = avisit_count + 1; | |
803 return false; | |
804 } | |
805 | |
806 return true; | |
807 } | |
808 | |
15337
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
809 jit_instruction *front (void) { return instructions.front (); } |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
810 |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
811 jit_instruction *back (void) { return instructions.back (); } |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
812 |
15016 | 813 JIT_VALUE_ACCEPT; |
814 private: | |
815 void internal_append (jit_instruction *instr); | |
816 | |
817 void compute_df (size_t avisit_count); | |
818 | |
819 bool update_idom (size_t avisit_count); | |
820 | |
821 void create_dom_tree (size_t avisit_count); | |
822 | |
823 static jit_block *idom_intersect (jit_block *i, jit_block *j); | |
824 | |
825 size_t mvisit_count; | |
826 size_t mid; | |
827 jit_block *idom; | |
828 df_set mdf; | |
829 std::vector<jit_block *> dom_succ; | |
830 std::string mname; | |
831 instruction_list instructions; | |
832 bool malive; | |
833 std::list<jit_block *>::iterator mlocation; | |
834 }; | |
835 | |
836 // keeps track of phi functions that use a block on incomming edges | |
837 class | |
838 jit_phi_incomming : public jit_internal_node<jit_block, jit_phi_incomming> | |
839 { | |
840 public: | |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
841 jit_phi_incomming (void) : muser (0) { } |
15016 | 842 |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
843 jit_phi_incomming (jit_phi *auser) : muser (auser) { } |
15016 | 844 |
15232
2c0259dc1a82
jit-ir.h (jit_phi_incomming::jit_phi_incomming): Remove extraneous parent initialization
Max Brister <max@2bass.com>
parents:
15231
diff
changeset
|
845 jit_phi_incomming (const jit_phi_incomming& use) |
15016 | 846 { |
847 *this = use; | |
848 } | |
849 | |
850 jit_phi_incomming& operator= (const jit_phi_incomming& use) | |
851 { | |
852 stash_value (use.value ()); | |
853 muser = use.muser; | |
854 return *this; | |
855 } | |
856 | |
857 jit_phi *user (void) const { return muser; } | |
858 | |
859 jit_block *user_parent (void) const; | |
860 private: | |
861 jit_phi *muser; | |
862 }; | |
863 | |
864 // A non-ssa variable | |
865 class | |
866 jit_variable : public jit_value | |
867 { | |
868 public: | |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
869 jit_variable (const std::string& aname) : mname (aname), mlast_use (0) { } |
15016 | 870 |
871 const std::string &name (void) const { return mname; } | |
872 | |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
873 // manipulate the value_stack, for use during SSA construction. The top of |
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
874 // the value stack represents the current value for this variable |
15016 | 875 bool has_top (void) const |
876 { | |
877 return ! value_stack.empty (); | |
878 } | |
879 | |
880 jit_value *top (void) const | |
881 { | |
882 return value_stack.top (); | |
883 } | |
884 | |
885 void push (jit_instruction *v) | |
886 { | |
887 value_stack.push (v); | |
888 mlast_use = v; | |
889 } | |
890 | |
891 void pop (void) | |
892 { | |
893 value_stack.pop (); | |
894 } | |
895 | |
896 jit_instruction *last_use (void) const | |
897 { | |
898 return mlast_use; | |
899 } | |
900 | |
901 void stash_last_use (jit_instruction *instr) | |
902 { | |
903 mlast_use = instr; | |
904 } | |
905 | |
906 // blocks in which we are used | |
907 void use_blocks (jit_block::df_set& result) | |
908 { | |
909 jit_use *use = first_use (); | |
910 while (use) | |
911 { | |
912 result.insert (use->user_parent ()); | |
913 use = use->next (); | |
914 } | |
915 } | |
916 | |
917 virtual std::ostream& print (std::ostream& os, size_t indent = 0) const | |
918 { | |
919 return print_indent (os, indent) << mname; | |
920 } | |
921 | |
922 JIT_VALUE_ACCEPT; | |
923 private: | |
924 std::string mname; | |
925 std::stack<jit_value *> value_stack; | |
926 jit_instruction *mlast_use; | |
927 }; | |
928 | |
929 class | |
930 jit_assign_base : public jit_instruction | |
931 { | |
932 public: | |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
933 jit_assign_base (jit_variable *adest) : jit_instruction (), mdest (adest) { } |
15016 | 934 |
935 jit_assign_base (jit_variable *adest, size_t npred) : jit_instruction (npred), | |
936 mdest (adest) {} | |
937 | |
938 jit_assign_base (jit_variable *adest, jit_value *arg0, jit_value *arg1) | |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
939 : jit_instruction (arg0, arg1), mdest (adest) { } |
15016 | 940 |
941 jit_variable *dest (void) const { return mdest; } | |
942 | |
943 virtual void push_variable (void) | |
944 { | |
945 mdest->push (this); | |
946 } | |
947 | |
948 virtual void pop_variable (void) | |
949 { | |
950 mdest->pop (); | |
951 } | |
952 | |
953 virtual std::ostream& short_print (std::ostream& os) const | |
954 { | |
955 if (type ()) | |
956 jit_print (os, type ()) << ": "; | |
957 | |
958 dest ()->short_print (os); | |
959 return os << "#" << id (); | |
960 } | |
961 private: | |
962 jit_variable *mdest; | |
963 }; | |
964 | |
965 class | |
966 jit_assign : public jit_assign_base | |
967 { | |
968 public: | |
969 jit_assign (jit_variable *adest, jit_value *asrc) | |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
970 : jit_assign_base (adest, adest, asrc), martificial (false) { } |
15016 | 971 |
972 jit_value *overwrite (void) const | |
973 { | |
974 return argument (0); | |
975 } | |
976 | |
977 jit_value *src (void) const | |
978 { | |
979 return argument (1); | |
980 } | |
981 | |
982 // variables don't get modified in an SSA, but COW requires we modify | |
983 // variables. An artificial assign is for when a variable gets modified. We | |
984 // need an assign in the SSA, but the reference counts shouldn't be updated. | |
985 bool artificial (void) const { return martificial; } | |
986 | |
987 void mark_artificial (void) { martificial = true; } | |
988 | |
989 virtual bool infer (void) | |
990 { | |
991 jit_type *stype = src ()->type (); | |
992 if (stype != type()) | |
993 { | |
994 stash_type (stype); | |
995 return true; | |
996 } | |
997 | |
998 return false; | |
999 } | |
1000 | |
1001 virtual std::ostream& print (std::ostream& os, size_t indent = 0) const | |
1002 { | |
1003 print_indent (os, indent) << *this << " = " << *src (); | |
1004 | |
1005 if (artificial ()) | |
1006 os << " [artificial]"; | |
1007 | |
1008 return os; | |
1009 } | |
1010 | |
1011 JIT_VALUE_ACCEPT; | |
1012 private: | |
1013 bool martificial; | |
1014 }; | |
1015 | |
1016 class | |
1017 jit_phi : public jit_assign_base | |
1018 { | |
1019 public: | |
1020 jit_phi (jit_variable *adest, size_t npred) | |
1021 : jit_assign_base (adest, npred) | |
1022 { | |
1023 mincomming.reserve (npred); | |
1024 } | |
1025 | |
1026 // removes arguments form dead incomming jumps | |
1027 bool prune (void); | |
1028 | |
1029 void add_incomming (jit_block *from, jit_value *value) | |
1030 { | |
1031 push_argument (value); | |
1032 mincomming.push_back (jit_phi_incomming (this)); | |
1033 mincomming[mincomming.size () - 1].stash_value (from); | |
1034 } | |
1035 | |
1036 jit_block *incomming (size_t i) const | |
1037 { | |
1038 return mincomming[i].value (); | |
1039 } | |
1040 | |
20654 | 1041 #if HAVE_LLVM |
15016 | 1042 llvm::BasicBlock *incomming_llvm (size_t i) const |
1043 { | |
1044 return incomming (i)->to_llvm (); | |
1045 } | |
20654 | 1046 #endif |
15016 | 1047 |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
1048 virtual void construct_ssa (void) { } |
15016 | 1049 |
1050 virtual bool infer (void); | |
1051 | |
1052 virtual std::ostream& print (std::ostream& os, size_t indent = 0) const | |
1053 { | |
1054 std::stringstream ss; | |
1055 print_indent (ss, indent); | |
1056 short_print (ss) << " phi "; | |
1057 std::string ss_str = ss.str (); | |
1058 std::string indent_str (ss_str.size (), ' '); | |
1059 os << ss_str; | |
1060 | |
1061 for (size_t i = 0; i < argument_count (); ++i) | |
1062 { | |
1063 if (i > 0) | |
1064 os << indent_str; | |
1065 os << "| "; | |
1066 | |
1067 os << *incomming (i) << " -> "; | |
1068 os << *argument (i); | |
1069 | |
1070 if (i + 1 < argument_count ()) | |
1071 os << std::endl; | |
1072 } | |
1073 | |
1074 return os; | |
1075 } | |
1076 | |
20654 | 1077 #if HAVE_LLVM |
15016 | 1078 llvm::PHINode *to_llvm (void) const; |
20654 | 1079 #endif |
15016 | 1080 |
1081 JIT_VALUE_ACCEPT; | |
1082 private: | |
1083 std::vector<jit_phi_incomming> mincomming; | |
1084 }; | |
1085 | |
1086 class | |
1087 jit_terminator : public jit_instruction | |
1088 { | |
1089 public: | |
1090 #define JIT_TERMINATOR_CONST(N) \ | |
1091 jit_terminator (size_t asuccessor_count, \ | |
1092 OCT_MAKE_DECL_LIST (jit_value *, arg, N)) \ | |
1093 : jit_instruction (OCT_MAKE_ARG_LIST (arg, N)), \ | |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
1094 malive (asuccessor_count, false) { } |
15016 | 1095 |
1096 JIT_TERMINATOR_CONST (1) | |
1097 JIT_TERMINATOR_CONST (2) | |
1098 JIT_TERMINATOR_CONST (3) | |
1099 | |
1100 #undef JIT_TERMINATOR_CONST | |
1101 | |
1102 jit_block *successor (size_t idx = 0) const | |
1103 { | |
1104 return static_cast<jit_block *> (argument (idx)); | |
1105 } | |
1106 | |
20654 | 1107 #if HAVE_LLVM |
15016 | 1108 llvm::BasicBlock *successor_llvm (size_t idx = 0) const |
1109 { | |
1110 return successor (idx)->to_llvm (); | |
1111 } | |
20654 | 1112 #endif |
15016 | 1113 |
1114 size_t successor_index (const jit_block *asuccessor) const; | |
1115 | |
1116 std::ostream& print_successor (std::ostream& os, size_t idx = 0) const | |
1117 { | |
1118 if (alive (idx)) | |
1119 os << "[live] "; | |
1120 else | |
1121 os << "[dead] "; | |
1122 | |
1123 return successor (idx)->short_print (os); | |
1124 } | |
1125 | |
1126 // Check if the jump to successor is live | |
1127 bool alive (const jit_block *asuccessor) const | |
1128 { | |
1129 return alive (successor_index (asuccessor)); | |
1130 } | |
1131 | |
1132 bool alive (size_t idx) const { return malive[idx]; } | |
1133 | |
1134 bool alive (int idx) const { return malive[idx]; } | |
1135 | |
1136 size_t successor_count (void) const { return malive.size (); } | |
1137 | |
1138 virtual bool infer (void); | |
1139 | |
20654 | 1140 #if HAVE_LLVM |
15016 | 1141 llvm::TerminatorInst *to_llvm (void) const; |
20654 | 1142 #endif |
15016 | 1143 protected: |
1144 virtual bool check_alive (size_t) const { return true; } | |
1145 private: | |
1146 std::vector<bool> malive; | |
1147 }; | |
1148 | |
1149 class | |
1150 jit_branch : public jit_terminator | |
1151 { | |
1152 public: | |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
1153 jit_branch (jit_block *succ) : jit_terminator (1, succ) { } |
15016 | 1154 |
1155 virtual size_t successor_count (void) const { return 1; } | |
1156 | |
1157 virtual std::ostream& print (std::ostream& os, size_t indent = 0) const | |
1158 { | |
1159 print_indent (os, indent) << "branch: "; | |
1160 return print_successor (os); | |
1161 } | |
1162 | |
1163 JIT_VALUE_ACCEPT; | |
1164 }; | |
1165 | |
1166 class | |
1167 jit_cond_branch : public jit_terminator | |
1168 { | |
1169 public: | |
1170 jit_cond_branch (jit_value *c, jit_block *ctrue, jit_block *cfalse) | |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
1171 : jit_terminator (2, ctrue, cfalse, c) { } |
15016 | 1172 |
1173 jit_value *cond (void) const { return argument (2); } | |
1174 | |
1175 std::ostream& print_cond (std::ostream& os) const | |
1176 { | |
1177 return cond ()->short_print (os); | |
1178 } | |
1179 | |
20654 | 1180 #if HAVE_LLVM |
15016 | 1181 llvm::Value *cond_llvm (void) const |
1182 { | |
1183 return cond ()->to_llvm (); | |
1184 } | |
20654 | 1185 #endif |
15016 | 1186 |
1187 virtual size_t successor_count (void) const { return 2; } | |
1188 | |
1189 virtual std::ostream& print (std::ostream& os, size_t indent = 0) const | |
1190 { | |
1191 print_indent (os, indent) << "cond_branch: "; | |
1192 print_cond (os) << ", "; | |
1193 print_successor (os, 0) << ", "; | |
1194 return print_successor (os, 1); | |
1195 } | |
1196 | |
1197 JIT_VALUE_ACCEPT; | |
1198 }; | |
1199 | |
1200 class | |
1201 jit_call : public jit_instruction | |
1202 { | |
1203 public: | |
15337
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1204 jit_call (const jit_operation& (*aoperation) (void)) |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1205 : moperation (aoperation ()) |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1206 { |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1207 const jit_function& ol = overload (); |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1208 if (ol.valid ()) |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1209 stash_type (ol.result ()); |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1210 } |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1211 |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1212 jit_call (const jit_operation& aoperation) : moperation (aoperation) |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1213 { |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1214 const jit_function& ol = overload (); |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1215 if (ol.valid ()) |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1216 stash_type (ol.result ()); |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1217 } |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1218 |
15016 | 1219 #define JIT_CALL_CONST(N) \ |
1220 jit_call (const jit_operation& aoperation, \ | |
1221 OCT_MAKE_DECL_LIST (jit_value *, arg, N)) \ | |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
1222 : jit_instruction (OCT_MAKE_ARG_LIST (arg, N)), moperation (aoperation) { } \ |
15016 | 1223 \ |
1224 jit_call (const jit_operation& (*aoperation) (void), \ | |
1225 OCT_MAKE_DECL_LIST (jit_value *, arg, N)) \ | |
1226 : jit_instruction (OCT_MAKE_ARG_LIST (arg, N)), moperation (aoperation ()) \ | |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
1227 { } |
15016 | 1228 |
1229 JIT_CALL_CONST (1) | |
1230 JIT_CALL_CONST (2) | |
1231 JIT_CALL_CONST (3) | |
1232 JIT_CALL_CONST (4) | |
1233 | |
1234 #undef JIT_CALL_CONST | |
1235 | |
15067 | 1236 jit_call (const jit_operation& aoperation, |
1237 const std::vector<jit_value *>& args) | |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
1238 : jit_instruction (args), moperation (aoperation) |
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
1239 { } |
15016 | 1240 |
1241 const jit_operation& operation (void) const { return moperation; } | |
1242 | |
1243 bool can_error (void) const | |
1244 { | |
1245 return overload ().can_error (); | |
1246 } | |
1247 | |
1248 const jit_function& overload (void) const | |
1249 { | |
1250 return moperation.overload (argument_types ()); | |
1251 } | |
1252 | |
15603 | 1253 virtual bool needs_release (void) const; |
15016 | 1254 |
1255 virtual std::ostream& print (std::ostream& os, size_t indent = 0) const | |
1256 { | |
1257 print_indent (os, indent); | |
1258 | |
1259 if (use_count ()) | |
1260 short_print (os) << " = "; | |
1261 os << "call " << moperation.name () << " ("; | |
1262 | |
1263 for (size_t i = 0; i < argument_count (); ++i) | |
1264 { | |
1265 print_argument (os, i); | |
1266 if (i + 1 < argument_count ()) | |
1267 os << ", "; | |
1268 } | |
1269 return os << ")"; | |
1270 } | |
1271 | |
1272 virtual bool infer (void); | |
1273 | |
1274 JIT_VALUE_ACCEPT; | |
1275 private: | |
1276 const jit_operation& moperation; | |
1277 }; | |
1278 | |
1279 // FIXME: This is just ugly... | |
15594
a7b22144318a
jit-ir.h: Fix typo in comment
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1280 // checks error_state, if error_state is false then goto the normal branch, |
15016 | 1281 // otherwise goto the error branch |
1282 class | |
1283 jit_error_check : public jit_terminator | |
1284 { | |
1285 public: | |
15603 | 1286 // Which variable is the error check for? |
1287 enum variable | |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
1288 { |
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
1289 var_error_state, |
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
1290 var_interrupt |
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
1291 }; |
15603 | 1292 |
1293 static std::string variable_to_string (variable v); | |
1294 | |
1295 jit_error_check (variable var, jit_call *acheck_for, jit_block *normal, | |
1296 jit_block *error) | |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
1297 : jit_terminator (2, error, normal, acheck_for), mvariable (var) { } |
15603 | 1298 |
1299 jit_error_check (variable var, jit_block *normal, jit_block *error) | |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
1300 : jit_terminator (2, error, normal), mvariable (var) { } |
15603 | 1301 |
1302 variable check_variable (void) const { return mvariable; } | |
1303 | |
1304 bool has_check_for (void) const | |
1305 { | |
1306 return argument_count () == 3; | |
1307 } | |
15016 | 1308 |
1309 jit_call *check_for (void) const | |
1310 { | |
15603 | 1311 assert (has_check_for ()); |
15016 | 1312 return static_cast<jit_call *> (argument (2)); |
1313 } | |
1314 | |
15603 | 1315 virtual std::ostream& print (std::ostream& os, size_t indent = 0) const; |
15016 | 1316 |
1317 JIT_VALUE_ACCEPT; | |
1318 protected: | |
1319 virtual bool check_alive (size_t idx) const | |
1320 { | |
15603 | 1321 if (! has_check_for ()) |
1322 return true; | |
15016 | 1323 return idx == 1 ? true : check_for ()->can_error (); |
1324 } | |
15603 | 1325 private: |
1326 variable mvariable; | |
15016 | 1327 }; |
1328 | |
15056
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
1329 // for now only handles the 1D case |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
1330 class |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
1331 jit_magic_end : public jit_instruction |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
1332 { |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
1333 public: |
15067 | 1334 class |
1335 context | |
1336 { | |
1337 public: | |
1338 context (void) : value (0), index (0), count (0) | |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
1339 { } |
15067 | 1340 |
15182
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
1341 context (jit_factory& factory, jit_value *avalue, size_t aindex, |
15102
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
1342 size_t acount); |
15067 | 1343 |
1344 jit_value *value; | |
15102
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
1345 jit_const_index *index; |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
1346 jit_const_index *count; |
15067 | 1347 }; |
1348 | |
1349 jit_magic_end (const std::vector<context>& full_context); | |
15056
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
1350 |
15102
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
1351 virtual bool infer (void); |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
1352 |
15056
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
1353 const jit_function& overload () const; |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
1354 |
15102
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
1355 virtual std::ostream& print (std::ostream& os, size_t indent = 0) const; |
15056
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
1356 |
15102
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
1357 context resolve_context (void) const; |
15056
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
1358 |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
1359 virtual std::ostream& short_print (std::ostream& os) const |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
1360 { |
15102
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
1361 return os << "magic_end" << "#" << id (); |
15056
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
1362 } |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
1363 |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
1364 JIT_VALUE_ACCEPT; |
15102
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
1365 private: |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
1366 std::vector<context> contexts; |
15056
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
1367 }; |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
1368 |
15016 | 1369 class |
1370 jit_extract_argument : public jit_assign_base | |
1371 { | |
1372 public: | |
1373 jit_extract_argument (jit_type *atype, jit_variable *adest) | |
1374 : jit_assign_base (adest) | |
1375 { | |
1376 stash_type (atype); | |
1377 } | |
1378 | |
1379 const std::string& name (void) const | |
1380 { | |
1381 return dest ()->name (); | |
1382 } | |
1383 | |
1384 const jit_function& overload (void) const | |
1385 { | |
1386 return jit_typeinfo::cast (type (), jit_typeinfo::get_any ()); | |
1387 } | |
1388 | |
1389 virtual std::ostream& print (std::ostream& os, size_t indent = 0) const | |
1390 { | |
1391 print_indent (os, indent); | |
1392 | |
1393 return short_print (os) << " = extract " << name (); | |
1394 } | |
1395 | |
1396 JIT_VALUE_ACCEPT; | |
1397 }; | |
1398 | |
1399 class | |
1400 jit_store_argument : public jit_instruction | |
1401 { | |
1402 public: | |
1403 jit_store_argument (jit_variable *var) | |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
1404 : jit_instruction (var), dest (var) |
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
1405 { } |
15016 | 1406 |
1407 const std::string& name (void) const | |
1408 { | |
1409 return dest->name (); | |
1410 } | |
1411 | |
1412 const jit_function& overload (void) const | |
1413 { | |
1414 return jit_typeinfo::cast (jit_typeinfo::get_any (), result_type ()); | |
1415 } | |
1416 | |
1417 jit_value *result (void) const | |
1418 { | |
1419 return argument (0); | |
1420 } | |
1421 | |
1422 jit_type *result_type (void) const | |
1423 { | |
1424 return result ()->type (); | |
1425 } | |
1426 | |
20654 | 1427 #if HAVE_LLVM |
15016 | 1428 llvm::Value *result_llvm (void) const |
1429 { | |
1430 return result ()->to_llvm (); | |
1431 } | |
20654 | 1432 #endif |
15016 | 1433 |
1434 virtual std::ostream& print (std::ostream& os, size_t indent = 0) const | |
1435 { | |
1436 jit_value *res = result (); | |
1437 print_indent (os, indent) << "store "; | |
1438 dest->short_print (os); | |
1439 | |
1440 if (! isa<jit_variable> (res)) | |
1441 { | |
1442 os << " = "; | |
1443 res->short_print (os); | |
1444 } | |
1445 | |
1446 return os; | |
1447 } | |
1448 | |
1449 JIT_VALUE_ACCEPT; | |
1450 private: | |
1451 jit_variable *dest; | |
1452 }; | |
1453 | |
1454 class | |
15337
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1455 jit_return : public jit_instruction |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1456 { |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1457 public: |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
1458 jit_return (void) { } |
15337
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1459 |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
1460 jit_return (jit_value *retval) : jit_instruction (retval) { } |
15337
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1461 |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1462 jit_value *result (void) const |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1463 { |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1464 return argument_count () ? argument (0) : 0; |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1465 } |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1466 |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1467 jit_type *result_type (void) const |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1468 { |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1469 jit_value *res = result (); |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1470 return res ? res->type () : 0; |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1471 } |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1472 |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1473 virtual std::ostream& print (std::ostream& os, size_t indent = 0) const |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1474 { |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1475 print_indent (os, indent) << "return"; |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1476 |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1477 if (result ()) |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1478 os << " " << *result (); |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1479 |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1480 return os; |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1481 } |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1482 |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1483 JIT_VALUE_ACCEPT; |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1484 }; |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1485 |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15232
diff
changeset
|
1486 class |
15016 | 1487 jit_ir_walker |
1488 { | |
1489 public: | |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
1490 virtual ~jit_ir_walker () { } |
15016 | 1491 |
1492 #define JIT_METH(clname) \ | |
1493 virtual void visit (jit_ ## clname&) = 0; | |
1494 | |
1495 JIT_VISIT_IR_CLASSES; | |
1496 | |
1497 #undef JIT_METH | |
1498 }; | |
1499 | |
1500 template <typename T, jit_type *(*EXTRACT_T)(void), typename PASS_T, bool QUOTE> | |
1501 void | |
1502 jit_const<T, EXTRACT_T, PASS_T, QUOTE>::accept (jit_ir_walker& walker) | |
1503 { | |
1504 walker.visit (*this); | |
1505 } | |
1506 | |
1507 #undef JIT_VALUE_ACCEPT | |
1508 | |
20654 | 1509 #endif /* ifdef HAVE_JIT */ |
15016 | 1510 #endif |