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