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