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