CACAO
Instructions.hpp
Go to the documentation of this file.
1 /* src/vm/jit/compiler2/Instructions.hpp - Instructions
2 
3  Copyright (C) 2013
4  CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 
6  This file is part of CACAO.
7 
8  This program is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 2, or (at
11  your option) any later version.
12 
13  This program is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  02110-1301, USA.
22 
23 */
24 
25 /**
26  * This file contains the Instruction class.
27  * The Instruction class is the base class for all other instruction types.
28  * They are defined in Instructions.hpp.
29  */
30 
31 #ifndef _JIT_COMPILER2_INSTRUCTIONS
32 #define _JIT_COMPILER2_INSTRUCTIONS
33 
38 #include "vm/types.hpp"
39 
40 namespace cacao {
41 namespace jit {
42 namespace compiler2 {
43 
44 // Instruction groups
45 
46 /**
47  * Base type of instructions with a single operand.
48  */
49 class UnaryInst : public Instruction {
50 public:
51 
52  /**
53  * Construct a UnaryInst.
54  *
55  * @param id The corresponding InstID.
56  * @param type The type of the value that is computed by this UnaryInst.
57  * @param op The operand.
58  */
59  explicit UnaryInst(InstID id, Type::TypeID type, Value* op) : Instruction(id, type) {
60  append_op(op);
61  }
62 
63  /**
64  * Conversion method.
65  */
66  virtual UnaryInst* to_UnaryInst() { return this; }
67 };
68 
69 /**
70  * Base type of instructions with two operands.
71  *
72  * @note Idea: create a ArithmeticInst superclass which features a method
73  * e.g. simplify() which returns the result of the operands if they are
74  * constants.
75  */
76 class BinaryInst : public Instruction {
77 public:
78 
79  /**
80  * Construct a BinaryInst.
81  *
82  * @param id The corresponding InstID.
83  * @param type The type that is computed by this BinaryInst.
84  * @param op1 The first operand.
85  * @param op2 The second operand.
86  */
87  explicit BinaryInst(InstID id, Type::TypeID type, Value* op1, Value* op2) : Instruction(id, type) {
88  append_op(op1);
89  append_op(op2);
90  }
91 
92  /**
93  * Conversion method.
94  */
95  virtual BinaryInst* to_BinaryInst() { return this; }
96 };
97 
98 /**
99  * Base type of instructions with an arbitrary number of operands.
100  */
101 class MultiOpInst : public Instruction {
102 public:
103 
104  /**
105  * Construct a MultiOpInst.
106  *
107  * @param id The corresponding InstID.
108  * @param type The type that is computed by this MultiOpInst.
109  */
110  explicit MultiOpInst(InstID id, Type::TypeID type) : Instruction(id, type) {}
111 
112  // exporting to the public
115 };
116 
117 /**
118  * Base type of instructions that compute a condition.
119  */
120 class CondInst {
121 protected:
122 
123  /**
124  * The kind of condition that is computed.
125  */
127 
128 public:
129 
130  /**
131  * Construct a CondInst.
132  *
133  * @param condition The kind of condition to copmute.
134  */
135  explicit CondInst(Conditional::CondID condition) : condition(condition){}
136 
137  /**
138  * Get the kind of condition that is computed.
139  */
141 
142  virtual ~CondInst() {}
143 };
144 
145 /**
146  * Provides a mapping from HIR values to baseline IR variables.
147  *
148  * In order to reconstruct the source state during on-stack replacement, it
149  * is necessary to be able to reconstruct the machine-independent source state
150  * from the current machine-dependent execution state. Due to the generality of
151  * the baseline compiler's IR the on-stack replacement mechanism represents the
152  * source state in terms of the baseline IR variables. Hence, it is necessary
153  * to be able to map compiler2-specific HIR values to baseline IR variables. A
154  * SourceStateInst provides such mapping information for a single program
155  * location which is identified by the (machine-independent) ID of the
156  * corresponding baseline IR instruction.
157  */
158 class SourceStateInst : public Instruction {
159 public:
160 
161  /**
162  * Maps a HIR value to a baseline IR javalocal index.
163  */
164  struct Javalocal {
165 
166  /**
167  * The value that is mapped to a baseline IR javalocal index.
168  */
170 
171  /**
172  * A baseline IR javalocal index.
173  */
174  std::size_t index;
175 
176  /**
177  * Construct a Javalocal that maps @p value to @p index
178  *
179  * @param value The Value that is mapped to @p index.
180  * @param index The javalocal index that corresponds to @p value.
181  */
182  explicit Javalocal(Value *value, std::size_t index) : value(value), index(index) {}
183  };
184 
185 private:
186 
190 
191  /**
192  * The program location corresponding to the provided mapping information.
193  *
194  * The mappings of HIR values to baseline IR variables, which are given by
195  * this SourceStateInst, are bound to this exact program location. This
196  * location is given in terms of an ID of the corresponding baseline IR
197  * instruction.
198  */
200 
201  /**
202  * The state of the enclosing method in case we are in an inlined region.
203  */
205 
206  /**
207  * List of mappings from HIR values to baseline IR javalocal indices.
208  */
210 
211  /**
212  * List of HIR values that correspond to baseline IR stack variables.
213  */
215 
216  /**
217  * List of HIR values that correspond to method parameters.
218  */
220 
221 public:
222 
223  typedef JavalocalListTy::const_iterator const_javalocal_iterator;
224  typedef StackvarListTy::const_iterator const_stackvar_iterator;
225  typedef ParamListTy::const_iterator const_param_iterator;
226 
227  /**
228  * Construct a SourceStateInst.
229  *
230  * @param source_location The ID of the baseline IR instruction at the
231  * mapped program location.
232  * @param hir_location The HIR instruction that corresponds to the
233  * given @p source_location.
234  */
236  : Instruction(SourceStateInstID, Type::VoidTypeID),
237  source_location(source_location) {
238  assert(!hir_location->is_floating());
239  append_dep(hir_location);
240  }
241 
242  /**
243  * Get the BeginInst of the block that contains this SourceStateInst.
244  */
245  virtual BeginInst* get_BeginInst() const {
247  assert(begin);
248  return begin;
249  }
250 
251  /**
252  * @return The program location that corresponds to the given mappings.
253  */
255 
256  /**
257  * @return The state of the enclosing method in case we are in an inlined region.
258  */
259  SourceStateInst *get_parent() const { return parent; };
260 
261  /**
262  * Set state of the enclosing method in case we are in an inlined region.
263  *
264  * @param new_parent The corresponding source state.
265  */
266  void set_parent(SourceStateInst *new_parent) { parent = new_parent; }
267 
268  /**
269  * Append a new mapping from a HIR Value to a baseline IR javalocal index.
270  *
271  * @param local The Javalocal to append.
272  */
274  append_op(local.value);
275  javalocals.push_back(local);
276  }
277 
278  /**
279  * Append a new value to corresponds to a baseline IR stack variable.
280  *
281  * @param value The value to append.
282  */
283  void append_stackvar(Value *value) {
284  append_op(value);
285  stackvars.push_back(value);
286  }
287 
288  /**
289  * Append a new value to corresponds to a method parameter.
290  *
291  * @param value The value to append.
292  */
293  void append_param(Value *value) {
294  append_op(value);
295  params.push_back(value);
296  }
297 
300 
303 
304  const_param_iterator param_begin() const { return params.begin(); }
305  const_param_iterator param_end() const { return params.end(); }
306 
307  virtual void replace_op(Value* v_old, Value* v_new) {
308  Instruction::replace_op(v_old, v_new);
309  std::replace(stackvars.begin(), stackvars.end(), v_old, v_new);
310  std::replace(params.begin(), params.end(), v_old, v_new);
311  for (JavalocalListTy::iterator i = javalocals.begin(), e = javalocals.end();
312  i != e; i++) {
313  Javalocal &local = *i;
314  if (local.value == v_old) {
315  local.value = v_new;
316  }
317  }
318  }
319 
320  /**
321  * @see Instruction::is_homogeneous()
322  */
323  virtual bool is_homogeneous() const { return false; }
324 
325  /**
326  * For now we prevent floating to avoid unforeseen instruction reordering.
327  */
328  virtual bool is_floating() const { return false; }
329 
330  /**
331  * Conversion method.
332  */
333  virtual SourceStateInst* to_SourceStateInst() { return this; }
334 
335  /**
336  * Visitor pattern.
337  */
338  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
339 };
340 
341 /**
342  * Base type of instructions that can be mapped to a SourceStateInst.
343  */
345 private:
346 
347  /**
348  * The SourceStateInst that corresponds to this Instruction.
349  */
351 
352 public:
353 
354  /**
355  * Construct a SourceStateAwareInst.
356  */
358 
359  /**
360  * Convert this SourceStateAwareInst to an Instruction.
361  *
362  * @return This SourceStateAwareInst as Instruction.
363  */
364  virtual Instruction *to_Instruction() = 0;
365 
366  /**
367  * Get the SourceStateInst that corresponds to this Instruction.
368  *
369  * @return The source state if available, NULL otherwise.
370  */
372 
373  /**
374  * Set the SourceStateInst that corresponds to this Instruction.
375  *
376  * This will be done automatically by the SourceStateAttachmentPass.
377  *
378  * @param source_state The corresponding SourceStateInst.
379  */
381  assert(source_state != NULL);
382  assert(this->source_state == NULL);
383  this->source_state = source_state;
385  assert(I != NULL);
386  I->append_dep(source_state);
387  }
388 
389  virtual bool needs_source_state() { return true; }
390 
392 };
393 
394 /**
395  * Base type of instructions that dereference an object reference.
396  */
398 private:
399 
400  /**
401  * Whether a null-check is needed to safeguard the dereference.
402  */
404 
405 public:
406 
408 
409  /**
410  * Control whether a null-check is needed to safeguard the dereference.
411  */
413  this->needs_null_check = needs_null_check;
414  }
415 
416  /**
417  * Whether a null-check is needed to safeguard the dereference.
418  */
419  bool get_needs_null_check() const { return needs_null_check; }
420 
421  /**
422  * Get the corresponding object reference.
423  */
424  virtual Instruction *get_objectref() = 0;
425 
426  virtual bool needs_source_state() { return get_needs_null_check(); }
427 
428  /**
429  * Conversion method.
430  */
431  virtual DereferenceInst *to_DereferenceInst() = 0;
432 
433  virtual ~DereferenceInst() {}
434 };
435 
436 /**
437  * This Instruction marks the start of a basic block.
438  */
439 class BeginInst : public Instruction {
440 public:
441 
443  typedef PredecessorListTy::const_iterator const_pred_iterator;
444 
445 private:
446 
449 
451  pred_list[index] = BI;
452  }
453  void set_successor(int index, BeginInst *BI);
454 
455 public:
456  explicit BeginInst() : Instruction(BeginInstID, Type::VoidTypeID) {
457  end = NULL;
458  }
459  explicit BeginInst(EndInst *end) : Instruction(BeginInstID, Type::VoidTypeID), end(end) {}
460  virtual BeginInst* to_BeginInst() { return this; }
461  virtual BeginInst *get_BeginInst() const { return const_cast<BeginInst*>(this); }
462  int get_predecessor_index(const BeginInst* BI) const {
463  if (BI) {
464  int index = 0;
465  for (PredecessorListTy::const_iterator i = pred_list.begin(),
466  e = pred_list.end(); i != e; ++i) {
467  if (BI == (*i)) {
468  return index;
469  }
470  index++;
471  }
472  }
473  return -1;
474  }
476  if (index < 0 || (unsigned)index > pred_size()) {
477  return NULL;
478  }
479  PredecessorListTy::const_iterator i = pred_list.begin();
480  while(index--) {
481  ++i;
482  }
483  assert(i != pred_list.end());
484  return *i;
485  }
486  int get_successor_index(const BeginInst* BI) const;
487 
488  EndInst *get_EndInst() const { return end; }
489  void set_EndInst(EndInst* e) { end = e; }
490  virtual bool is_floating() const { return false; }
491 
492  const_pred_iterator pred_begin() const { return pred_list.begin(); }
493  const_pred_iterator pred_end() const { return pred_list.end(); }
494  std::size_t pred_size() const { return pred_list.size(); }
495 
496  friend class EndInst;
497  friend class Method;
498  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
499 };
500 
501 /**
502  * This stores a reference to a BeginInst.
503  */
505 private:
507 public:
508  // constructor
509  explicit BeginInstRef(BeginInst* BI) : begin(BI) {}
510  /// copy constructor
511  BeginInstRef(const BeginInstRef &other) : begin(other.begin) {}
512  /// copy assignment operator
514  begin = other.begin;
515  return (*this);
516  }
517  // assign BeginInst
519  begin = BI;
520  return (*this);
521  }
522  // conversion
523  operator BeginInst*() {
524  return begin;
525  }
526  // getter
527  BeginInst* get() const {
528  return begin;
529  }
530 };
531 
532 inline OStream& operator<<(OStream &OS, const BeginInstRef &BIR) {
533  return OS << BIR.get();
534 }
535 
536 /**
537  * This Instruction marks the end of a basic block.
538  */
539 class EndInst : public Instruction {
540 public:
542  typedef SuccessorListTy::const_iterator succ_const_iterator;
543  typedef SuccessorListTy::const_reverse_iterator succ_const_reverse_iterator;
544 private:
547  succ_list[index] = BI;
548  }
549 public:
550  explicit EndInst(BeginInst* begin) : Instruction(EndInstID, Type::VoidTypeID, begin) {
551  assert(begin);
552  begin->set_EndInst(this);
553  }
554  explicit EndInst(InstID id, BeginInst* begin) : Instruction(id, Type::VoidTypeID, begin) {
555  assert(begin);
556  begin->set_EndInst(this);
557  }
558  virtual EndInst* to_EndInst() { return this; }
559  virtual bool is_floating() const { return false; }
560 
561  void append_succ(BeginInst* bi) {
562  assert(bi);
563  succ_list.push_back(BeginInstRef(bi));
564  assert(begin);
565  bi->pred_list.push_back(begin);
566  }
567 
568  int get_successor_index(const BeginInst* BI) const {
569  if (BI) {
570  int index = 0;
571  for (SuccessorListTy::const_iterator i = succ_list.begin(),
572  e = succ_list.end(); i != e; ++i) {
573  if (BI == i->get()) {
574  return index;
575  }
576  index++;
577  }
578  }
579  return -1;
580  }
581  SuccessorListTy::const_iterator succ_begin() const { return succ_list.begin(); }
582  SuccessorListTy::const_iterator succ_end() const { return succ_list.end(); }
583  SuccessorListTy::const_reverse_iterator succ_rbegin() const { return succ_list.rbegin(); }
584  SuccessorListTy::const_reverse_iterator succ_rend() const { return succ_list.rend(); }
585  BeginInstRef &succ_front() { return succ_list.front(); }
586  BeginInstRef &succ_back() { return succ_list.back(); }
587  size_t succ_size() const { return succ_list.size(); }
588 
590  assert(i < succ_size());
591  return succ_list[i];
592  }
593 
594  friend class BeginInst;
595  friend class Method;
596  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
597 };
598 
599 inline int BeginInst::get_successor_index(const BeginInst* BI) const {
600  return get_EndInst()->get_successor_index(BI);
601 }
603  get_EndInst()->set_successor(index,BI);
604 }
605 
606 // Instructions
607 
608 /**
609  * Represents an explicit null-check on an object reference.
610  */
612 public:
613 
614  /**
615  * Construct a CHECKNULLInst.
616  *
617  * @param objectref The object reference to check.
618  */
619  explicit CHECKNULLInst(Value *objectref)
620  : UnaryInst(CHECKNULLInstID, Type::VoidTypeID, objectref) {
621  assert(objectref != NULL);
622  append_op(objectref);
623  }
624 
625  /**
626  * @see Instruction::is_homogeneous()
627  */
628  virtual bool is_homogeneous() const { return false; }
629 
630  /**
631  * Conversion method.
632  */
633  virtual Instruction *to_Instruction() { return this; }
634 
635  /**
636  * Conversion method.
637  */
638  virtual SourceStateAwareInst *to_SourceStateAwareInst() { return this; }
639 
640  /**
641  * Conversion method.
642  */
643  virtual CHECKNULLInst *to_CHECKNULLInst() { return this; }
644 
645  /**
646  * Visitor pattern.
647  */
648  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
649 };
650 
651 /**
652  * Get the length of an array.
653  */
654 class ARRAYLENGTHInst : public UnaryInst, public DereferenceInst {
655 public:
656 
657  /**
658  * Construct an ARRAYLENGTHInst.
659  *
660  * @param arrayref The array of interest.
661  */
662  explicit ARRAYLENGTHInst(Value *arrayref)
663  : UnaryInst(ARRAYLENGTHInstID, Type::IntTypeID, arrayref) {}
664 
666  Instruction *objectref = (*op_begin())->to_Instruction();
667  assert(objectref);
668  return objectref;
669  }
670 
671  /**
672  * Conversion method.
673  */
674  virtual Instruction* to_Instruction() { return this; }
675 
676  virtual SourceStateAwareInst* to_SourceStateAwareInst() { return this; }
677 
678  /**
679  * Conversion method.
680  */
681  virtual DereferenceInst* to_DereferenceInst() { return this; }
682 
683  /**
684  * Conversion method.
685  */
686  virtual ARRAYLENGTHInst* to_ARRAYLENGTHInst() { return this; }
687 
688  /**
689  * @see Instruction::is_homogeneous()
690  */
691  virtual bool is_homogeneous() const { return false; }
692 
693  /**
694  * Visitor pattern.
695  */
696  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
697 };
698 
699 class NEGInst : public UnaryInst {
700 public:
701  explicit NEGInst(Type::TypeID type,Value *S1) : UnaryInst(NEGInstID, type, S1) {}
702  virtual NEGInst* to_NEGInst() { return this; }
703  virtual bool is_arithmetic() const { return true; }
704  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
705 };
706 
707 class CASTInst : public UnaryInst {
708 public:
710  : UnaryInst(CASTInstID, type, s1) {
711  }
712  virtual CASTInst* to_CASTInst() { return this; }
713  virtual bool is_homogeneous() const { return false; }
714  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
715 };
716 
717 class ADDInst : public BinaryInst {
718 public:
719  explicit ADDInst(Type::TypeID type, Value* S1, Value* S2) : BinaryInst(ADDInstID, type, S1, S2) {}
720  virtual ADDInst* to_ADDInst() { return this; }
721  virtual bool is_arithmetic() const { return true; }
722  virtual bool is_commutable() const { return true; }
723  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
724 };
725 
726 class SUBInst : public BinaryInst{
727 public:
728  explicit SUBInst(Type::TypeID type, Value* S1, Value* S2) : BinaryInst(SUBInstID, type, S1, S2) {}
729  virtual SUBInst* to_SUBInst() { return this; }
730  virtual bool is_arithmetic() const { return true; }
731  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
732 };
733 
734 class MULInst : public BinaryInst {
735 public:
736  explicit MULInst(Type::TypeID type, Value* S1, Value* S2) : BinaryInst(MULInstID, type, S1, S2) {}
737  virtual MULInst* to_MULInst() { return this; }
738  virtual bool is_arithmetic() const { return true; }
739  virtual bool is_commutable() const { return true; }
740  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
741 };
742 
743 class DIVInst : public BinaryInst {
744 public:
745  explicit DIVInst(Type::TypeID type, Value* S1, Value* S2) : BinaryInst(DIVInstID, type, S1, S2) {}
746  virtual DIVInst* to_DIVInst() { return this; }
747  virtual bool is_arithmetic() const { return true; }
748  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
749 };
750 
751 class REMInst : public BinaryInst {
752 public:
753  explicit REMInst(Type::TypeID type, Value* S1, Value* S2) : BinaryInst(REMInstID, type, S1, S2) {}
754  virtual REMInst* to_REMInst() { return this; }
755  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
756 };
757 
758 class SHLInst : public Instruction {
759 public:
761  virtual SHLInst* to_SHLInst() { return this; }
762  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
763 };
764 
765 class USHRInst : public Instruction {
766 public:
768  virtual USHRInst* to_USHRInst() { return this; }
769  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
770 };
771 
772 class ANDInst : public BinaryInst {
773 public:
774  explicit ANDInst(Type::TypeID type, Value* S1, Value* S2) : BinaryInst(ANDInstID, type, S1, S2) {}
775  virtual ANDInst* to_ANDInst() { return this; }
776  virtual bool is_commutable() const { return true; }
777  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
778 };
779 
780 class ORInst : public BinaryInst {
781 public:
782  explicit ORInst(Type::TypeID type, Value* S1, Value* S2) : BinaryInst(ORInstID, type, S1, S2) {}
783  virtual ORInst* to_ORInst() { return this; }
784  virtual bool is_commutable() const { return true; }
785  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
786 };
787 
788 class XORInst : public BinaryInst {
789 public:
790  explicit XORInst(Type::TypeID type, Value* S1, Value* S2) : BinaryInst(XORInstID, type, S1, S2) {}
791  virtual XORInst* to_XORInst() { return this; }
792  virtual bool is_commutable() const { return true; }
793  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
794 };
795 
796 class CMPInst : public BinaryInst {
797 public:
799  G,
800  L,
802  };
803  explicit CMPInst(Value* S1, Value* S2, FloatHandling f) : BinaryInst(CMPInstID, Type::IntTypeID, S1, S2), f(f) {}
804  virtual CMPInst* to_CMPInst() { return this; }
805  virtual bool is_homogeneous() const { return false; }
806  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
807  FloatHandling get_FloatHandling() const { return f; }
808 private:
810 };
811 
812 class CONSTInst : public Instruction {
813 private:
814  typedef union {
815  int32_t i;
816  int64_t l;
817  float f;
818  double d;
819  void *anyptr;
820  java_handle_t *stringconst; /* for ACONST with string */
821  classref_or_classinfo c; /* for ACONST with class */
822  } val_operand_t;
824 public:
825  explicit CONSTInst(int32_t i,Type::IntType) : Instruction(CONSTInstID, Type::IntTypeID) {
826  value.i = i;
827  }
828  explicit CONSTInst(int64_t l,Type::LongType) : Instruction(CONSTInstID, Type::LongTypeID) {
829  value.l = l;
830  }
831  explicit CONSTInst(float f,Type::FloatType) : Instruction(CONSTInstID, Type::FloatTypeID) {
832  value.f = f;
833  }
834  explicit CONSTInst(double d,Type::DoubleType) : Instruction(CONSTInstID, Type::DoubleTypeID) {
835  value.d = d;
836  }
837  explicit CONSTInst(void *anyptr,Type::ReferenceType) : Instruction(CONSTInstID, Type::ReferenceTypeID) {
838  value.anyptr = anyptr;
839  }
840  virtual CONSTInst* to_CONSTInst() { return this; }
841 
842  /**
843  * @bug this does not what one might expect! Do not use!
844  */
845  s8 get_value() const {
846  switch(get_type()) {
847  case Type::LongTypeID: return (s8)value.l;
848  case Type::IntTypeID: return (s8)value.i;
849  case Type::FloatTypeID: return (s8)value.f;
850  case Type::DoubleTypeID: return (s8)value.d;
851  default: assert(0); return 0;
852  }
853  return 0;
854  }
855  int32_t get_Int() const {
856  assert(get_type() == Type::IntTypeID);
857  return value.i;
858  }
859  int64_t get_Long() const {
860  assert(get_type() == Type::LongTypeID);
861  return value.l;
862  }
863  float get_Float() const {
864  assert(get_type() == Type::FloatTypeID);
865  return value.f;
866  }
867  double get_Double() const {
868  assert(get_type() == Type::DoubleTypeID);
869  return value.d;
870  }
871  void *get_Reference() const {
872  assert(get_type() == Type::ReferenceTypeID);
873  return value.anyptr;
874  }
875  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
876  virtual OStream& print(OStream& OS) const {
877  Instruction::print(OS);
878  switch(get_type()){
879  case Type::IntTypeID: return OS << " = " << get_Int();
880  case Type::LongTypeID: return OS << " = " << get_Long();
881  case Type::FloatTypeID: return OS << " = " << get_Float();
882  case Type::DoubleTypeID: return OS << " = " << get_Double();
883  default: break;
884  }
885  return OS;
886  }
887 };
888 
889 /**
890  * Base class of instructions that access a field on a class or object.
891  */
892 class FieldAccessInst : public Instruction {
893 private:
894 
895  /**
896  * The accessed field.
897  */
899 
900 public:
901 
902  /**
903  * Construct a FieldAccessInst.
904  *
905  * @param id The corresponding InstID.
906  * @param type The corresponding type.
907  * @param field The accessed field.
908  */
910  : Instruction(id, type), field(field) {
911  assert(field);
912  }
913 
914  /**
915  * Get the accessed field.
916  */
917  fieldinfo *get_field() const { return field; }
918 };
919 
920 /**
921  * Get the value of an object's field.
922  */
924 public:
925 
926  /**
927  * Construct a GETFIELDInst.
928  *
929  * @param type The type of the value to read from the field.
930  * @param objectref The object whose field is accessed.
931  * @param field The accessed field.
932  * @param begin The BeginInst of the block that contains this GETFIELDInst.
933  * @param state_change The previous side-effecting Instruction.
934  */
935  explicit GETFIELDInst(Type::TypeID type, Value *objectref,
936  fieldinfo *field, BeginInst *begin, Instruction *state_change)
937  : FieldAccessInst(GETFIELDInstID, type, field) {
938  assert(objectref);
939  assert(begin);
940  assert(state_change);
941 
942  append_op(objectref);
943  append_dep(begin);
944  append_dep(state_change);
945  }
946 
947  /**
948  * Get the BeginInst of the block that contains this GETFIELDInst.
949  */
950  virtual BeginInst* get_BeginInst() const {
952  assert(begin);
953  return begin;
954  }
955 
957  Instruction *objectref = (*op_begin())->to_Instruction();
958  assert(objectref);
959  return objectref;
960  }
961 
962  /**
963  * @see Instruction::is_homogeneous()
964  */
965  virtual bool is_homogeneous() const { return false; }
966 
967  /**
968  * For now consider as fixed to avoid illegal instruction reordering.
969  */
970  virtual bool is_floating() const { return false; }
971 
972  virtual Instruction* to_Instruction() { return this; }
973 
974  virtual SourceStateAwareInst* to_SourceStateAwareInst() { return this; }
975 
976  /**
977  * Conversion method.
978  */
979  virtual DereferenceInst* to_DereferenceInst() { return this; }
980 
981  /**
982  * Conversion method.
983  */
984  virtual GETFIELDInst* to_GETFIELDInst() { return this; }
985 
986  /**
987  * Visitor pattern.
988  */
989  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
990 };
991 
992 /**
993  * Write a value to an object's field.
994  */
996 public:
997 
998  /**
999  * Construct a PUTFIELDInst.
1000  *
1001  * @param objectref The object whose field is accessed.
1002  * @param value The value to write.
1003  * @param field The accessed field.
1004  * @param begin The BeginInst of the block that contains this PUTFIELDInst.
1005  * @param state_change The previous side-effecting Instruction.
1006  */
1007  explicit PUTFIELDInst(Value *objectref, Value *value, fieldinfo *field,
1008  BeginInst* begin, Instruction *state_change)
1009  : FieldAccessInst(PUTFIELDInstID, value->get_type(), field) {
1010  assert(objectref);
1011  assert(value);
1012  assert(begin);
1013  assert(state_change);
1014 
1015  append_op(objectref);
1016  append_op(value);
1017  append_dep(begin);
1018  append_dep(state_change);
1019  }
1020 
1021  /**
1022  * Get the BeginInst of the block that contains this PUTFIELDInst.
1023  */
1024  virtual BeginInst* get_BeginInst() const {
1026  assert(begin);
1027  return begin;
1028  }
1029 
1031  Instruction *objectref = (*op_begin())->to_Instruction();
1032  assert(objectref);
1033  return objectref;
1034  }
1035 
1036  /**
1037  * @see Instruction::is_homogeneous()
1038  */
1039  virtual bool is_homogeneous() const { return false; }
1040 
1041  /**
1042  * A PUTFIELDInst might change the global state.
1043  */
1044  virtual bool has_side_effects() const { return true; }
1045 
1046  /**
1047  * A PUTFIELDInst is not allowed to float.
1048  */
1049  virtual bool is_floating() const { return false; }
1050 
1051  virtual Instruction* to_Instruction() { return this; }
1052 
1053  virtual SourceStateAwareInst* to_SourceStateAwareInst() { return this; }
1054 
1055  /**
1056  * Conversion method.
1057  */
1058  virtual DereferenceInst* to_DereferenceInst() { return this; }
1059 
1060  /**
1061  * Conversion method.
1062  */
1063  virtual PUTFIELDInst* to_PUTFIELDInst() { return this; }
1064 
1065  /**
1066  * Visitor pattern.
1067  */
1068  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
1069 };
1070 
1071 /**
1072  * Get the value of a static field.
1073  */
1075 public:
1076 
1077  /**
1078  * Construct a GETSTATICInst.
1079  *
1080  * @param type The type of the value to read from the field.
1081  * @param field The accessed field.
1082  * @param begin The BeginInst of the block that contains this GETSTATICInst.
1083  * @param state_change The previous side-effecting Instruction.
1084  */
1086  BeginInst *begin, Instruction *state_change)
1087  : FieldAccessInst(GETSTATICInstID, type, field) {
1088  assert(begin);
1089  assert(state_change);
1090 
1091  append_dep(begin);
1092  append_dep(state_change);
1093  }
1094 
1095  /**
1096  * Get the BeginInst of the block that contains this GETSTATICInst.
1097  */
1098  virtual BeginInst* get_BeginInst() const {
1100  assert(begin);
1101  return begin;
1102  }
1103 
1104  /**
1105  * @see Instruction::is_homogeneous()
1106  */
1107  virtual bool is_homogeneous() const { return false; }
1108 
1109  /**
1110  * For now consider as fixed to avoid illegal instruction reordering.
1111  */
1112  virtual bool is_floating() const { return false; }
1113 
1114  /**
1115  * Conversion method.
1116  */
1117  virtual GETSTATICInst* to_GETSTATICInst() { return this; }
1118 
1119  /**
1120  * Visitor pattern.
1121  */
1122  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
1123 };
1124 
1125 /**
1126  * Write a value to a static field.
1127  */
1129 public:
1130 
1131  /**
1132  * Construct a PUTSTATICInst.
1133  *
1134  * @param value The value to write.
1135  * @param field The accessed field.
1136  * @param begin The BeginInst of the block that contains this PUTSTATICInst.
1137  * @param state_change The previous side-effecting Instruction.
1138  */
1139  explicit PUTSTATICInst(Value *value, fieldinfo *field,
1140  BeginInst* begin, Instruction *state_change)
1141  : FieldAccessInst(PUTSTATICInstID, value->get_type(), field) {
1142  assert(value);
1143  assert(begin);
1144  assert(state_change);
1145 
1146  append_op(value);
1147  append_dep(begin);
1148  append_dep(state_change);
1149  }
1150 
1151  /**
1152  * Get the BeginInst of the block that contains this PUTSTATICInst.
1153  */
1154  virtual BeginInst* get_BeginInst() const {
1156  assert(begin);
1157  return begin;
1158  }
1159 
1160  /**
1161  * @see Instruction::is_homogeneous()
1162  */
1163  virtual bool is_homogeneous() const { return false; }
1164 
1165  /**
1166  * A PUTSTATICInst changes the global state.
1167  */
1168  virtual bool has_side_effects() const { return true; }
1169 
1170  /**
1171  * A PUTSTATICInst is not allowed to float.
1172  */
1173  virtual bool is_floating() const { return false; }
1174 
1175  /**
1176  * Conversion method.
1177  */
1178  virtual PUTSTATICInst* to_PUTSTATICInst() { return this; }
1179 
1180  /**
1181  * Visitor pattern.
1182  */
1183  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
1184 };
1185 
1186 class INCInst : public Instruction {
1187 public:
1189  virtual INCInst* to_INCInst() { return this; }
1190  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
1191 };
1192 
1193 class AREFInst : public Instruction, public DereferenceInst {
1194 public:
1196  : Instruction(AREFInstID, type) {
1197  assert(ref->get_type() == Type::ReferenceTypeID);
1198  assert(index->get_type() == Type::IntTypeID);
1199  assert(begin);
1200  append_op(ref);
1201  append_op(index);
1202  append_dep(begin);
1203  }
1204 
1205  /**
1206  * Get the BeginInst of the block that contains this AREFInst.
1207  */
1208  virtual BeginInst* get_BeginInst() const {
1210  assert(begin);
1211  return begin;
1212  }
1213 
1215  Instruction *objectref = (*op_begin())->to_Instruction();
1216  assert(objectref);
1217  return objectref;
1218  }
1219 
1220  virtual Instruction* to_Instruction() { return this; }
1221 
1222  virtual SourceStateAwareInst* to_SourceStateAwareInst() { return this; }
1223 
1224  /**
1225  * Conversion method.
1226  */
1227  virtual DereferenceInst* to_DereferenceInst() { return this; }
1228 
1229  virtual AREFInst* to_AREFInst() { return this; }
1230  virtual bool is_homogeneous() const { return false; }
1231  virtual bool is_floating() const { return false; }
1232  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
1233 };
1234 
1235 /**
1236  * Store a value into an array.
1237  *
1238  * TODO The JVM specification uses "astore" to refer to an operation that
1239  * stores a reference to a local variable. To avoid confusion we should
1240  * therefore rename this class to something more uncontentious like
1241  * "ArrayStoreInst".
1242  */
1243 class ASTOREInst : public Instruction, public DereferenceInst {
1244 public:
1245 
1246  /**
1247  * Construct an ASTOREInst.
1248  *
1249  * @param type The type of the value to store.
1250  * @param ref The reference to the accessed array element.
1251  * @param begin The BeginInst of the block that contains the ASTOREInst.
1252  * @param state_change The previous side-effect.
1253  */
1254  explicit ASTOREInst(Type::TypeID type, Value* ref, Value* value,
1255  BeginInst *begin, Instruction *state_change)
1256  : Instruction(ASTOREInstID, Type::VoidTypeID) {
1257  append_op(ref);
1258  append_op(value);
1259  append_dep(begin);
1260  append_dep(state_change);
1261  }
1262 
1263  /**
1264  * Get the BeginInst of the block that contains this ASTOREInst.
1265  */
1266  virtual BeginInst* get_BeginInst() const {
1268  assert(begin);
1269  return begin;
1270  }
1271 
1273  AREFInst *aref = (*op_begin())->to_Instruction()->to_AREFInst();
1274  assert(aref);
1275  Instruction *objectref = aref->get_objectref();
1276  return objectref;
1277  }
1278 
1279  /**
1280  * @see Instruction::is_homogeneous()
1281  */
1282  virtual bool is_homogeneous() const { return false; }
1283 
1284  /**
1285  * An ASTOREInst might change the global state.
1286  */
1287  virtual bool has_side_effects() const { return true; }
1288 
1289  /**
1290  * An ASTOREInst is not allowed to float.
1291  */
1292  virtual bool is_floating() const { return false; }
1293 
1294  virtual Instruction* to_Instruction() { return this; }
1295 
1296  virtual SourceStateAwareInst* to_SourceStateAwareInst() { return this; }
1297 
1298  /**
1299  * Conversion method.
1300  */
1301  virtual DereferenceInst* to_DereferenceInst() { return this; }
1302 
1303  /**
1304  * Conversion method.
1305  */
1306  virtual ASTOREInst* to_ASTOREInst() { return this; }
1307 
1308  /**
1309  * Visitor pattern.
1310  */
1311  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
1312 };
1313 
1314 /**
1315  * Load a value from an array.
1316  *
1317  * TODO The JVM specification uses "aload" to refer to an operation that
1318  * stores a reference to a local variable. To avoid confusion we should
1319  * therefore rename this class to something more uncontentious like
1320  * "ArrayLoadInst".
1321  */
1322 class ALOADInst : public Instruction, public DereferenceInst {
1323 public:
1324 
1325  /**
1326  * Construct an ALOADInst.
1327  *
1328  * @param type The type of the accessed array element.
1329  * @param ref The reference to the accessed array element.
1330  * @param begin The BeginInst of the block that contains the ALOADInst.
1331  * @param state_change The previous side-effect.
1332  */
1334  BeginInst *begin, Instruction *state_change)
1335  : Instruction(ALOADInstID, type) {
1336  append_op(ref);
1337  append_dep(begin);
1338  append_dep(state_change);
1339  }
1340 
1341  /**
1342  * Get the BeginInst of the block that contains this ALOADInst.
1343  */
1344  virtual BeginInst* get_BeginInst() const {
1345  assert(dep_size() > 0);
1346  return dep_front()->to_BeginInst();
1347  }
1348 
1350  AREFInst *aref = (*op_begin())->to_Instruction()->to_AREFInst();
1351  assert(aref);
1352  Instruction *objectref = aref->get_objectref();
1353  return objectref;
1354  }
1355 
1356  /**
1357  * @see Instruction::is_homogeneous()
1358  */
1359  virtual bool is_homogeneous() const { return false; }
1360 
1361  /**
1362  * For now consider as fixed to avoid illegal instruction reordering.
1363  */
1364  virtual bool is_floating() const { return false; }
1365 
1366  virtual Instruction* to_Instruction() { return this; }
1367 
1368  virtual SourceStateAwareInst* to_SourceStateAwareInst() { return this; }
1369 
1370  /**
1371  * Conversion method.
1372  */
1373  virtual DereferenceInst* to_DereferenceInst() { return this; }
1374 
1375  /**
1376  * Conversion method.
1377  */
1378  virtual ALOADInst* to_ALOADInst() { return this; }
1379 
1380  /**
1381  * Visitor pattern.
1382  */
1383  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
1384 };
1385 
1386 /**
1387  * Perform a bounds-check for an array-access.
1388  */
1390 public:
1391 
1392  /**
1393  * Construct an ARRAYBOUNDSCHECKInst.
1394  *
1395  * @param arrayref The reference to the accessed array.
1396  * @param index The accessed index.
1397  */
1398  explicit ARRAYBOUNDSCHECKInst(Value* arrayref, Value* index)
1399  : BinaryInst(ARRAYBOUNDSCHECKInstID, Type::VoidTypeID, arrayref, index) {
1400  assert(arrayref != NULL);
1401  assert(arrayref->get_type() == Type::ReferenceTypeID);
1402  assert(index != NULL);
1403  assert(index->get_type() == Type::IntTypeID);
1404  }
1405 
1407  Instruction *objectref = (*op_begin())->to_Instruction();
1408  assert(objectref);
1409  return objectref;
1410  }
1411 
1412  /**
1413  * @see Instruction::is_homogeneous()
1414  */
1415  virtual bool is_homogeneous() const { return false; }
1416 
1417  /**
1418  * Casting method.
1419  */
1420  virtual Instruction *to_Instruction() { return this; }
1421 
1422  /**
1423  * Casting method.
1424  */
1425  virtual SourceStateAwareInst *to_SourceStateAwareInst() { return this; }
1426 
1427  /**
1428  * Conversion method.
1429  */
1430  virtual DereferenceInst* to_DereferenceInst() { return this; }
1431 
1432  /**
1433  * Casting method.
1434  */
1435  virtual ARRAYBOUNDSCHECKInst *to_ARRAYBOUNDSCHECKInst() { return this; }
1436 
1437  /**
1438  * Visitor pattern.
1439  */
1440  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
1441 };
1442 
1443 /**
1444  * A LOADInst represents an argument that is passed to the current method.
1445  */
1446 class LOADInst : public Instruction {
1447 private:
1448 
1449  /**
1450  * The index of the argument that is represented by this LOADInst.
1451  */
1452  unsigned index;
1453 
1454 public:
1455 
1456  /**
1457  * Construct a LOADInst.
1458  *
1459  * @param type The type of the method-argument.
1460  * @param index The index of the method-argument.
1461  * @param begin The initial BeginInst of the current method.
1462  */
1464  : Instruction(LOADInstID, type, begin), index(index) {}
1465 
1466  /**
1467  * Conversion method.
1468  */
1469  virtual LOADInst* to_LOADInst() { return this; }
1470 
1471  /**
1472  * The index of the argument is represented by this LOADInst.
1473  */
1474  unsigned get_index() const { return index; }
1475 
1476  /**
1477  * A LOADInst must not float, it has to stay in the method's initial block.
1478  */
1479  bool is_floating() const { return false; }
1480 
1481  /**
1482  * Visitor pattern.
1483  */
1484  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
1485 };
1486 
1487 class NEWInst : public Instruction {
1488 public:
1490  virtual NEWInst* to_NEWInst() { return this; }
1491  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
1492 };
1493 
1494 class NEWARRAYInst : public Instruction {
1495 public:
1497  virtual NEWARRAYInst* to_NEWARRAYInst() { return this; }
1498  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
1499 };
1500 
1501 class ANEWARRAYInst : public Instruction {
1502 public:
1504  virtual ANEWARRAYInst* to_ANEWARRAYInst() { return this; }
1505  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
1506 };
1507 
1509 public:
1511  virtual MULTIANEWARRAYInst* to_MULTIANEWARRAYInst() { return this; }
1512  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
1513 };
1514 
1515 class CHECKCASTInst : public Instruction {
1516 public:
1518  virtual CHECKCASTInst* to_CHECKCASTInst() { return this; }
1519  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
1520 };
1521 
1522 class INSTANCEOFInst : public Instruction {
1523 public:
1525  virtual INSTANCEOFInst* to_INSTANCEOFInst() { return this; }
1526  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
1527 };
1528 
1529 class GOTOInst : public EndInst {
1530 private:
1531  /**
1532  * @note this is for expert use only.
1533  * You will have to adjust the successor (and the backlink) manually.
1534  */
1536  : EndInst(GOTOInstID, begin) {}
1537 public:
1538  explicit GOTOInst(BeginInst *begin, BeginInst* targetBlock)
1539  : EndInst(GOTOInstID, begin) {
1540  append_succ(targetBlock);
1541  }
1542  virtual GOTOInst* to_GOTOInst() { return this; }
1544  return succ_front();
1545  }
1546  friend class Method;
1547  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
1548 };
1549 
1550 /**
1551  * Base type of instruction that perform a method invocation.
1552  */
1553 class INVOKEInst : public MultiOpInst {
1554 private:
1555 
1556  /**
1557  * The MethodDescriptor of the method to invoke.
1558  */
1560 
1561  /**
1562  * Holds information about the method to invoke.
1563  */
1565 
1566 public:
1567 
1568  /**
1569  * Construct an INVOKEInst.
1570  *
1571  * @param ID The corresponding InstID.
1572  * @param type The return type.
1573  * @param size The number of method parameters.
1574  * @param fmiref The reference to the corresponding methodinfo.
1575  * @param begin The block that contains the invocation.
1576  * @param state_chage The previous side-effect.
1577  */
1578  explicit INVOKEInst(InstID ID, Type::TypeID type, unsigned size,
1579  constant_FMIref *fmiref, BeginInst *begin, Instruction *state_change, SourceStateInst *source_state)
1580  : MultiOpInst(ID, type), MD(size),
1581  fmiref(fmiref) {
1582  assert(state_change && state_change->get_name());
1583  append_dep(begin);
1584  append_dep(state_change);
1585  append_dep(source_state);
1586  }
1587 
1588  /**
1589  * Get the BeginInst of the block that contains this INVOKEInst.
1590  */
1591  virtual BeginInst* get_BeginInst() const {
1593  assert(begin);
1594  return begin;
1595  }
1596 
1598  auto it = std::next(dep_begin(), 2);
1599  SourceStateInst *source_state = (*it)->to_SourceStateInst();
1600  assert(source_state);
1601  return source_state;
1602  }
1603 
1604  /**
1605  * @see Instruction::is_homogeneous()
1606  */
1607  virtual bool is_homogeneous() const { return false; }
1608 
1609  /**
1610  * Pessimistically assume that each kind of invocation has side-effects.
1611  */
1612  virtual bool has_side_effects() const { return true; }
1613 
1614  /**
1615  * An INVOKEInst is not allowed to float, it has to stay fixed in the CFG.
1616  */
1617  virtual bool is_floating() const { return false; }
1618 
1619  /**
1620  * Append a parameter that has to be passed to the invoked method.
1621  *
1622  * @param V The corresponding parameter.
1623  */
1625  std::size_t i = op_size();
1626  assert(i < MD.size());
1627  MD[i] = V->get_type();
1628  append_op(V);
1629  }
1630 
1631  /**
1632  * Get the MethodDescriptor of the method to invoke.
1633  */
1635  assert(MD.size() == op_size());
1636  return MD;
1637  }
1638 
1639  /**
1640  * Get information about the method to invoke.
1641  */
1642  constant_FMIref* get_fmiref() const { return fmiref; }
1643 
1644  /**
1645  * Conversion method.
1646  */
1647  virtual INVOKEInst* to_INVOKEInst() { return this; }
1648 
1649  /**
1650  * Visitor pattern.
1651  */
1652  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
1653 };
1654 
1655 /**
1656  * Invoke a static method.
1657  */
1659 public:
1660 
1661  /**
1662  * Construct an INVOKESTATICInst.
1663  *
1664  * @param type The return type.
1665  * @param size The number of method parameters.
1666  * @param fmiref The reference to the corresponding methodinfo.
1667  * @param begin The BeginInst of the block that contains this INVOKESTATICInst.
1668  * @param state_change The previous side-effect.
1669  */
1671  constant_FMIref *fmiref, BeginInst *begin, Instruction *state_change, SourceStateInst *source_state)
1672  : INVOKEInst(INVOKESTATICInstID, type, size, fmiref, begin, state_change, source_state) {}
1673 
1674  /**
1675  * Conversion method.
1676  */
1677  virtual INVOKESTATICInst* to_INVOKESTATICInst() { return this; }
1678 
1679  /**
1680  * Visitor pattern.
1681  */
1682  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
1683 };
1684 
1685 /**
1686  * Invoke an instance method.
1687  */
1689 public:
1690 
1691  /**
1692  * Construct an INVOKEVIRTUALInst.
1693  *
1694  * @param type The return type.
1695  * @param size The number of method parameters.
1696  * @param fmiref The reference to the corresponding methodinfo.
1697  * @param begin The BeginInst of the block that contains this INVOKEVIRTUALInst.
1698  * @param state_change The previous side-effect.
1699  */
1702  : INVOKEInst(INVOKEVIRTUALInstID, type, size, fmiref, begin, state_change, source_state) {}
1703 
1705  Instruction *objectref = (*op_begin())->to_Instruction();
1706  assert(objectref);
1707  return objectref;
1708  }
1709 
1710  virtual Instruction* to_Instruction() { return this; }
1711 
1712  virtual SourceStateAwareInst* to_SourceStateAwareInst() { return this; }
1713 
1714  /**
1715  * Conversion method.
1716  */
1717  virtual DereferenceInst* to_DereferenceInst() { return this; }
1718 
1719  /**
1720  * Conversion method.
1721  */
1722  virtual INVOKEVIRTUALInst* to_INVOKEVIRTUALInst() { return this; }
1723 
1724  /**
1725  * Visitor pattern.
1726  */
1727  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
1728 };
1729 
1730 /**
1731  * Invoke an instance method with special handling.
1732  */
1734 public:
1735 
1736  /**
1737  * Construct an INVOKESPECIALInst.
1738  *
1739  * @param type The return type.
1740  * @param size The number of method parameters.
1741  * @param fmiref The reference to the corresponding methodinfo.
1742  * @param begin The BeginInst of the block that contains this INVOKESPECIALInst.
1743  * @param state_change The previous side-effect.
1744  */
1746  constant_FMIref *fmiref, BeginInst *begin, Instruction *state_change, SourceStateInst *source_state)
1747  : INVOKEInst(INVOKESPECIALInstID, type, size, fmiref, begin, state_change, source_state) {}
1748 
1749  /**
1750  * Conversion method.
1751  */
1752  virtual INVOKESPECIALInst* to_INVOKESPECIALInst() { return this; }
1753 
1754  /**
1755  * Visitor pattern.
1756  */
1757  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
1758 };
1759 
1760 /**
1761  * Invoke an interface method.
1762  */
1764 public:
1765 
1766  /**
1767  * Construct an INVOKEINTERFACEInst.
1768  *
1769  * @param type The return type.
1770  * @param size The number of method parameters.
1771  * @param fmiref The reference to the corresponding methodinfo.
1772  * @param begin The BeginInst of the block that contains this INVOKEINTERFACEInst.
1773  * @param state_change The previous side-effect.
1774  */
1777  : INVOKEInst(INVOKEINTERFACEInstID, type, size, fmiref, begin, state_change, source_state) {}
1778 
1780  Instruction *objectref = (*op_begin())->to_Instruction();
1781  assert(objectref);
1782  return objectref;
1783  }
1784 
1785  virtual Instruction* to_Instruction() { return this; }
1786 
1787  virtual SourceStateAwareInst* to_SourceStateAwareInst() { return this; }
1788 
1789  /**
1790  * Conversion method.
1791  */
1792  virtual DereferenceInst* to_DereferenceInst() { return this; }
1793 
1794  /**
1795  * Conversion method.
1796  */
1797  virtual INVOKEINTERFACEInst* to_INVOKEINTERFACEInst() { return this; }
1798 
1799  /**
1800  * Visitor pattern.
1801  */
1802  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
1803 };
1804 
1805 /**
1806  * Invoke a builtin.
1807  */
1808 class BUILTINInst : public INVOKEInst {
1809 private:
1810 
1811  /**
1812  * A pointer to the function that implements the builtin functionality.
1813  */
1815 
1816 public:
1817 
1818  /**
1819  * Construct a BUILTINInst.
1820  *
1821  * @param type The return type.
1822  * @param address A pointer to the function that implements the builtin
1823  * functionality.
1824  * @param size The number of parameters for the invocation.
1825  * @param begin The BeginInst of the block that contains this BUILTINInst.
1826  * @param state_change The previous side-effect.
1827  */
1828  explicit BUILTINInst(Type::TypeID type, u1 *address, unsigned size,
1829  BeginInst *begin, Instruction *state_change, SourceStateInst *source_state)
1830  : INVOKEInst(BUILTINInstID, type, size, NULL, begin, state_change, source_state), address(address) {}
1831 
1832  /**
1833  * Get the pointer to the function that implements the builtin functionality.
1834  */
1835  u1 *get_address() const {
1836  return address;
1837  }
1838 
1839  /**
1840  * Conversion method.
1841  */
1842  virtual BUILTINInst* to_BUILTINInst() { return this; }
1843 
1844  /**
1845  * Visitor pattern.
1846  */
1847  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
1848 };
1849 
1850 class IFInst : public EndInst, public CondInst {
1851 public:
1853  BeginInst* trueBlock, BeginInst* falseBlock)
1854  : EndInst(IFInstID, begin), CondInst(cond) {
1855  append_op(S1);
1856  append_op(S2);
1857  append_succ(trueBlock);
1858  append_succ(falseBlock);
1859  assert(S1->get_type() == S2->get_type());
1860  set_type(S1->get_type());
1861  }
1862  virtual IFInst* to_IFInst() { return this; }
1865  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
1866 };
1867 
1868 class IF_CMPInst : public Instruction {
1869 public:
1871  virtual IF_CMPInst* to_IF_CMPInst() { return this; }
1872  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
1873 };
1874 
1875 class TABLESWITCHInst : public EndInst {
1876 private:
1879 public:
1880  /// wrapper for type safety
1881  struct LOW {
1883  explicit LOW(s4 low) : low(low) {}
1884  };
1885  /// wrapper for type safety
1886  struct HIGH {
1888  explicit HIGH(s4 high) : high(high) {}
1889  };
1890  /// constructor
1891  explicit TABLESWITCHInst(BeginInst *begin, Value* S1, LOW low, HIGH high)
1892  : EndInst(TABLESWITCHInstID, begin), tablelow(low.low), tablehigh(high.high) {
1893  assert(tablehigh >= tablelow);
1894  append_op(S1);
1896  }
1897 
1898  s4 get_low() const { return tablelow; }
1899  s4 get_high() const { return tablehigh; }
1900  virtual TABLESWITCHInst* to_TABLESWITCHInst() { return this; }
1901  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
1902 
1903  virtual bool verify() const {
1904  if (tablehigh < tablelow ) {
1905  ERROR_MSG("TABLESWITCH verification error","tablehigh ("<<tablehigh
1906  << ") is greater then tablelow ("<< tablelow << ")");
1907  return false;
1908  }
1909  if (succ_size() != std::size_t(tablehigh - tablelow + 1 + 1)) {
1910  ERROR_MSG("TABLESWITCH verification error","Number of successors (" << succ_size()
1911  << ") not equal to targets (" << tablehigh - tablelow +1 << ")");
1912  return false;
1913  }
1914  return Instruction::verify();
1915  }
1916 };
1917 
1918 class LOOKUPSWITCHInst : public EndInst {
1919 public:
1921  typedef MatchTy::iterator match_iterator;
1922 private:
1925 public:
1926  /// wrapper for type safety
1927  struct MATCH {
1929  explicit MATCH(s4 match) : match(match) {}
1930  };
1932  : EndInst(LOOKUPSWITCHInstID, begin), lookupcount(lookupcount), matches(lookupcount) {
1933  append_op(S1);
1935  }
1936  virtual LOOKUPSWITCHInst* to_LOOKUPSWITCHInst() { return this; }
1937  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
1938  void set_match(s4 index, MATCH match) {
1939  assert(index >= 0 && index < lookupcount);
1940  matches[index] = match.match;
1941  }
1943  return matches[index];
1944  }
1946  return matches.begin();
1947  }
1949  return matches.end();
1950  }
1951  virtual bool verify() const {
1952  if ( lookupcount < 0) {
1953  ERROR_MSG("LOOKUPSWITCH verification error","Lookup count is negative ("
1954  << lookupcount << ")");
1955  return false;
1956  }
1957  if (succ_size() != std::size_t(lookupcount + 1)) {
1958  ERROR_MSG("LOOKUPSWITCH verification error","Number of successors (" << succ_size()
1959  << ") not equal to targets (" << lookupcount + 1 << ")");
1960  return false;
1961  }
1962  return Instruction::verify();
1963  }
1964 };
1965 
1966 /**
1967  * Return from the current method.
1968  */
1969 class RETURNInst : public EndInst {
1970 public:
1971 
1972  /**
1973  * Construct a RETURNInst that ends a void method.
1974  *
1975  * @param begin The corresponding BeginInst.
1976  */
1978 
1979  /**
1980  * Construct a RETURNInst that ends a method by returning @p S1.
1981  *
1982  * @param begin The corresponding BeginInst.
1983  * @param S1 The value to return.
1984  */
1985  explicit RETURNInst(BeginInst *begin, Value* S1) : EndInst(RETURNInstID, begin) {
1986  append_op(S1);
1987  set_type(S1->get_type());
1988  }
1989 
1990  /**
1991  * Conversion method.
1992  */
1993  virtual RETURNInst* to_RETURNInst() { return this; }
1994 
1995  /**
1996  * Visitor pattern.
1997  */
1998  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
1999 };
2000 
2001 class THROWInst : public Instruction {
2002 public:
2004  virtual THROWInst* to_THROWInst() { return this; }
2005  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
2006 };
2007 
2008 class PHIInst : public MultiOpInst {
2009 public:
2011  append_dep(begin);
2012  }
2013  virtual PHIInst* to_PHIInst() { return this; }
2014 
2015  virtual BeginInst* get_BeginInst() const {
2017  assert(begin);
2018  return begin;
2019  }
2020  virtual bool is_floating() const { return false; }
2021 
2022  // exporting to the public
2023  using Instruction::append_op;
2024  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
2025 };
2026 
2027 /**
2028  * A point where the method can be entered through on-stack replacement.
2029  */
2031 public:
2032 
2033  /**
2034  * Construct a ReplacementEntryInst.
2035  *
2036  * @param begin The corresponding BeginInst.
2037  * @param source_state The corresponding source state.
2038  */
2040  : Instruction(ReplacementEntryInstID, Type::VoidTypeID) {
2041  assert(begin);
2042  assert(source_state);
2043  append_dep(begin);
2044  append_dep(source_state);
2045  }
2046 
2047  /**
2048  * Get the BeginInst this ReplacementEntryInst is attached to.
2049  */
2050  virtual BeginInst* get_BeginInst() const {
2051  assert(dep_size() >= 1);
2053  assert(begin);
2054  return begin;
2055  }
2056 
2057  /**
2058  * Get the source state at this ReplacementEntryInst.
2059  *
2060  * The source state is used to reconstruct the stack frame for the
2061  * optimized code. Since optimized code is currently only entered at method
2062  * entry, the information that is captured by the source state is
2063  * sufficient for this task.
2064  */
2066  assert(dep_size() >= 2);
2067  SourceStateInst *source_state = (*(++dep_begin()))->to_SourceStateInst();
2068  assert(source_state);
2069  return source_state;
2070  }
2071 
2072  /**
2073  * Conversion method.
2074  */
2075  virtual ReplacementEntryInst* to_ReplacementEntryInst() { return this; }
2076 
2077  /**
2078  * A ReplacementEntryInst is fixed to the method's initial BeginInst.
2079  */
2080  virtual bool is_floating() const { return false; }
2081 
2082  /**
2083  * Visitor pattern.
2084  */
2085  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
2086 };
2087 
2088 /**
2089  * Represents a speculative assumption that has to be checked at run-time.
2090  *
2091  * Optimizations that rely on speculative assumptions may generate
2092  * AssumptionInst in order to avoid the illegal execution of speculatively
2093  * transformed program regions. In case a speculation fails at run-time,
2094  * deoptimization will be triggered to transfer execution back to an
2095  * unoptimized version of this method.
2096  */
2098 private:
2099 
2100  /**
2101  * The entry to the region of code that relies on this assumption.
2102  */
2104 
2105 public:
2106 
2107  /**
2108  * Construct an AssumptionInst.
2109  *
2110  * @param condition A boolean HIR expression that encodes the
2111  * speculative assumption to check.
2112  * @param guarded_block The entry to the region of the code that relies on
2113  * this assumption and thus needs to be guarded
2114  * against illegal execution.
2115  */
2117  : Instruction(AssumptionInstID, Type::VoidTypeID) {
2118  assert(condition);
2119  assert(condition->get_type() != Type::VoidTypeID);
2120  append_op(condition);
2121  this->guarded_block = guarded_block;
2122  guarded_block->append_dep(this);
2123  }
2124 
2125  /**
2126  * Get the entry to the region of code that relies on this assumption.
2127  */
2128  virtual BeginInst *get_guarded_block() const {
2129  return guarded_block;
2130  }
2131 
2132  /**
2133  * @see Instruction::is_homogeneous()
2134  */
2135  virtual bool is_homogeneous() const { return false; }
2136 
2137  /**
2138  * Conversion method.
2139  */
2140  virtual Instruction *to_Instruction() { return this; }
2141 
2142  /**
2143  * Conversion method.
2144  */
2145  virtual SourceStateAwareInst *to_SourceStateAwareInst() { return this; }
2146 
2147  /**
2148  * Conversion method.
2149  */
2150  virtual AssumptionInst *to_AssumptionInst() { return this; }
2151 
2152  /**
2153  * Visitor pattern.
2154  */
2155  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
2156 };
2157 
2158 /**
2159  * Transfers execution back to an unoptimized version of the method.
2160  */
2162 public:
2163 
2164  /**
2165  * Construct a DeoptimizeInst.
2166  *
2167  * @param begin The corresponding BeginInst.
2168  */
2170  : EndInst(DeoptimizeInstID, begin) {
2172  }
2173 
2174  /**
2175  * A DeoptimizeInst is fixed in the CFG and therefore non-floating.
2176  */
2177  virtual bool is_floating() const { return false; }
2178 
2179  /**
2180  * Conversion method.
2181  */
2182  virtual Instruction *to_Instruction() { return this; }
2183 
2184  /**
2185  * Conversion method.
2186  */
2187  virtual SourceStateAwareInst *to_SourceStateAwareInst() { return this; }
2188 
2189  /**
2190  * Conversion method.
2191  */
2192  virtual DeoptimizeInst *to_DeoptimizeInst() { return this; }
2193 
2194  /**
2195  * Visitor pattern.
2196  */
2197  virtual void accept(InstructionVisitor& v, bool copyOperands) { v.visit(this, copyOperands); }
2198 };
2199 
2200 } // end namespace compiler2
2201 } // end namespace jit
2202 } // end namespace cacao
2203 
2204 #endif /* _JIT_COMPILER2_INSTRUCTIONS */
2205 
2206 
2207 /*
2208  * These are local overrides for various environment variables in Emacs.
2209  * Please do not remove this and leave it at the end of the file, where
2210  * Emacs will automagically detect them.
2211  * ---------------------------------------------------------------------
2212  * Local variables:
2213  * mode: c++
2214  * indent-tabs-mode: t
2215  * c-basic-offset: 4
2216  * tab-width: 4
2217  * End:
2218  * vim:noexpandtab:sw=4:ts=4:
2219  */
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
virtual Instruction * to_Instruction()
PHIInst(Type::TypeID type, BeginInst *begin)
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
virtual BeginInst * get_BeginInst() const
Get the BeginInst this ReplacementEntryInst is attached to.
ParamListTy params
List of HIR values that correspond to method parameters.
virtual bool is_arithmetic() const
True if the instruction is an arithmetic instruction.
virtual AREFInst * to_AREFInst()
CONSTInst(double d, Type::DoubleType)
virtual Instruction * to_Instruction()
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
std::size_t index
INVOKESTATICInst(Type::TypeID type, unsigned size, constant_FMIref *fmiref, BeginInst *begin, Instruction *state_change, SourceStateInst *source_state)
Construct an INVOKESTATICInst.
virtual BeginInst * get_guarded_block() const
Get the entry to the region of code that relies on this assumption.
virtual bool is_floating() const
For now consider as fixed to avoid illegal instruction reordering.
virtual bool is_homogeneous() const
virtual CASTInst * to_CASTInst()
alloc::vector< Javalocal >::type JavalocalListTy
virtual OStream & print(OStream &OS) const
print
Definition: Instruction.cpp:43
PUTFIELDInst(Value *objectref, Value *value, fieldinfo *field, BeginInst *begin, Instruction *state_change)
Construct a PUTFIELDInst.
virtual DereferenceInst * to_DereferenceInst()
Conversion method.
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
virtual bool is_commutable() const
True if the operands of the instruction are commutable.
JNIEnv jthread jmethodID jlocation jclass jobject jfieldID field
Definition: jvmti.h:221
virtual INVOKEINTERFACEInst * to_INVOKEINTERFACEInst()
Conversion method.
virtual Instruction * get_objectref()
Get the corresponding object reference.
virtual INVOKESPECIALInst * to_INVOKESPECIALInst()
Conversion method.
virtual IF_CMPInst * to_IF_CMPInst()
virtual INVOKESTATICInst * to_INVOKESTATICInst()
Conversion method.
Conditional::CondID condition
The kind of condition that is computed.
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
BeginInst * get_predecessor(int index) const
XORInst(Type::TypeID type, Value *S1, Value *S2)
alloc::vector< Value * >::type StackvarListTy
virtual bool is_floating() const
True if the instruction has no fixed control dependencies.
virtual Instruction * to_Instruction()
Conversion method.
GETSTATICInst(Type::TypeID type, fieldinfo *field, BeginInst *begin, Instruction *state_change)
Construct a GETSTATICInst.
SourceStateInst * get_source_state() const
Get the SourceStateInst that corresponds to this Instruction.
virtual BUILTINInst * to_BUILTINInst()
Conversion method.
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
Maps a HIR value to a baseline IR javalocal index.
const_javalocal_iterator javalocal_end() const
virtual Instruction * get_objectref()
Get the corresponding object reference.
CMPInst(Value *S1, Value *S2, FloatHandling f)
virtual Instruction * get_objectref()
Get the corresponding object reference.
virtual BeginInst * get_BeginInst() const
Get the BeginInst of the block that contains this ALOADInst.
virtual INSTANCEOFInst * to_INSTANCEOFInst()
virtual DereferenceInst * to_DereferenceInst()
Conversion method.
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
fieldinfo * get_field() const
Get the accessed field.
INVOKESPECIALInst(Type::TypeID type, unsigned size, constant_FMIref *fmiref, BeginInst *begin, Instruction *state_change, SourceStateInst *source_state)
Construct an INVOKESPECIALInst.
Write a value to a static field.
virtual bool is_arithmetic() const
True if the instruction is an arithmetic instruction.
BeginInst * BI
Type::TypeID get_type() const
get the value type of the instruction
Definition: Value.hpp:68
virtual BeginInst * get_BeginInst() const
Get the BeginInst of the block that contains this ASTOREInst.
SourceStateInst(s4 source_location, Instruction *hir_location)
Construct a SourceStateInst.
NEGInst(Type::TypeID type, Value *S1)
Get the value of an object&#39;s field.
virtual MULInst * to_MULInst()
PredecessorListTy::const_iterator const_pred_iterator
Base type of instruction that perform a method invocation.
virtual bool is_floating() const
For now we prevent floating to avoid unforeseen instruction reordering.
virtual SHLInst * to_SHLInst()
void set_source_state(SourceStateInst *source_state)
Set the SourceStateInst that corresponds to this Instruction.
void set_needs_null_check(bool needs_null_check)
Control whether a null-check is needed to safeguard the dereference.
Load a value from an array.
virtual BeginInst * get_BeginInst() const
Get the BeginInst of the block that contains this SourceStateInst.
virtual BinaryInst * to_BinaryInst()
Conversion method.
virtual Instruction * to_Instruction()
virtual bool is_homogeneous() const
virtual SourceStateAwareInst * to_SourceStateAwareInst()
const char * get_name() const
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
BeginInstRef(const BeginInstRef &other)
copy constructor
int get_successor_index(const BeginInst *BI) const
INVOKEVIRTUALInst(Type::TypeID type, unsigned size, constant_FMIref *fmiref, BeginInst *begin, Instruction *state_change, SourceStateInst *source_state)
Construct an INVOKEVIRTUALInst.
This Instruction marks the start of a basic block.
virtual SourceStateAwareInst * to_SourceStateAwareInst()
virtual GETFIELDInst * to_GETFIELDInst()
Conversion method.
virtual SourceStateAwareInst * to_SourceStateAwareInst()
Casting method.
u2 op
Definition: disass.cpp:129
virtual bool is_floating() const
True if the instruction has no fixed control dependencies.
This Instruction marks the end of a basic block.
const_dep_iterator dep_begin() const
void append_javalocal(Javalocal local)
Append a new mapping from a HIR Value to a baseline IR javalocal index.
TABLESWITCHInst(BeginInst *begin, Value *S1, LOW low, HIGH high)
constructor
virtual SourceStateAwareInst * to_SourceStateAwareInst()
Conversion method.
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
bool is_floating() const
A LOADInst must not float, it has to stay in the method&#39;s initial block.
AREFInst(Type::TypeID type, Value *ref, Value *index, BeginInst *begin)
const_stackvar_iterator stackvar_begin() const
BeginInstRef & operator=(BeginInst *BI)
virtual CMPInst * to_CMPInst()
virtual SourceStateAwareInst * to_SourceStateAwareInst()
Transfers execution back to an unoptimized version of the method.
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
virtual XORInst * to_XORInst()
void set_successor(int index, BeginInst *BI)
virtual SourceStateAwareInst * to_SourceStateAwareInst()
Conversion method.
Get the value of a static field.
virtual bool is_homogeneous() const
u1 * address
A pointer to the function that implements the builtin functionality.
ADDInst(Type::TypeID type, Value *S1, Value *S2)
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
virtual Instruction * get_objectref()=0
Get the corresponding object reference.
virtual DereferenceInst * to_DereferenceInst()
Conversion method.
fieldinfo * field
The accessed field.
virtual bool is_floating() const
True if the instruction has no fixed control dependencies.
A point where the method can be entered through on-stack replacement.
IFInst(BeginInst *begin, Value *S1, Value *S2, Conditional::CondID cond, BeginInst *trueBlock, BeginInst *falseBlock)
BeginInstRef & operator=(const BeginInstRef &other)
copy assignment operator
virtual ALOADInst * to_ALOADInst()
Conversion method.
virtual DereferenceInst * to_DereferenceInst()
Conversion method.
virtual UnaryInst * to_UnaryInst()
Conversion method.
virtual bool verify() const
Check if the instruction is in a correct state.
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
alloc::vector< BeginInstRef >::type SuccessorListTy
Write a value to an object&#39;s field.
virtual CHECKNULLInst * to_CHECKNULLInst()
Conversion method.
return true
Definition: PatcherNew.cpp:104
constant_FMIref * fmiref
Holds information about the method to invoke.
CONSTInst(int64_t l, Type::LongType)
INVOKEInst(InstID ID, Type::TypeID type, unsigned size, constant_FMIref *fmiref, BeginInst *begin, Instruction *state_change, SourceStateInst *source_state)
Construct an INVOKEInst.
uint8_t u1
Definition: types.hpp:40
virtual bool is_floating() const
A ReplacementEntryInst is fixed to the method&#39;s initial BeginInst.
virtual Instruction * to_Instruction()
Conversion method.
#define ERROR_MSG(EXPR_SHORT, EXPR_LONG)
Definition: logging.hpp:124
Perform a bounds-check for an array-access.
virtual bool is_homogeneous() const
int get_successor_index(const BeginInst *BI) const
virtual ARRAYLENGTHInst * to_ARRAYLENGTHInst()
Conversion method.
GOTOInst(BeginInst *begin, BeginInst *targetBlock)
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
const_pred_iterator pred_begin() const
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
SourceStateInst * get_parent() const
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
SourceStateAwareInst()
Construct a SourceStateAwareInst.
BUILTINInst(Type::TypeID type, u1 *address, unsigned size, BeginInst *begin, Instruction *state_change, SourceStateInst *source_state)
Construct a BUILTINInst.
int64_t s8
Definition: types.hpp:48
virtual Instruction * to_Instruction()
Conversion method.
virtual BeginInst * get_BeginInst() const
Get the BeginInst of the block that contains this GETSTATICInst.
virtual Instruction * get_objectref()
Get the corresponding object reference.
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
virtual Instruction * to_Instruction()
Convert this SourceStateAwareInst to an Instruction.
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
virtual CONSTInst * to_CONSTInst()
virtual PHIInst * to_PHIInst()
DeoptimizeInst(BeginInst *begin)
Construct a DeoptimizeInst.
virtual INVOKEVIRTUALInst * to_INVOKEVIRTUALInst()
Conversion method.
Base class of instructions that access a field on a class or object.
ALOADInst(Type::TypeID type, Value *ref, BeginInst *begin, Instruction *state_change)
Construct an ALOADInst.
virtual SourceStateInst * to_SourceStateInst()
Conversion method.
JNIEnv jthread jobject jclass jlong size
Definition: jvmti.h:387
const_param_iterator param_begin() const
virtual INCInst * to_INCInst()
virtual SourceStateAwareInst * to_SourceStateAwareInst()
virtual Instruction * get_objectref()
Get the corresponding object reference.
Represents an explicit null-check on an object reference.
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
EndInst(InstID id, BeginInst *begin)
virtual Instruction * get_objectref()
Get the corresponding object reference.
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
virtual Instruction * get_objectref()
Get the corresponding object reference.
const_param_iterator param_end() const
Store a value into an array.
StackvarListTy stackvars
List of HIR values that correspond to baseline IR stack variables.
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
virtual BeginInst * get_BeginInst() const
Get the BeginInst of the block that contains this PUTSTATICInst.
SuccessorListTy::const_reverse_iterator succ_rbegin() const
unsigned index
The index of the argument that is represented by this LOADInst.
This stores a reference to a BeginInst.
const_javalocal_iterator javalocal_begin() const
Base type of instructions that can be mapped to a SourceStateInst.
virtual ORInst * to_ORInst()
virtual SourceStateAwareInst * to_SourceStateAwareInst()
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
REMInst(Type::TypeID type, Value *S1, Value *S2)
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
constant_FMIref * get_fmiref() const
Get information about the method to invoke.
void append_param(Value *value)
Append a new value to corresponds to a method parameter.
Represents a speculative assumption that has to be checked at run-time.
ReplacementEntryInst(BeginInst *begin, SourceStateInst *source_state)
Construct a ReplacementEntryInst.
SuccessorListTy::const_reverse_iterator succ_rend() const
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
virtual bool has_side_effects() const
Pessimistically assume that each kind of invocation has side-effects.
Javalocal(Value *value, std::size_t index)
Construct a Javalocal that maps value to index.
Base type of instructions with an arbitrary number of operands.
virtual DereferenceInst * to_DereferenceInst()
Conversion method.
SuccessorListTy::const_iterator succ_end() const
SourceStateInst * get_source_state() const
Get the source state at this ReplacementEntryInst.
bool needs_null_check
Whether a null-check is needed to safeguard the dereference.
CONSTInst(float f, Type::FloatType)
virtual THROWInst * to_THROWInst()
ARRAYBOUNDSCHECKInst(Value *arrayref, Value *index)
Construct an ARRAYBOUNDSCHECKInst.
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
StackvarListTy::const_iterator const_stackvar_iterator
virtual bool verify() const
Check if the instruction is in a correct state.
Definition: Instruction.cpp:82
int get_predecessor_index(const BeginInst *BI) const
virtual bool is_floating() const
A PUTFIELDInst is not allowed to float.
virtual GETSTATICInst * to_GETSTATICInst()
Conversion method.
virtual PUTFIELDInst * to_PUTFIELDInst()
Conversion method.
virtual bool is_homogeneous() const
virtual NEGInst * to_NEGInst()
CONSTInst(void *anyptr, Type::ReferenceType)
JavalocalListTy::const_iterator const_javalocal_iterator
Invoke an instance method with special handling.
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
Base type of instructions with a single operand.
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
virtual OStream & print(OStream &OS) const
print
Provides a mapping from HIR values to baseline IR variables.
virtual bool is_floating() const
For now consider as fixed to avoid illegal instruction reordering.
Conditional::CondID get_condition() const
Get the kind of condition that is computed.
virtual bool is_floating() const
True if the instruction has no fixed control dependencies.
std::vector< T, Allocator< T > > type
Definition: vector.hpp:38
Base type of instructions that compute a condition.
virtual bool is_commutable() const
True if the operands of the instruction are commutable.
virtual AssumptionInst * to_AssumptionInst()
Conversion method.
virtual bool is_homogeneous() const
True if the instruction has a homogeneous signature.
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
virtual AREFInst * to_AREFInst()
Definition: Instruction.hpp:57
virtual LOADInst * to_LOADInst()
Conversion method.
virtual DeoptimizeInst * to_DeoptimizeInst()
Conversion method.
alloc::vector< Value * >::type ParamListTy
u1 * get_address() const
Get the pointer to the function that implements the builtin functionality.
Simple stream class for formatted output.
Definition: OStream.hpp:141
Instruction * dep_front() const
virtual DereferenceInst * to_DereferenceInst()
Conversion method.
virtual Instruction * get_objectref()
Get the corresponding object reference.
Instruction super class.
Definition: Instruction.hpp:75
virtual Instruction * to_Instruction()
Casting method.
virtual REMInst * to_REMInst()
DIVInst(Type::TypeID type, Value *S1, Value *S2)
virtual void replace_op(Value *v_old, Value *v_new)
virtual ANDInst * to_ANDInst()
OStream & operator<<(OStream &OS, const Conditional::CondID &cond)
Definition: Conditional.cpp:34
const_stackvar_iterator stackvar_end() const
virtual void replace_op(Value *v_old, Value *v_new)
Definition: Instruction.cpp:66
JNIEnv jthread jmethodID void * address
Definition: jvmti.h:264
virtual SourceStateAwareInst * to_SourceStateAwareInst()
virtual Instruction * to_Instruction()
MIIterator i
virtual bool is_arithmetic() const
True if the instruction is an arithmetic instruction.
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
Fieldref, Methodref and InterfaceMethodref.
Definition: references.hpp:86
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
virtual ASTOREInst * to_ASTOREInst()
Conversion method.
virtual DereferenceInst * to_DereferenceInst()=0
Conversion method.
virtual SourceStateAwareInst * to_SourceStateAwareInst()
Conversion method.
int32_t s4
Definition: types.hpp:45
virtual RETURNInst * to_RETURNInst()
Conversion method.
SuccessorListTy::const_iterator succ_begin() const
virtual BeginInst * get_BeginInst() const
Get the BeginInst of the block that contains this AREFInst.
MethodDescriptor & get_MethodDescriptor()
Get the MethodDescriptor of the method to invoke.
virtual bool is_homogeneous() const
True if the instruction has a homogeneous signature.
BeginInstRef & get_successor(size_t i)
SourceStateInst * parent
The state of the enclosing method in case we are in an inlined region.
SuccessorListTy::const_reverse_iterator succ_const_reverse_iterator
BeginInst * guarded_block
The entry to the region of code that relies on this assumption.
virtual BeginInst * to_BeginInst()
OStream & OS
SourceStateInst * source_state
The SourceStateInst that corresponds to this Instruction.
ANDInst(Type::TypeID type, Value *S1, Value *S2)
const_op_iterator op_begin() const
virtual DereferenceInst * to_DereferenceInst()
Conversion method.
RETURNInst(BeginInst *begin)
Construct a RETURNInst that ends a void method.
virtual bool is_floating() const
An ASTOREInst is not allowed to float.
JavalocalListTy javalocals
List of mappings from HIR values to baseline IR javalocal indices.
Base type of instructions with two operands.
MethodDescriptor MD
The MethodDescriptor of the method to invoke.
CHECKNULLInst(Value *objectref)
Construct a CHECKNULLInst.
virtual bool is_floating() const
True if the instruction has no fixed control dependencies.
virtual bool is_floating() const
For now consider as fixed to avoid illegal instruction reordering.
virtual Instruction * to_Instruction()
Conversion method.
SuccessorListTy::const_iterator succ_const_iterator
MIIterator e
virtual CHECKCASTInst * to_CHECKCASTInst()
ASTOREInst(Type::TypeID type, Value *ref, Value *value, BeginInst *begin, Instruction *state_change)
Construct an ASTOREInst.
Get the length of an array.
virtual bool is_floating() const
A DeoptimizeInst is fixed in the CFG and therefore non-floating.
CASTInst(Type::TypeID type, Value *s1)
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
virtual SUBInst * to_SUBInst()
virtual GOTOInst * to_GOTOInst()
virtual ARRAYBOUNDSCHECKInst * to_ARRAYBOUNDSCHECKInst()
Casting method.
virtual bool has_side_effects() const
A PUTFIELDInst might change the global state.
virtual SourceStateInst * get_SourceStateInst() const
void set_predecessor(int index, BeginInst *BI)
virtual INVOKEInst * to_INVOKEInst()
Conversion method.
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
#define I(value)
Definition: codegen.c:279
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
virtual bool is_commutable() const
True if the operands of the instruction are commutable.
void append_succ(BeginInst *bi)
virtual DereferenceInst * to_DereferenceInst()
Conversion method.
virtual bool has_side_effects() const
An ASTOREInst might change the global state.
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
virtual ANEWARRAYInst * to_ANEWARRAYInst()
ARRAYLENGTHInst(Value *arrayref)
Construct an ARRAYLENGTHInst.
virtual BeginInst * get_BeginInst() const
Get the BeginInst of the block that contains this GETFIELDInst.
virtual SourceStateAwareInst * to_SourceStateAwareInst()
alloc::vector< BeginInst * >::type PredecessorListTy
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
ParamListTy::const_iterator const_param_iterator
virtual bool is_arithmetic() const
True if the instruction is an arithmetic instruction.
virtual NEWARRAYInst * to_NEWARRAYInst()
UnaryInst(InstID id, Type::TypeID type, Value *op)
Construct a UnaryInst.
virtual MULTIANEWARRAYInst * to_MULTIANEWARRAYInst()
SUBInst(Type::TypeID type, Value *S1, Value *S2)
virtual bool is_arithmetic() const
True if the instruction is an arithmetic instruction.
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
const_pred_iterator pred_end() const
virtual Instruction * to_Instruction()
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
virtual LOOKUPSWITCHInst * to_LOOKUPSWITCHInst()
virtual PUTSTATICInst * to_PUTSTATICInst()
Conversion method.
int8_t s1
Definition: types.hpp:39
virtual SourceStateAwareInst * to_SourceStateAwareInst()
virtual Instruction * get_objectref()
Get the corresponding object reference.
GETFIELDInst(Type::TypeID type, Value *objectref, fieldinfo *field, BeginInst *begin, Instruction *state_change)
Construct a GETFIELDInst.
bool get_needs_null_check() const
Whether a null-check is needed to safeguard the dereference.
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
virtual TABLESWITCHInst * to_TABLESWITCHInst()
unsigned get_index() const
The index of the argument is represented by this LOADInst.
RETURNInst(BeginInst *begin, Value *S1)
Construct a RETURNInst that ends a method by returning S1.
BinaryInst(InstID id, Type::TypeID type, Value *op1, Value *op2)
Construct a BinaryInst.
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
virtual bool is_commutable() const
True if the operands of the instruction are commutable.
virtual EndInst * to_EndInst()
Base type of instructions that dereference an object reference.
static java_object_t * next
Definition: copy.c:43
virtual bool is_commutable() const
True if the operands of the instruction are commutable.
virtual DereferenceInst * to_DereferenceInst()
Conversion method.
virtual Instruction * to_Instruction()=0
Convert this SourceStateAwareInst to an Instruction.
AssumptionInst(Value *condition, BeginInst *guarded_block)
Construct an AssumptionInst.
PUTSTATICInst(Value *value, fieldinfo *field, BeginInst *begin, Instruction *state_change)
Construct a PUTSTATICInst.
LOADInst(Type::TypeID type, unsigned index, BeginInst *begin)
Construct a LOADInst.
void set_parent(SourceStateInst *new_parent)
Set state of the enclosing method in case we are in an inlined region.
virtual BeginInst * to_BeginInst()
Definition: Instruction.hpp:81
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
INVOKEINTERFACEInst(Type::TypeID type, unsigned size, constant_FMIref *fmiref, BeginInst *begin, Instruction *state_change, SourceStateInst *source_state)
Construct an INVOKEINTERFACEInst.
virtual bool is_homogeneous() const
True if the instruction has a homogeneous signature.
virtual bool verify() const
Check if the instruction is in a correct state.
virtual bool is_homogeneous() const
virtual DIVInst * to_DIVInst()
virtual BeginInst * get_BeginInst() const
Get the BeginInst of the block that contains this PUTFIELDInst.
virtual bool has_side_effects() const
A PUTSTATICInst changes the global state.
void set_successor(int index, BeginInst *BI)
void append_stackvar(Value *value)
Append a new value to corresponds to a baseline IR stack variable.
void set_match(s4 index, MATCH match)
virtual void visit(UnaryInst *I, bool copyOperands)
std::size_t index
A baseline IR javalocal index.
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
virtual bool is_floating() const
A PUTSTATICInst is not allowed to float.
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
virtual BeginInst * get_BeginInst() const
Get the BeginInst of the block that contains this INVOKEInst.
CondInst(Conditional::CondID condition)
Construct a CondInst.
CONSTInst(int32_t i, Type::IntType)
FieldAccessInst(InstID id, Type::TypeID type, fieldinfo *field)
Construct a FieldAccessInst.
void set_type(Type::TypeID t)
Definition: Value.hpp:63
virtual USHRInst * to_USHRInst()
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
virtual NEWInst * to_NEWInst()
void append_parameter(Value *V)
Append a parameter that has to be passed to the invoked method.
Value * value
The value that is mapped to a baseline IR javalocal index.
ORInst(Type::TypeID type, Value *S1, Value *S2)
std::size_t pred_size() const
A LOADInst represents an argument that is passed to the current method.
virtual BeginInst * get_BeginInst() const
Get the corresponding BeginInst.
MultiOpInst(InstID id, Type::TypeID type)
Construct a MultiOpInst.
MULInst(Type::TypeID type, Value *S1, Value *S2)
virtual ReplacementEntryInst * to_ReplacementEntryInst()
Conversion method.
virtual bool is_floating() const
An INVOKEInst is not allowed to float, it has to stay fixed in the CFG.
FloatHandling get_FloatHandling() const
s4 source_location
The program location corresponding to the provided mapping information.
virtual Instruction * to_Instruction()
Convert this SourceStateAwareInst to an Instruction.
Return from the current method.
LOOKUPSWITCHInst(BeginInst *begin, Value *S1, s4 lookupcount)
virtual void accept(InstructionVisitor &v, bool copyOperands)
Visitor pattern.
virtual BeginInst * get_BeginInst() const
Get the corresponding BeginInst.
virtual ADDInst * to_ADDInst()
MethodDescriptor TODO: more info.