Mercurial > octave-nkf
annotate src/interp-core/jit-ir.cc @ 15182:a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
* jit-ir.cc (jit_factory, jit_block_list): New class.
(jit_block::maybe_split): Use jit_factory and jit_block_list instead of
jit_convert.
(jit_magic_end::context::context): Use jit_factory instead of jit_convert.
* jit-ir.h (jit_factory, jit_block_list): New class.
(jit_block::maybe_split): Use jit_block_list and jit_factory.
(jit_magic_end::context::context) Use jit_factory.
* pt-jit.cc (jit_convert): Use jit_factory and jit_block_list instead of
internal methods.
(jit_convert::append): Removed method.
(jit_convert::create_checked_impl): Merg in jit_convert::create_check.
(jit_convert::insert_before, jit_convert;:insert_after,
jit_convert::~jit_convert, jit_convert::append): Remove method.
(jit_convert_llvm::convert): Use jit_block_list.
* pt-jit.h (jit_convert::~jit_convert, jit_convert::append): Remove declaration.
(jit_convert::create, jit_convert::insert_before, jit_convert::insert_after,
jit_convert::track_value): Remove method.
(jit_convert_llvm::convert): Use jit_block_list.
author | Max Brister <max@2bass.com> |
---|---|
date | Wed, 15 Aug 2012 23:30:02 -0500 |
parents | 7a19e8275d41 |
children | ed4f4fb78586 |
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 // defines required by llvm | |
24 #define __STDC_LIMIT_MACROS | |
25 #define __STDC_CONSTANT_MACROS | |
26 | |
27 #ifdef HAVE_CONFIG_H | |
28 #include <config.h> | |
29 #endif | |
30 | |
31 #ifdef HAVE_LLVM | |
32 | |
33 #include "jit-ir.h" | |
34 | |
35 #include <llvm/BasicBlock.h> | |
36 #include <llvm/Instructions.h> | |
37 | |
38 #include "error.h" | |
15182
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
39 |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
40 // -------------------- jit_factory -------------------- |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
41 jit_factory::~jit_factory (void) |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
42 { |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
43 for (value_list::iterator iter = all_values.begin (); |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
44 iter != all_values.end (); ++iter) |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
45 delete *iter; |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
46 } |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
47 |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
48 void |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
49 jit_factory::track_value (jit_value *value) |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
50 { |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
51 if (value->type ()) |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
52 mconstants.push_back (value); |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
53 all_values.push_back (value); |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
54 } |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
55 |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
56 // -------------------- jit_block_list -------------------- |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
57 void |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
58 jit_block_list::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:
15171
diff
changeset
|
59 { |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
60 ++iter; |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
61 insert_before (iter, ablock); |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
62 } |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
63 |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
64 void |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
65 jit_block_list::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:
15171
diff
changeset
|
66 { |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
67 insert_after (loc->location (), ablock); |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
68 } |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
69 |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
70 void |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
71 jit_block_list::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:
15171
diff
changeset
|
72 { |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
73 iter = mlist.insert (iter, ablock); |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
74 ablock->stash_location (iter); |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
75 } |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
76 |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
77 void |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
78 jit_block_list::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:
15171
diff
changeset
|
79 { |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
80 insert_before (loc->location (), ablock); |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
81 } |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
82 |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
83 void |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
84 jit_block_list::push_back (jit_block *b) |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
85 { |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
86 mlist.push_back (b); |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
87 iterator iter = mlist.end (); |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
88 b->stash_location (--iter); |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
89 } |
15016 | 90 |
91 // -------------------- jit_use -------------------- | |
92 jit_block * | |
93 jit_use::user_parent (void) const | |
94 { | |
95 return muser->parent (); | |
96 } | |
97 | |
98 // -------------------- jit_value -------------------- | |
99 jit_value::~jit_value (void) | |
100 {} | |
101 | |
102 jit_block * | |
103 jit_value::first_use_block (void) | |
104 { | |
105 jit_use *use = first_use (); | |
106 while (use) | |
107 { | |
108 if (! isa<jit_error_check> (use->user ())) | |
109 return use->user_parent (); | |
110 | |
111 use = use->next (); | |
112 } | |
113 | |
114 return 0; | |
115 } | |
116 | |
117 void | |
118 jit_value::replace_with (jit_value *value) | |
119 { | |
120 while (first_use ()) | |
121 { | |
122 jit_instruction *user = first_use ()->user (); | |
123 size_t idx = first_use ()->index (); | |
124 user->stash_argument (idx, value); | |
125 } | |
126 } | |
127 | |
128 #define JIT_METH(clname) \ | |
129 void \ | |
130 jit_ ## clname::accept (jit_ir_walker& walker) \ | |
131 { \ | |
132 walker.visit (*this); \ | |
133 } | |
134 | |
135 JIT_VISIT_IR_NOTEMPLATE | |
136 #undef JIT_METH | |
137 | |
138 std::ostream& | |
139 operator<< (std::ostream& os, const jit_value& value) | |
140 { | |
141 return value.short_print (os); | |
142 } | |
143 | |
144 std::ostream& | |
145 jit_print (std::ostream& os, jit_value *avalue) | |
146 { | |
147 if (avalue) | |
148 return avalue->print (os); | |
149 return os << "NULL"; | |
150 } | |
151 | |
152 // -------------------- jit_instruction -------------------- | |
153 void | |
154 jit_instruction::remove (void) | |
155 { | |
156 if (mparent) | |
157 mparent->remove (mlocation); | |
158 resize_arguments (0); | |
159 } | |
160 | |
161 llvm::BasicBlock * | |
162 jit_instruction::parent_llvm (void) const | |
163 { | |
164 return mparent->to_llvm (); | |
165 } | |
166 | |
167 std::ostream& | |
168 jit_instruction::short_print (std::ostream& os) const | |
169 { | |
170 if (type ()) | |
171 jit_print (os, type ()) << ": "; | |
172 return os << "#" << mid; | |
173 } | |
174 | |
175 void | |
176 jit_instruction::do_construct_ssa (size_t start, size_t end) | |
177 { | |
178 for (size_t i = start; i < end; ++i) | |
179 { | |
180 jit_value *arg = argument (i); | |
181 jit_variable *var = dynamic_cast<jit_variable *> (arg); | |
182 if (var && var->has_top ()) | |
183 stash_argument (i, var->top ()); | |
184 } | |
185 } | |
186 | |
187 // -------------------- jit_block -------------------- | |
188 void | |
189 jit_block::replace_with (jit_value *value) | |
190 { | |
191 assert (isa<jit_block> (value)); | |
192 jit_block *block = static_cast<jit_block *> (value); | |
193 | |
194 jit_value::replace_with (block); | |
195 | |
196 while (ILIST_T::first_use ()) | |
197 { | |
198 jit_phi_incomming *incomming = ILIST_T::first_use (); | |
199 incomming->stash_value (block); | |
200 } | |
201 } | |
202 | |
203 void | |
204 jit_block::replace_in_phi (jit_block *ablock, jit_block *with) | |
205 { | |
206 jit_phi_incomming *node = ILIST_T::first_use (); | |
207 while (node) | |
208 { | |
209 jit_phi_incomming *prev = node; | |
210 node = node->next (); | |
211 | |
212 if (prev->user_parent () == ablock) | |
213 prev->stash_value (with); | |
214 } | |
215 } | |
216 | |
217 jit_block * | |
218 jit_block::maybe_merge () | |
219 { | |
220 if (successor_count () == 1 && successor (0) != this | |
221 && (successor (0)->use_count () == 1 || instructions.size () == 1)) | |
222 { | |
223 jit_block *to_merge = successor (0); | |
224 merge (*to_merge); | |
225 return to_merge; | |
226 } | |
227 | |
228 return 0; | |
229 } | |
230 | |
231 void | |
232 jit_block::merge (jit_block& block) | |
233 { | |
234 // the merge block will contain a new terminator | |
235 jit_terminator *old_term = terminator (); | |
236 if (old_term) | |
237 old_term->remove (); | |
238 | |
239 bool was_empty = end () == begin (); | |
240 iterator merge_begin = end (); | |
241 if (! was_empty) | |
242 --merge_begin; | |
243 | |
244 instructions.splice (end (), block.instructions); | |
245 if (was_empty) | |
246 merge_begin = begin (); | |
247 else | |
248 ++merge_begin; | |
249 | |
250 // now merge_begin points to the start of the new instructions, we must | |
251 // update their parent information | |
252 for (iterator iter = merge_begin; iter != end (); ++iter) | |
253 { | |
254 jit_instruction *instr = *iter; | |
255 instr->stash_parent (this, iter); | |
256 } | |
257 | |
258 block.replace_with (this); | |
259 } | |
260 | |
261 jit_instruction * | |
262 jit_block::prepend (jit_instruction *instr) | |
263 { | |
264 instructions.push_front (instr); | |
265 instr->stash_parent (this, instructions.begin ()); | |
266 return instr; | |
267 } | |
268 | |
269 jit_instruction * | |
270 jit_block::prepend_after_phi (jit_instruction *instr) | |
271 { | |
272 // FIXME: Make this O(1) | |
273 for (iterator iter = begin (); iter != end (); ++iter) | |
274 { | |
275 jit_instruction *temp = *iter; | |
276 if (! isa<jit_phi> (temp)) | |
277 { | |
278 insert_before (iter, instr); | |
279 return instr; | |
280 } | |
281 } | |
282 | |
283 return append (instr); | |
284 } | |
285 | |
286 void | |
287 jit_block::internal_append (jit_instruction *instr) | |
288 { | |
289 instructions.push_back (instr); | |
290 instr->stash_parent (this, --instructions.end ()); | |
291 } | |
292 | |
293 jit_instruction * | |
294 jit_block::insert_before (iterator loc, jit_instruction *instr) | |
295 { | |
296 iterator iloc = instructions.insert (loc, instr); | |
297 instr->stash_parent (this, iloc); | |
298 return instr; | |
299 } | |
300 | |
301 jit_instruction * | |
302 jit_block::insert_after (iterator loc, jit_instruction *instr) | |
303 { | |
304 ++loc; | |
305 iterator iloc = instructions.insert (loc, instr); | |
306 instr->stash_parent (this, iloc); | |
307 return instr; | |
308 } | |
309 | |
310 jit_terminator * | |
311 jit_block::terminator (void) const | |
312 { | |
313 assert (this); | |
314 if (instructions.empty ()) | |
315 return 0; | |
316 | |
317 jit_instruction *last = instructions.back (); | |
318 return dynamic_cast<jit_terminator *> (last); | |
319 } | |
320 | |
321 bool | |
322 jit_block::branch_alive (jit_block *asucc) const | |
323 { | |
324 return terminator ()->alive (asucc); | |
325 } | |
326 | |
327 jit_block * | |
328 jit_block::successor (size_t i) const | |
329 { | |
330 jit_terminator *term = terminator (); | |
331 return term->successor (i); | |
332 } | |
333 | |
334 size_t | |
335 jit_block::successor_count (void) const | |
336 { | |
337 jit_terminator *term = terminator (); | |
338 return term ? term->successor_count () : 0; | |
339 } | |
340 | |
341 llvm::BasicBlock * | |
342 jit_block::to_llvm (void) const | |
343 { | |
344 return llvm::cast<llvm::BasicBlock> (llvm_value); | |
345 } | |
346 | |
347 std::ostream& | |
348 jit_block::print_dom (std::ostream& os) const | |
349 { | |
350 short_print (os); | |
351 os << ":\n"; | |
352 os << " mid: " << mid << std::endl; | |
353 os << " predecessors: "; | |
354 for (jit_use *use = first_use (); use; use = use->next ()) | |
355 os << *use->user_parent () << " "; | |
356 os << std::endl; | |
357 | |
358 os << " successors: "; | |
359 for (size_t i = 0; i < successor_count (); ++i) | |
360 os << *successor (i) << " "; | |
361 os << std::endl; | |
362 | |
363 os << " idom: "; | |
364 if (idom) | |
365 os << *idom; | |
366 else | |
367 os << "NULL"; | |
368 os << std::endl; | |
369 os << " df: "; | |
370 for (df_iterator iter = df_begin (); iter != df_end (); ++iter) | |
371 os << **iter << " "; | |
372 os << std::endl; | |
373 | |
374 os << " dom_succ: "; | |
375 for (size_t i = 0; i < dom_succ.size (); ++i) | |
376 os << *dom_succ[i] << " "; | |
377 | |
378 return os << std::endl; | |
379 } | |
380 | |
381 void | |
382 jit_block::compute_df (size_t avisit_count) | |
383 { | |
384 if (visited (avisit_count)) | |
385 return; | |
386 | |
387 if (use_count () >= 2) | |
388 { | |
389 for (jit_use *use = first_use (); use; use = use->next ()) | |
390 { | |
391 jit_block *runner = use->user_parent (); | |
392 while (runner != idom) | |
393 { | |
394 runner->mdf.insert (this); | |
395 runner = runner->idom; | |
396 } | |
397 } | |
398 } | |
399 | |
400 for (size_t i = 0; i < successor_count (); ++i) | |
401 successor (i)->compute_df (avisit_count); | |
402 } | |
403 | |
404 bool | |
405 jit_block::update_idom (size_t avisit_count) | |
406 { | |
407 if (visited (avisit_count) || ! use_count ()) | |
408 return false; | |
409 | |
410 bool changed = false; | |
411 for (jit_use *use = first_use (); use; use = use->next ()) | |
412 { | |
413 jit_block *pred = use->user_parent (); | |
414 changed = pred->update_idom (avisit_count) || changed; | |
415 } | |
416 | |
417 jit_use *use = first_use (); | |
418 jit_block *new_idom = use->user_parent (); | |
419 use = use->next (); | |
420 | |
421 for (; use; use = use->next ()) | |
422 { | |
423 jit_block *pred = use->user_parent (); | |
424 jit_block *pidom = pred->idom; | |
425 if (pidom) | |
426 new_idom = idom_intersect (pidom, new_idom); | |
427 } | |
428 | |
429 if (idom != new_idom) | |
430 { | |
431 idom = new_idom; | |
432 return true; | |
433 } | |
434 | |
435 return changed; | |
436 } | |
437 | |
438 void | |
439 jit_block::pop_all (void) | |
440 { | |
441 for (iterator iter = begin (); iter != end (); ++iter) | |
442 { | |
443 jit_instruction *instr = *iter; | |
444 instr->pop_variable (); | |
445 } | |
446 } | |
447 | |
448 jit_block * | |
15182
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
449 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:
15171
diff
changeset
|
450 jit_block *asuccessor) |
15016 | 451 { |
452 if (successor_count () > 1) | |
453 { | |
454 jit_terminator *term = terminator (); | |
455 size_t idx = term->successor_index (asuccessor); | |
15182
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
456 jit_block *split = factory.create<jit_block> ("phi_split", mvisit_count); |
15016 | 457 |
15171
7a19e8275d41
Do not simplify the CFG during type inference
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
458 // place after this to ensure define before use in the blocks list |
15182
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
459 blocks.insert_after (this, split); |
15016 | 460 |
461 term->stash_argument (idx, split); | |
15182
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
462 jit_branch *br = split->append (factory.create<jit_branch> (asuccessor)); |
15016 | 463 replace_in_phi (asuccessor, split); |
464 | |
465 if (alive ()) | |
466 { | |
467 split->mark_alive (); | |
468 br->infer (); | |
469 } | |
470 | |
471 return split; | |
472 } | |
473 | |
474 return this; | |
475 } | |
476 | |
477 void | |
478 jit_block::create_dom_tree (size_t avisit_count) | |
479 { | |
480 if (visited (avisit_count)) | |
481 return; | |
482 | |
483 if (idom != this) | |
484 idom->dom_succ.push_back (this); | |
485 | |
486 for (size_t i = 0; i < successor_count (); ++i) | |
487 successor (i)->create_dom_tree (avisit_count); | |
488 } | |
489 | |
490 jit_block * | |
491 jit_block::idom_intersect (jit_block *i, jit_block *j) | |
492 { | |
493 while (i && j && i != j) | |
494 { | |
495 while (i && i->id () > j->id ()) | |
496 i = i->idom; | |
497 | |
498 while (i && j && j->id () > i->id ()) | |
499 j = j->idom; | |
500 } | |
501 | |
502 return i ? i : j; | |
503 } | |
504 | |
505 // -------------------- jit_phi_incomming -------------------- | |
506 | |
507 jit_block * | |
508 jit_phi_incomming::user_parent (void) const | |
509 { return muser->parent (); } | |
510 | |
511 // -------------------- jit_phi -------------------- | |
512 bool | |
513 jit_phi::prune (void) | |
514 { | |
515 jit_block *p = parent (); | |
516 size_t new_idx = 0; | |
517 jit_value *unique = argument (1); | |
518 | |
519 for (size_t i = 0; i < argument_count (); ++i) | |
520 { | |
521 jit_block *inc = incomming (i); | |
522 if (inc->branch_alive (p)) | |
523 { | |
524 if (unique != argument (i)) | |
525 unique = 0; | |
526 | |
527 if (new_idx != i) | |
528 { | |
529 stash_argument (new_idx, argument (i)); | |
530 mincomming[new_idx].stash_value (inc); | |
531 } | |
532 | |
533 ++new_idx; | |
534 } | |
535 } | |
536 | |
537 if (new_idx != argument_count ()) | |
538 { | |
539 resize_arguments (new_idx); | |
540 mincomming.resize (new_idx); | |
541 } | |
542 | |
543 assert (argument_count () > 0); | |
544 if (unique) | |
545 { | |
546 replace_with (unique); | |
547 return true; | |
548 } | |
549 | |
550 return false; | |
551 } | |
552 | |
553 bool | |
554 jit_phi::infer (void) | |
555 { | |
556 jit_block *p = parent (); | |
557 if (! p->alive ()) | |
558 return false; | |
559 | |
560 jit_type *infered = 0; | |
561 for (size_t i = 0; i < argument_count (); ++i) | |
562 { | |
563 jit_block *inc = incomming (i); | |
564 if (inc->branch_alive (p)) | |
565 infered = jit_typeinfo::join (infered, argument_type (i)); | |
566 } | |
567 | |
568 if (infered != type ()) | |
569 { | |
570 stash_type (infered); | |
571 return true; | |
572 } | |
573 | |
574 return false; | |
575 } | |
576 | |
577 llvm::PHINode * | |
578 jit_phi::to_llvm (void) const | |
579 { | |
580 return llvm::cast<llvm::PHINode> (jit_value::to_llvm ()); | |
581 } | |
582 | |
583 // -------------------- jit_terminator -------------------- | |
584 size_t | |
585 jit_terminator::successor_index (const jit_block *asuccessor) const | |
586 { | |
587 size_t scount = successor_count (); | |
588 for (size_t i = 0; i < scount; ++i) | |
589 if (successor (i) == asuccessor) | |
590 return i; | |
591 | |
592 panic_impossible (); | |
593 } | |
594 | |
595 bool | |
596 jit_terminator::infer (void) | |
597 { | |
598 if (! parent ()->alive ()) | |
599 return false; | |
600 | |
601 bool changed = false; | |
602 for (size_t i = 0; i < malive.size (); ++i) | |
603 if (! malive[i] && check_alive (i)) | |
604 { | |
605 changed = true; | |
606 malive[i] = true; | |
607 successor (i)->mark_alive (); | |
608 } | |
609 | |
610 return changed; | |
611 } | |
612 | |
613 llvm::TerminatorInst * | |
614 jit_terminator::to_llvm (void) const | |
615 { | |
616 return llvm::cast<llvm::TerminatorInst> (jit_value::to_llvm ()); | |
617 } | |
618 | |
619 // -------------------- jit_call -------------------- | |
620 bool | |
621 jit_call::infer (void) | |
622 { | |
623 // FIXME: explain algorithm | |
624 for (size_t i = 0; i < argument_count (); ++i) | |
625 { | |
626 already_infered[i] = argument_type (i); | |
627 if (! already_infered[i]) | |
628 return false; | |
629 } | |
630 | |
631 jit_type *infered = moperation.result (already_infered); | |
632 if (! infered && use_count ()) | |
633 { | |
634 std::stringstream ss; | |
635 ss << "Missing overload in type inference for "; | |
636 print (ss, 0); | |
637 throw jit_fail_exception (ss.str ()); | |
638 } | |
639 | |
640 if (infered != type ()) | |
641 { | |
642 stash_type (infered); | |
643 return true; | |
644 } | |
645 | |
646 return false; | |
647 } | |
648 | |
15056
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
649 // -------------------- jit_magic_end -------------------- |
15182
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
650 jit_magic_end::context::context (jit_factory& factory, jit_value *avalue, |
15102
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
651 size_t aindex, size_t acount) |
15182
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
652 : value (avalue), index (factory.create<jit_const_index> (aindex)), |
a7a56b436de2
Factor out jit_block_list and jit_factory from jit_convert
Max Brister <max@2bass.com>
parents:
15171
diff
changeset
|
653 count (factory.create<jit_const_index> (acount)) |
15102
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
654 {} |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
655 |
15067 | 656 jit_magic_end::jit_magic_end (const std::vector<context>& full_context) |
15102
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
657 : contexts (full_context) |
15067 | 658 { |
15102
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
659 resize_arguments (contexts.size ()); |
15067 | 660 |
661 size_t i; | |
662 std::vector<context>::const_iterator iter; | |
15102
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
663 for (iter = contexts.begin (), i = 0; iter != contexts.end (); ++iter, ++i) |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
664 stash_argument (i, iter->value); |
15067 | 665 } |
666 | |
15102
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
667 jit_magic_end::context |
15056
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
668 jit_magic_end::resolve_context (void) const |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
669 { |
15124
0464e3ceb85b
Skip functions when resolving end context in JIT
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
670 size_t idx; |
0464e3ceb85b
Skip functions when resolving end context in JIT
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
671 for (idx = 0; idx < contexts.size (); ++idx) |
0464e3ceb85b
Skip functions when resolving end context in JIT
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
672 { |
0464e3ceb85b
Skip functions when resolving end context in JIT
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
673 jit_type *ctx_type = contexts[idx].value->type (); |
0464e3ceb85b
Skip functions when resolving end context in JIT
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
674 if (! ctx_type || ctx_type->skip_paren ()) |
0464e3ceb85b
Skip functions when resolving end context in JIT
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
675 break; |
0464e3ceb85b
Skip functions when resolving end context in JIT
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
676 } |
0464e3ceb85b
Skip functions when resolving end context in JIT
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
677 |
0464e3ceb85b
Skip functions when resolving end context in JIT
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
678 if (idx >= contexts.size ()) |
0464e3ceb85b
Skip functions when resolving end context in JIT
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
679 idx = 0; |
0464e3ceb85b
Skip functions when resolving end context in JIT
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
680 |
0464e3ceb85b
Skip functions when resolving end context in JIT
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
681 context ret = contexts[idx]; |
0464e3ceb85b
Skip functions when resolving end context in JIT
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
682 ret.value = argument (idx); |
15102
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
683 return ret; |
15056
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
684 } |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
685 |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
686 bool |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
687 jit_magic_end::infer (void) |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
688 { |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
689 jit_type *new_type = overload ().result (); |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
690 if (new_type != type ()) |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
691 { |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
692 stash_type (new_type); |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
693 return true; |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
694 } |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
695 |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
696 return false; |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
697 } |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
698 |
15102
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
699 std::ostream& |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
700 jit_magic_end::print (std::ostream& os, size_t indent) const |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
701 { |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
702 context ctx = resolve_context (); |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
703 short_print (print_indent (os, indent)) << " (" << *ctx.value << ", "; |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
704 return os << *ctx.index << ", " << *ctx.count << ")"; |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
705 } |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
706 |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
707 const jit_function& |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
708 jit_magic_end::overload () const |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
709 { |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
710 const context& ctx = resolve_context (); |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
711 return jit_typeinfo::end (ctx.value, ctx.index, ctx.count); |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
712 } |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
713 |
15016 | 714 #endif |