CACAO
Instruction.hpp
Go to the documentation of this file.
1 /* src/vm/jit/compiler2/Instruction.hpp - Instruction
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_INSTRUCTION
32 #define _JIT_COMPILER2_INSTRUCTION
33 
36 
37 // for Instruction::reset
39 
41 
44 #include <algorithm>
45 
46 #include <cstddef>
47 
48 namespace cacao {
49 
50 class OStream;
51 
52 namespace jit {
53 namespace compiler2 {
54 
55 // Forward declarations
57 
58 // include instruction declaration
60 
61 /**
62  * Instruction super class.
63  * This is the base class for all instruction. The functions 'toXInstruction()'
64  * can be used to cast Instructions. If casting is not possible these functions
65  * return NULL. Therefor it can be used to check for a specific Instruction, e.g.:
66  * <code>
67  * if (CmdInstruction* ti = i.toCmdInstruction()
68  * { // 'i' is a CmpInstruction
69  * ...
70  * }
71  * </code>
72  */
73 class Instruction : public Value {
74 public:
77 
78  typedef OperandListTy::iterator op_iterator;
79  typedef DepListTy::iterator dep_iterator;
80  typedef OperandListTy::const_iterator const_op_iterator;
81  typedef DepListTy::const_iterator const_dep_iterator;
82 
83  enum InstID {
84 
85 // include instruction ids
87 
89  };
90 private:
94  // this is probably a waste of space
95  static int id_counter;
96 
97  /**
98  * Reset static infos (run by Compiler)
99  */
100  static void reset() {
101  id_counter = 0;
102  }
103  friend MachineCode* compile(methodinfo*);
104 
105 protected:
106  const InstID opcode;
108  const int id;
110 
111  explicit Instruction() : Value(Type::VoidTypeID), opcode(NoInstID), id(-1), begin(NULL) {
112  }
113 
114  void append_op(Value* v) {
115  op_list.push_back(v);
116  v->append_user(this);
117  }
119  void replace_op(Value* v_old, Value* v_new);
121  /**
122  * @todo use Value::print_operands
123  */
126 public:
128  : Value(type), opcode(opcode), id(id_counter++), begin(begin) {
129  }
131  virtual ~Instruction();
133  int get_id() const { return id; } ///< return a unique identifier for this instruction
134  InstID get_opcode() const { return opcode; } ///< return the opcode of the instruction
136  void set_Method(Method* M) { method = M; }
137  Method* get_Method() const { return method; }
139  const_op_iterator op_begin() const { return op_list.begin(); }
140  const_op_iterator op_end() const { return op_list.end(); }
141  Value* op_front() const { return op_list.front(); }
142  Value* op_back() const { return op_list.back(); }
143  size_t op_size() const { return op_list.size(); }
144  Value* get_operand(size_t i) {
145  return op_list[i];
146  }
147  int get_operand_index(Value *op) const {
148  for (int i = 0, e = op_list.size(); i < e; ++i) {
149  if (op == op_list[i])
150  return i;
151  }
152  return -1;
153  }
156  assert(I);
157  dep_list.push_back(I);
158  I->reverse_dep_list.push_back(this);
159  }
160 
162  assert(I);
163  dep_list.remove(I);
164  I->reverse_dep_list.remove(this);
165  }
167  /// check if the instruction is in a correct state
168  virtual bool verify() const;
170  const_dep_iterator dep_begin() const { return dep_list.begin(); }
171  const_dep_iterator dep_end() const { return dep_list.end(); }
172  Instruction* dep_front() const { return dep_list.front(); }
173  Instruction* dep_back() const { return dep_list.back(); }
174  size_t dep_size() const { return dep_list.size(); }
175  const_dep_iterator rdep_begin() const { return reverse_dep_list.begin(); }
176  const_dep_iterator rdep_end() const { return reverse_dep_list.end(); }
177  size_t rdep_size() const { return reverse_dep_list.size(); }
178 
179  /**
180  * Get the corresponding BeginInst.
181  *
182  * BeginInst are used to mark control flow joins (aka the start of a basic block).
183  * @return The directly dominating BeginInst. NULL if there is none (eg. several
184  * cadidates or dead code).
185  */
186  virtual BeginInst *get_BeginInst() const { return begin; }
187  virtual bool set_BeginInst(BeginInst *b) {
188  if (is_floating()) {
189  begin = b;
190  return true;
191  }
192  assert(0 && "Trying to set BeginInst of a non floating instruction");
193  return false;
194  }
195 
196  /// True if the instruction has a homogeneous signature.
197  /// (i.e. all operands and the result have the same type)
198  virtual bool is_homogeneous() const { return true; }
199  /// True if the instruction has no fixed control dependencies
200  virtual bool is_floating() const { return true; }
201  /// True the instruction has side effects
202  virtual bool has_side_effects() const { return false; }
203  /// True if the instruction is an arithmetic instruction
204  virtual bool is_arithmetic() const { return false; }
205  /// True if the operands of the instruction are commutable
206  virtual bool is_commutable() const { return false; }
207 
208  // casting functions
209  virtual Instruction* to_Instruction() { return this; }
210 
211 // include to_XXXInst()'s
213 
214  const char* get_name() const {
215  switch (opcode) {
216 // include switch cases
218 
219  case NoInstID: return "NoInst";
220  }
221  return "Unknown Instruction";
222  }
223 
224  /// Visitor
225  virtual void accept(InstructionVisitor& v, bool copyOperands) = 0;
226 
227  virtual OStream& print(OStream& OS) const;
228 
229  // needed to access replace_op in replace_value
230  friend class Value;
231 };
232 
233 /**
234  * Less comparator for Instruction pointers.
235  *
236  * Use for std::set, std::map.
237  */
238 struct InstPtrLess :
239 public std::binary_function<const Instruction*, const Instruction*, bool> {
240  bool operator()(const Instruction *lhs, const Instruction *rhs) const {
241  return lhs->get_id() < rhs->get_id();
242  }
243 };
244 
245 inline OStream& operator<<(OStream &OS, const Instruction &I) {
246  return I.print(OS);
247 }
248 OStream& operator<<(OStream &OS, const Instruction *I);
249 
250 } // end namespace compiler2
251 } // end namespace jit
252 } // end namespace cacao
253 
254 #undef DEBUG_NAME
255 
256 #endif /* _JIT_COMPILER2_INSTRUCTION */
257 
258 
259 /*
260  * These are local overrides for various environment variables in Emacs.
261  * Please do not remove this and leave it at the end of the file, where
262  * Emacs will automagically detect them.
263  * ---------------------------------------------------------------------
264  * Local variables:
265  * mode: c++
266  * indent-tabs-mode: t
267  * c-basic-offset: 4
268  * tab-width: 4
269  * End:
270  * vim:noexpandtab:sw=4:ts=4:
271  */
Instruction * dep_back() const
virtual OStream & print(OStream &OS) const
print
Definition: Instruction.cpp:43
const_dep_iterator rdep_begin() const
void append_user(Instruction *I)
Definition: Value.hpp:54
const char * get_name() const
This Instruction mark the start of a basic block.
u2 op
Definition: disass.cpp:129
virtual void accept(InstructionVisitor &v, bool copyOperands)=0
Visitor.
const_dep_iterator dep_begin() const
OperandListTy::iterator op_iterator
Definition: Instruction.hpp:78
friend MachineCode * compile(methodinfo *)
Definition: Compiler.cpp:123
virtual bool is_floating() const
True if the instruction has no fixed control dependencies.
virtual bool has_side_effects() const
True the instruction has side effects.
Second stage compiler class.
virtual bool is_arithmetic() const
True if the instruction is an arithmetic instruction.
OperandListTy::const_iterator const_op_iterator
Definition: Instruction.hpp:80
std::list< T, Allocator< T > > type
Definition: list.hpp:38
InstID get_opcode() const
return the opcode of the instruction
OStream & print_operands(OStream &OS)
Definition: Instruction.cpp:75
virtual bool verify() const
check if the instruction is in a correct state
Definition: Instruction.cpp:82
JNIEnv jthread jmethodID method
Definition: jvmti.h:207
int get_id() const
return a unique identifier for this instruction
std::vector< T, Allocator< T > > type
Definition: vector.hpp:38
virtual bool is_commutable() const
True if the operands of the instruction are commutable.
virtual Instruction * to_Instruction()
Simple stream class for formatted output.
Definition: OStream.hpp:141
Instruction * dep_front() const
Instruction super class.
Definition: Instruction.hpp:73
OStream & operator<<(OStream &OS, const Conditional::CondID &cond)
Definition: Conditional.cpp:34
Less comparator for Instruction pointers.
alloc::vector< Value * >::type OperandListTy
Definition: Instruction.hpp:75
void replace_op(Value *v_old, Value *v_new)
Definition: Instruction.cpp:66
const_dep_iterator rdep_end() const
virtual bool is_homogeneous() const
True if the instruction has a homogeneous signature.
MIIterator i
DepListTy::const_iterator const_dep_iterator
Definition: Instruction.hpp:81
OStream & OS
const_op_iterator op_begin() const
int get_operand_index(Value *op) const
static void reset()
Reset static infos (run by Compiler)
MIIterator e
#define I(value)
Definition: codegen.c:279
virtual bool set_BeginInst(BeginInst *b)
const Method & M
const_dep_iterator dep_end() const
virtual BeginInst * get_BeginInst() const
Get the corresponding BeginInst.
bool operator()(const Instruction *lhs, const Instruction *rhs) const
DepListTy::iterator dep_iterator
Definition: Instruction.hpp:79
const_op_iterator op_end() const
alloc::list< Instruction * >::type DepListTy
Definition: Instruction.hpp:76
Instruction(InstID opcode, Type::TypeID type, BeginInst *begin=NULL)