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
59 
60 // include instruction declaration
62 
63 /**
64  * Instruction super class.
65  * This is the base class for all instruction. The functions 'toXInstruction()'
66  * can be used to cast Instructions. If casting is not possible these functions
67  * return NULL. Therefor it can be used to check for a specific Instruction, e.g.:
68  * <code>
69  * if (CmdInstruction* ti = i.toCmdInstruction()
70  * { // 'i' is a CmpInstruction
71  * ...
72  * }
73  * </code>
74  */
75 class Instruction : public Value {
76 public:
79 
80  typedef OperandListTy::iterator op_iterator;
81  typedef DepListTy::iterator dep_iterator;
82  typedef OperandListTy::const_iterator const_op_iterator;
83  typedef DepListTy::const_iterator const_dep_iterator;
84 
85  enum InstID {
86 
87 // include instruction ids
89 
90  NoInstID
91  };
92 private:
96  // this is probably a waste of space
97  static int id_counter;
98 
99  /**
100  * Reset static infos (run by Compiler)
101  */
102  static void reset() {
103  id_counter = 0;
104  }
105  friend MachineCode* compile(methodinfo*);
106 
107 protected:
108  const InstID opcode;
110  const int id;
112 
113  explicit Instruction() : Value(Type::VoidTypeID), opcode(NoInstID), id(-1), begin(NULL) {
114  }
115 
116  void append_op(Value* v) {
117  op_list.push_back(v);
118  v->append_user(this);
119  }
121  virtual void replace_op(Value* v_old, Value* v_new);
123  /**
124  * @todo use Value::print_operands
125  */
128 public:
130  : Value(type), opcode(opcode), id(id_counter++), begin(begin) {
131  }
133  virtual ~Instruction();
135  int get_id() const { return id; } ///< return a unique identifier for this instruction
136  InstID get_opcode() const { return opcode; } ///< return the opcode of the instruction
138  void set_Method(Method* M) { method = M; }
139  Method* get_Method() const { return method; }
141  const_op_iterator op_begin() const { return op_list.begin(); }
142  const_op_iterator op_end() const { return op_list.end(); }
143  Value* op_front() const { return op_list.front(); }
144  Value* op_back() const { return op_list.back(); }
145  size_t op_size() const { return op_list.size(); }
146  Value* get_operand(size_t i) {
147  return op_list[i];
148  }
149  int get_operand_index(Value *op) const {
150  for (int i = 0, e = op_list.size(); i < e; ++i) {
151  if (op == op_list[i])
152  return i;
153  }
154  return -1;
155  }
158  assert(I);
159  dep_list.push_back(I);
160  I->reverse_dep_list.push_back(this);
161  }
162 
164  assert(I);
165  dep_list.remove(I);
166  I->reverse_dep_list.remove(this);
167  }
169  /**
170  * Check if the instruction is in a correct state.
171  */
172  virtual bool verify() const;
174  const_dep_iterator dep_begin() const { return dep_list.begin(); }
175  const_dep_iterator dep_end() const { return dep_list.end(); }
176  Instruction* dep_front() const { return dep_list.front(); }
177  Instruction* dep_back() const { return dep_list.back(); }
178  size_t dep_size() const { return dep_list.size(); }
179  const_dep_iterator rdep_begin() const { return reverse_dep_list.begin(); }
180  const_dep_iterator rdep_end() const { return reverse_dep_list.end(); }
181  size_t rdep_size() const { return reverse_dep_list.size(); }
182 
183  /**
184  * Get the corresponding BeginInst.
185  *
186  * BeginInst are used to mark control flow joins (aka the start of a basic block).
187  * @return The directly dominating BeginInst. NULL if there is none (eg. several
188  * cadidates or dead code).
189  */
190  virtual BeginInst *get_BeginInst() const { return begin; }
191  virtual bool set_BeginInst(BeginInst *b) {
192  if (is_floating()) {
193  begin = b;
194  return true;
195  }
196  assert(0 && "Trying to set BeginInst of a non floating instruction");
197  return false;
198  }
199 
200  /**
201  * True if the instruction has a homogeneous signature.
202  * (i.e. all operands and the result have the same type)
203  */
204  virtual bool is_homogeneous() const { return true; }
205 
206  /**
207  * True if the instruction has no fixed control dependencies.
208  */
209  virtual bool is_floating() const { return true; }
210 
211  /**
212  * True the instruction has side effects.
213  */
214  virtual bool has_side_effects() const { return false; }
215 
216  /**
217  * True if the instruction is an arithmetic instruction.
218  */
219  virtual bool is_arithmetic() const { return false; }
220 
221  /**
222  * True if the operands of the instruction are commutable.
223  */
224  virtual bool is_commutable() const { return false; }
225 
226  // casting functions
227  virtual Instruction* to_Instruction() { return this; }
228  virtual SourceStateAwareInst* to_SourceStateAwareInst() { return NULL; }
229  virtual DereferenceInst* to_DereferenceInst() { return NULL; }
230 
231 // include to_XXXInst()'s
233 
234  const char* get_name() const {
235  switch (opcode) {
236 // include switch cases
238 
239  case NoInstID: return "NoInst";
240  }
241  return "Unknown Instruction";
242  }
243 
244  /**
245  * Visitor pattern.
246  */
247  virtual void accept(InstructionVisitor& v, bool copyOperands) = 0;
248 
249  virtual OStream& print(OStream& OS) const;
250 
251  // needed to access replace_op in replace_value
252  friend class Value;
253 };
254 
255 /**
256  * Less comparator for Instruction pointers.
257  *
258  * Use for std::set, std::map.
259  */
260 struct InstPtrLess :
261 public std::binary_function<const Instruction*, const Instruction*, bool> {
262  bool operator()(const Instruction *lhs, const Instruction *rhs) const {
263  return lhs->get_id() < rhs->get_id();
264  }
265 };
266 
267 inline OStream& operator<<(OStream &OS, const Instruction &I) {
268  return I.print(OS);
269 }
270 OStream& operator<<(OStream &OS, const Instruction *I);
271 
272 } // end namespace compiler2
273 } // end namespace jit
274 } // end namespace cacao
275 
276 #undef DEBUG_NAME
277 
278 #endif /* _JIT_COMPILER2_INSTRUCTION */
279 
280 
281 /*
282  * These are local overrides for various environment variables in Emacs.
283  * Please do not remove this and leave it at the end of the file, where
284  * Emacs will automagically detect them.
285  * ---------------------------------------------------------------------
286  * Local variables:
287  * mode: c++
288  * indent-tabs-mode: t
289  * c-basic-offset: 4
290  * tab-width: 4
291  * End:
292  * vim:noexpandtab:sw=4:ts=4:
293  */
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 marks the start of a basic block.
u2 op
Definition: disass.cpp:129
virtual void accept(InstructionVisitor &v, bool copyOperands)=0
Visitor pattern.
const_dep_iterator dep_begin() const
OperandListTy::iterator op_iterator
Definition: Instruction.hpp:80
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.
virtual SourceStateAwareInst * to_SourceStateAwareInst()
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:82
std::list< T, Allocator< T > > type
Definition: list.hpp:38
InstID get_opcode() const
return the opcode of the instruction
Base type of instructions that can be mapped to a SourceStateInst.
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:75
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:77
virtual 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:83
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
Base type of instructions that dereference an object reference.
virtual DereferenceInst * to_DereferenceInst()
DepListTy::iterator dep_iterator
Definition: Instruction.hpp:81
const_op_iterator op_end() const
alloc::list< Instruction * >::type DepListTy
Definition: Instruction.hpp:78