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