Mercurial > hg > truffle
annotate src/share/vm/c1/c1_LIRGenerator.hpp @ 6862:8a5ea0a9ccc4
7127708: G1: change task num types from int to uint in concurrent mark
Summary: Change the type of various task num fields, parameters etc to unsigned and rename them to be more consistent with the other collectors. Code changes were also reviewed by Vitaly Davidovich.
Reviewed-by: johnc
Contributed-by: Kaushik Srenevasan <kaushik@twitter.com>
author | johnc |
---|---|
date | Sat, 06 Oct 2012 01:17:44 -0700 |
parents | 7eca5de9e0b6 |
children | 46f6f063b272 |
rev | line source |
---|---|
0 | 1 /* |
6006
0105f367a14c
7160570: Intrinsification support for tracing framework
rbackman
parents:
4966
diff
changeset
|
2 * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
342
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
342
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
342
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_C1_C1_LIRGENERATOR_HPP |
26 #define SHARE_VM_C1_C1_LIRGENERATOR_HPP | |
27 | |
28 #include "c1/c1_Instruction.hpp" | |
29 #include "c1/c1_LIR.hpp" | |
30 #include "ci/ciMethodData.hpp" | |
31 #include "utilities/sizes.hpp" | |
32 | |
0 | 33 // The classes responsible for code emission and register allocation |
34 | |
35 | |
36 class LIRGenerator; | |
37 class LIREmitter; | |
38 class Invoke; | |
39 class SwitchRange; | |
40 class LIRItem; | |
41 | |
42 define_array(LIRItemArray, LIRItem*) | |
43 define_stack(LIRItemList, LIRItemArray) | |
44 | |
45 class SwitchRange: public CompilationResourceObj { | |
46 private: | |
47 int _low_key; | |
48 int _high_key; | |
49 BlockBegin* _sux; | |
50 public: | |
51 SwitchRange(int start_key, BlockBegin* sux): _low_key(start_key), _high_key(start_key), _sux(sux) {} | |
52 void set_high_key(int key) { _high_key = key; } | |
53 | |
54 int high_key() const { return _high_key; } | |
55 int low_key() const { return _low_key; } | |
56 BlockBegin* sux() const { return _sux; } | |
57 }; | |
58 | |
59 define_array(SwitchRangeArray, SwitchRange*) | |
60 define_stack(SwitchRangeList, SwitchRangeArray) | |
61 | |
62 | |
63 class ResolveNode; | |
64 | |
65 define_array(NodeArray, ResolveNode*); | |
66 define_stack(NodeList, NodeArray); | |
67 | |
68 | |
69 // Node objects form a directed graph of LIR_Opr | |
70 // Edges between Nodes represent moves from one Node to its destinations | |
71 class ResolveNode: public CompilationResourceObj { | |
72 private: | |
73 LIR_Opr _operand; // the source or destinaton | |
74 NodeList _destinations; // for the operand | |
75 bool _assigned; // Value assigned to this Node? | |
76 bool _visited; // Node already visited? | |
77 bool _start_node; // Start node already visited? | |
78 | |
79 public: | |
80 ResolveNode(LIR_Opr operand) | |
81 : _operand(operand) | |
82 , _assigned(false) | |
83 , _visited(false) | |
84 , _start_node(false) {}; | |
85 | |
86 // accessors | |
87 LIR_Opr operand() const { return _operand; } | |
88 int no_of_destinations() const { return _destinations.length(); } | |
89 ResolveNode* destination_at(int i) { return _destinations[i]; } | |
90 bool assigned() const { return _assigned; } | |
91 bool visited() const { return _visited; } | |
92 bool start_node() const { return _start_node; } | |
93 | |
94 // modifiers | |
95 void append(ResolveNode* dest) { _destinations.append(dest); } | |
96 void set_assigned() { _assigned = true; } | |
97 void set_visited() { _visited = true; } | |
98 void set_start_node() { _start_node = true; } | |
99 }; | |
100 | |
101 | |
102 // This is shared state to be used by the PhiResolver so the operand | |
103 // arrays don't have to be reallocated for reach resolution. | |
104 class PhiResolverState: public CompilationResourceObj { | |
105 friend class PhiResolver; | |
106 | |
107 private: | |
108 NodeList _virtual_operands; // Nodes where the operand is a virtual register | |
109 NodeList _other_operands; // Nodes where the operand is not a virtual register | |
110 NodeList _vreg_table; // Mapping from virtual register to Node | |
111 | |
112 public: | |
113 PhiResolverState() {} | |
114 | |
115 void reset(int max_vregs); | |
116 }; | |
117 | |
118 | |
119 // class used to move value of phi operand to phi function | |
120 class PhiResolver: public CompilationResourceObj { | |
121 private: | |
122 LIRGenerator* _gen; | |
123 PhiResolverState& _state; // temporary state cached by LIRGenerator | |
124 | |
125 ResolveNode* _loop; | |
126 LIR_Opr _temp; | |
127 | |
128 // access to shared state arrays | |
129 NodeList& virtual_operands() { return _state._virtual_operands; } | |
130 NodeList& other_operands() { return _state._other_operands; } | |
131 NodeList& vreg_table() { return _state._vreg_table; } | |
132 | |
133 ResolveNode* create_node(LIR_Opr opr, bool source); | |
134 ResolveNode* source_node(LIR_Opr opr) { return create_node(opr, true); } | |
135 ResolveNode* destination_node(LIR_Opr opr) { return create_node(opr, false); } | |
136 | |
137 void emit_move(LIR_Opr src, LIR_Opr dest); | |
138 void move_to_temp(LIR_Opr src); | |
139 void move_temp_to(LIR_Opr dest); | |
140 void move(ResolveNode* src, ResolveNode* dest); | |
141 | |
142 LIRGenerator* gen() { | |
143 return _gen; | |
144 } | |
145 | |
146 public: | |
147 PhiResolver(LIRGenerator* _lir_gen, int max_vregs); | |
148 ~PhiResolver(); | |
149 | |
150 void move(LIR_Opr src, LIR_Opr dest); | |
151 }; | |
152 | |
153 | |
154 // only the classes below belong in the same file | |
155 class LIRGenerator: public InstructionVisitor, public BlockClosure { | |
342 | 156 |
0 | 157 private: |
158 Compilation* _compilation; | |
159 ciMethod* _method; // method that we are compiling | |
160 PhiResolverState _resolver_state; | |
161 BlockBegin* _block; | |
162 int _virtual_register_number; | |
163 Values _instruction_for_operand; | |
164 BitMap2D _vreg_flags; // flags which can be set on a per-vreg basis | |
165 LIR_List* _lir; | |
342 | 166 BarrierSet* _bs; |
0 | 167 |
168 LIRGenerator* gen() { | |
169 return this; | |
170 } | |
171 | |
172 #ifdef ASSERT | |
173 LIR_List* lir(const char * file, int line) const { | |
174 _lir->set_file_and_line(file, line); | |
175 return _lir; | |
176 } | |
177 #endif | |
178 LIR_List* lir() const { | |
179 return _lir; | |
180 } | |
181 | |
182 // a simple cache of constants used within a block | |
183 GrowableArray<LIR_Const*> _constants; | |
184 LIR_OprList _reg_for_constants; | |
185 Values _unpinned_constants; | |
186 | |
187 friend class PhiResolver; | |
188 | |
189 // unified bailout support | |
190 void bailout(const char* msg) const { compilation()->bailout(msg); } | |
191 bool bailed_out() const { return compilation()->bailed_out(); } | |
192 | |
193 void block_do_prolog(BlockBegin* block); | |
194 void block_do_epilog(BlockBegin* block); | |
195 | |
196 // register allocation | |
197 LIR_Opr rlock(Value instr); // lock a free register | |
198 LIR_Opr rlock_result(Value instr); | |
199 LIR_Opr rlock_result(Value instr, BasicType type); | |
200 LIR_Opr rlock_byte(BasicType type); | |
201 LIR_Opr rlock_callee_saved(BasicType type); | |
202 | |
203 // get a constant into a register and get track of what register was used | |
204 LIR_Opr load_constant(Constant* x); | |
205 LIR_Opr load_constant(LIR_Const* constant); | |
206 | |
1783 | 207 // Given an immediate value, return an operand usable in logical ops. |
208 LIR_Opr load_immediate(int x, BasicType type); | |
209 | |
0 | 210 void set_result(Value x, LIR_Opr opr) { |
211 assert(opr->is_valid(), "must set to valid value"); | |
212 assert(x->operand()->is_illegal(), "operand should never change"); | |
213 assert(!opr->is_register() || opr->is_virtual(), "should never set result to a physical register"); | |
214 x->set_operand(opr); | |
215 assert(opr == x->operand(), "must be"); | |
216 if (opr->is_virtual()) { | |
217 _instruction_for_operand.at_put_grow(opr->vreg_number(), x, NULL); | |
218 } | |
219 } | |
220 void set_no_result(Value x) { assert(!x->has_uses(), "can't have use"); x->clear_operand(); } | |
221 | |
222 friend class LIRItem; | |
223 | |
224 LIR_Opr round_item(LIR_Opr opr); | |
225 LIR_Opr force_to_spill(LIR_Opr value, BasicType t); | |
226 | |
227 PhiResolverState& resolver_state() { return _resolver_state; } | |
228 | |
229 void move_to_phi(PhiResolver* resolver, Value cur_val, Value sux_val); | |
230 void move_to_phi(ValueStack* cur_state); | |
231 | |
232 // code emission | |
233 void do_ArithmeticOp_Long (ArithmeticOp* x); | |
234 void do_ArithmeticOp_Int (ArithmeticOp* x); | |
235 void do_ArithmeticOp_FPU (ArithmeticOp* x); | |
236 | |
237 // platform dependent | |
238 LIR_Opr getThreadPointer(); | |
239 | |
240 void do_RegisterFinalizer(Intrinsic* x); | |
6135 | 241 void do_isInstance(Intrinsic* x); |
0 | 242 void do_getClass(Intrinsic* x); |
243 void do_currentThread(Intrinsic* x); | |
244 void do_MathIntrinsic(Intrinsic* x); | |
245 void do_ArrayCopy(Intrinsic* x); | |
246 void do_CompareAndSwap(Intrinsic* x, ValueType* type); | |
247 void do_NIOCheckIndex(Intrinsic* x); | |
248 void do_FPIntrinsics(Intrinsic* x); | |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2166
diff
changeset
|
249 void do_Reference_get(Intrinsic* x); |
0 | 250 |
251 void do_UnsafePrefetch(UnsafePrefetch* x, bool is_store); | |
252 | |
253 LIR_Opr call_runtime(BasicTypeArray* signature, LIRItemList* args, address entry, ValueType* result_type, CodeEmitInfo* info); | |
254 LIR_Opr call_runtime(BasicTypeArray* signature, LIR_OprList* args, address entry, ValueType* result_type, CodeEmitInfo* info); | |
255 | |
256 // convenience functions | |
257 LIR_Opr call_runtime(Value arg1, address entry, ValueType* result_type, CodeEmitInfo* info); | |
258 LIR_Opr call_runtime(Value arg1, Value arg2, address entry, ValueType* result_type, CodeEmitInfo* info); | |
259 | |
260 // GC Barriers | |
261 | |
262 // generic interface | |
263 | |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2166
diff
changeset
|
264 void pre_barrier(LIR_Opr addr_opr, LIR_Opr pre_val, bool do_load, bool patch, CodeEmitInfo* info); |
0 | 265 void post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val); |
266 | |
267 // specific implementations | |
342 | 268 // pre barriers |
269 | |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2166
diff
changeset
|
270 void G1SATBCardTableModRef_pre_barrier(LIR_Opr addr_opr, LIR_Opr pre_val, |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2166
diff
changeset
|
271 bool do_load, bool patch, CodeEmitInfo* info); |
0 | 272 |
273 // post barriers | |
274 | |
342 | 275 void G1SATBCardTableModRef_post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val); |
0 | 276 void CardTableModRef_post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val); |
277 | |
278 | |
279 static LIR_Opr result_register_for(ValueType* type, bool callee = false); | |
280 | |
281 ciObject* get_jobject_constant(Value value); | |
282 | |
283 LIRItemList* invoke_visit_arguments(Invoke* x); | |
284 void invoke_load_arguments(Invoke* x, LIRItemList* args, const LIR_OprList* arg_list); | |
285 | |
286 void trace_block_entry(BlockBegin* block); | |
287 | |
288 // volatile field operations are never patchable because a klass | |
289 // must be loaded to know it's volatile which means that the offset | |
290 // it always known as well. | |
291 void volatile_field_store(LIR_Opr value, LIR_Address* address, CodeEmitInfo* info); | |
292 void volatile_field_load(LIR_Address* address, LIR_Opr result, CodeEmitInfo* info); | |
293 | |
294 void put_Object_unsafe(LIR_Opr src, LIR_Opr offset, LIR_Opr data, BasicType type, bool is_volatile); | |
295 void get_Object_unsafe(LIR_Opr dest, LIR_Opr src, LIR_Opr offset, BasicType type, bool is_volatile); | |
296 | |
297 void arithmetic_call_op (Bytecodes::Code code, LIR_Opr result, LIR_OprList* args); | |
298 | |
1783 | 299 void increment_counter(address counter, BasicType type, int step = 1); |
0 | 300 void increment_counter(LIR_Address* addr, int step = 1); |
301 | |
302 // is_strictfp is only needed for mul and div (and only generates different code on i486) | |
303 void arithmetic_op(Bytecodes::Code code, LIR_Opr result, LIR_Opr left, LIR_Opr right, bool is_strictfp, LIR_Opr tmp, CodeEmitInfo* info = NULL); | |
304 // machine dependent. returns true if it emitted code for the multiply | |
305 bool strength_reduce_multiply(LIR_Opr left, int constant, LIR_Opr result, LIR_Opr tmp); | |
306 | |
307 void store_stack_parameter (LIR_Opr opr, ByteSize offset_from_sp_in_bytes); | |
308 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
309 void klass2reg_with_patching(LIR_Opr r, ciMetadata* obj, CodeEmitInfo* info); |
0 | 310 |
311 // this loads the length and compares against the index | |
312 void array_range_check (LIR_Opr array, LIR_Opr index, CodeEmitInfo* null_check_info, CodeEmitInfo* range_check_info); | |
313 // For java.nio.Buffer.checkIndex | |
314 void nio_range_check (LIR_Opr buffer, LIR_Opr index, LIR_Opr result, CodeEmitInfo* info); | |
315 | |
316 void arithmetic_op_int (Bytecodes::Code code, LIR_Opr result, LIR_Opr left, LIR_Opr right, LIR_Opr tmp); | |
317 void arithmetic_op_long (Bytecodes::Code code, LIR_Opr result, LIR_Opr left, LIR_Opr right, CodeEmitInfo* info = NULL); | |
318 void arithmetic_op_fpu (Bytecodes::Code code, LIR_Opr result, LIR_Opr left, LIR_Opr right, bool is_strictfp, LIR_Opr tmp = LIR_OprFact::illegalOpr); | |
319 | |
320 void shift_op (Bytecodes::Code code, LIR_Opr dst_reg, LIR_Opr value, LIR_Opr count, LIR_Opr tmp); | |
321 | |
322 void logic_op (Bytecodes::Code code, LIR_Opr dst_reg, LIR_Opr left, LIR_Opr right); | |
323 | |
324 void monitor_enter (LIR_Opr object, LIR_Opr lock, LIR_Opr hdr, LIR_Opr scratch, int monitor_no, CodeEmitInfo* info_for_exception, CodeEmitInfo* info); | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
325 void monitor_exit (LIR_Opr object, LIR_Opr lock, LIR_Opr hdr, LIR_Opr scratch, int monitor_no); |
0 | 326 |
327 void new_instance (LIR_Opr dst, ciInstanceKlass* klass, LIR_Opr scratch1, LIR_Opr scratch2, LIR_Opr scratch3, LIR_Opr scratch4, LIR_Opr klass_reg, CodeEmitInfo* info); | |
328 | |
329 // machine dependent | |
330 void cmp_mem_int(LIR_Condition condition, LIR_Opr base, int disp, int c, CodeEmitInfo* info); | |
331 void cmp_reg_mem(LIR_Condition condition, LIR_Opr reg, LIR_Opr base, int disp, BasicType type, CodeEmitInfo* info); | |
332 void cmp_reg_mem(LIR_Condition condition, LIR_Opr reg, LIR_Opr base, LIR_Opr disp, BasicType type, CodeEmitInfo* info); | |
333 | |
334 void arraycopy_helper(Intrinsic* x, int* flags, ciArrayKlass** expected_type); | |
335 | |
336 // returns a LIR_Address to address an array location. May also | |
337 // emit some code as part of address calculation. If | |
338 // needs_card_mark is true then compute the full address for use by | |
339 // both the store and the card mark. | |
340 LIR_Address* generate_address(LIR_Opr base, | |
341 LIR_Opr index, int shift, | |
342 int disp, | |
343 BasicType type); | |
344 LIR_Address* generate_address(LIR_Opr base, int disp, BasicType type) { | |
345 return generate_address(base, LIR_OprFact::illegalOpr, 0, disp, type); | |
346 } | |
347 LIR_Address* emit_array_address(LIR_Opr array_opr, LIR_Opr index_opr, BasicType type, bool needs_card_mark); | |
348 | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
349 // the helper for generate_address |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
350 void add_large_constant(LIR_Opr src, int c, LIR_Opr dest); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
351 |
0 | 352 // machine preferences and characteristics |
353 bool can_inline_as_constant(Value i) const; | |
354 bool can_inline_as_constant(LIR_Const* c) const; | |
355 bool can_store_as_constant(Value i, BasicType type) const; | |
356 | |
357 LIR_Opr safepoint_poll_register(); | |
1783 | 358 |
359 void profile_branch(If* if_instr, If::Condition cond); | |
360 void increment_event_counter_impl(CodeEmitInfo* info, | |
361 ciMethod *method, int frequency, | |
362 int bci, bool backedge, bool notify); | |
363 void increment_event_counter(CodeEmitInfo* info, int bci, bool backedge); | |
364 void increment_invocation_counter(CodeEmitInfo *info) { | |
365 if (compilation()->count_invocations()) { | |
366 increment_event_counter(info, InvocationEntryBci, false); | |
367 } | |
368 } | |
369 void increment_backedge_counter(CodeEmitInfo* info, int bci) { | |
370 if (compilation()->count_backedges()) { | |
371 increment_event_counter(info, bci, true); | |
372 } | |
0 | 373 } |
374 | |
375 CodeEmitInfo* state_for(Instruction* x, ValueStack* state, bool ignore_xhandler = false); | |
376 CodeEmitInfo* state_for(Instruction* x); | |
377 | |
378 // allocates a virtual register for this instruction if | |
379 // one isn't already allocated. Only for Phi and Local. | |
380 LIR_Opr operand_for_instruction(Instruction *x); | |
381 | |
382 void set_block(BlockBegin* block) { _block = block; } | |
383 | |
384 void block_prolog(BlockBegin* block); | |
385 void block_epilog(BlockBegin* block); | |
386 | |
387 void do_root (Instruction* instr); | |
388 void walk (Instruction* instr); | |
389 | |
390 void bind_block_entry(BlockBegin* block); | |
391 void start_block(BlockBegin* block); | |
392 | |
393 LIR_Opr new_register(BasicType type); | |
394 LIR_Opr new_register(Value value) { return new_register(as_BasicType(value->type())); } | |
395 LIR_Opr new_register(ValueType* type) { return new_register(as_BasicType(type)); } | |
396 | |
397 // returns a register suitable for doing pointer math | |
398 LIR_Opr new_pointer_register() { | |
399 #ifdef _LP64 | |
400 return new_register(T_LONG); | |
401 #else | |
402 return new_register(T_INT); | |
403 #endif | |
404 } | |
405 | |
406 static LIR_Condition lir_cond(If::Condition cond) { | |
407 LIR_Condition l; | |
408 switch (cond) { | |
409 case If::eql: l = lir_cond_equal; break; | |
410 case If::neq: l = lir_cond_notEqual; break; | |
411 case If::lss: l = lir_cond_less; break; | |
412 case If::leq: l = lir_cond_lessEqual; break; | |
413 case If::geq: l = lir_cond_greaterEqual; break; | |
414 case If::gtr: l = lir_cond_greater; break; | |
415 }; | |
416 return l; | |
417 } | |
418 | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
419 #ifdef __SOFTFP__ |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
420 void do_soft_float_compare(If *x); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
421 #endif // __SOFTFP__ |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
422 |
0 | 423 void init(); |
424 | |
425 SwitchRangeArray* create_lookup_ranges(TableSwitch* x); | |
426 SwitchRangeArray* create_lookup_ranges(LookupSwitch* x); | |
427 void do_SwitchRanges(SwitchRangeArray* x, LIR_Opr value, BlockBegin* default_sux); | |
428 | |
6006
0105f367a14c
7160570: Intrinsification support for tracing framework
rbackman
parents:
4966
diff
changeset
|
429 void do_RuntimeCall(address routine, int expected_arguments, Intrinsic* x); |
0105f367a14c
7160570: Intrinsification support for tracing framework
rbackman
parents:
4966
diff
changeset
|
430 #ifdef TRACE_HAVE_INTRINSICS |
0105f367a14c
7160570: Intrinsification support for tracing framework
rbackman
parents:
4966
diff
changeset
|
431 void do_ThreadIDIntrinsic(Intrinsic* x); |
0105f367a14c
7160570: Intrinsification support for tracing framework
rbackman
parents:
4966
diff
changeset
|
432 void do_ClassIDIntrinsic(Intrinsic* x); |
0105f367a14c
7160570: Intrinsification support for tracing framework
rbackman
parents:
4966
diff
changeset
|
433 #endif |
0105f367a14c
7160570: Intrinsification support for tracing framework
rbackman
parents:
4966
diff
changeset
|
434 |
0 | 435 public: |
436 Compilation* compilation() const { return _compilation; } | |
437 FrameMap* frame_map() const { return _compilation->frame_map(); } | |
438 ciMethod* method() const { return _method; } | |
439 BlockBegin* block() const { return _block; } | |
440 IRScope* scope() const { return block()->scope(); } | |
441 | |
442 int max_virtual_register_number() const { return _virtual_register_number; } | |
443 | |
444 void block_do(BlockBegin* block); | |
445 | |
446 // Flags that can be set on vregs | |
447 enum VregFlag { | |
448 must_start_in_memory = 0 // needs to be assigned a memory location at beginning, but may then be loaded in a register | |
449 , callee_saved = 1 // must be in a callee saved register | |
450 , byte_reg = 2 // must be in a byte register | |
451 , num_vreg_flags | |
452 | |
453 }; | |
454 | |
455 LIRGenerator(Compilation* compilation, ciMethod* method) | |
456 : _compilation(compilation) | |
457 , _method(method) | |
458 , _virtual_register_number(LIR_OprDesc::vreg_base) | |
459 , _vreg_flags(NULL, 0, num_vreg_flags) { | |
460 init(); | |
461 } | |
462 | |
463 // for virtual registers, maps them back to Phi's or Local's | |
464 Instruction* instruction_for_opr(LIR_Opr opr); | |
465 Instruction* instruction_for_vreg(int reg_num); | |
466 | |
467 void set_vreg_flag (int vreg_num, VregFlag f); | |
468 bool is_vreg_flag_set(int vreg_num, VregFlag f); | |
469 void set_vreg_flag (LIR_Opr opr, VregFlag f) { set_vreg_flag(opr->vreg_number(), f); } | |
470 bool is_vreg_flag_set(LIR_Opr opr, VregFlag f) { return is_vreg_flag_set(opr->vreg_number(), f); } | |
471 | |
472 // statics | |
473 static LIR_Opr exceptionOopOpr(); | |
474 static LIR_Opr exceptionPcOpr(); | |
475 static LIR_Opr divInOpr(); | |
476 static LIR_Opr divOutOpr(); | |
477 static LIR_Opr remOutOpr(); | |
478 static LIR_Opr shiftCountOpr(); | |
479 LIR_Opr syncTempOpr(); | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
480 LIR_Opr atomicLockOpr(); |
0 | 481 |
482 // returns a register suitable for saving the thread in a | |
483 // call_runtime_leaf if one is needed. | |
484 LIR_Opr getThreadTemp(); | |
485 | |
486 // visitor functionality | |
487 virtual void do_Phi (Phi* x); | |
488 virtual void do_Local (Local* x); | |
489 virtual void do_Constant (Constant* x); | |
490 virtual void do_LoadField (LoadField* x); | |
491 virtual void do_StoreField (StoreField* x); | |
492 virtual void do_ArrayLength (ArrayLength* x); | |
493 virtual void do_LoadIndexed (LoadIndexed* x); | |
494 virtual void do_StoreIndexed (StoreIndexed* x); | |
495 virtual void do_NegateOp (NegateOp* x); | |
496 virtual void do_ArithmeticOp (ArithmeticOp* x); | |
497 virtual void do_ShiftOp (ShiftOp* x); | |
498 virtual void do_LogicOp (LogicOp* x); | |
499 virtual void do_CompareOp (CompareOp* x); | |
500 virtual void do_IfOp (IfOp* x); | |
501 virtual void do_Convert (Convert* x); | |
502 virtual void do_NullCheck (NullCheck* x); | |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6143
diff
changeset
|
503 virtual void do_TypeCast (TypeCast* x); |
0 | 504 virtual void do_Invoke (Invoke* x); |
505 virtual void do_NewInstance (NewInstance* x); | |
506 virtual void do_NewTypeArray (NewTypeArray* x); | |
507 virtual void do_NewObjectArray (NewObjectArray* x); | |
508 virtual void do_NewMultiArray (NewMultiArray* x); | |
509 virtual void do_CheckCast (CheckCast* x); | |
510 virtual void do_InstanceOf (InstanceOf* x); | |
511 virtual void do_MonitorEnter (MonitorEnter* x); | |
512 virtual void do_MonitorExit (MonitorExit* x); | |
513 virtual void do_Intrinsic (Intrinsic* x); | |
514 virtual void do_BlockBegin (BlockBegin* x); | |
515 virtual void do_Goto (Goto* x); | |
516 virtual void do_If (If* x); | |
517 virtual void do_IfInstanceOf (IfInstanceOf* x); | |
518 virtual void do_TableSwitch (TableSwitch* x); | |
519 virtual void do_LookupSwitch (LookupSwitch* x); | |
520 virtual void do_Return (Return* x); | |
521 virtual void do_Throw (Throw* x); | |
522 virtual void do_Base (Base* x); | |
523 virtual void do_OsrEntry (OsrEntry* x); | |
524 virtual void do_ExceptionObject(ExceptionObject* x); | |
525 virtual void do_RoundFP (RoundFP* x); | |
526 virtual void do_UnsafeGetRaw (UnsafeGetRaw* x); | |
527 virtual void do_UnsafePutRaw (UnsafePutRaw* x); | |
528 virtual void do_UnsafeGetObject(UnsafeGetObject* x); | |
529 virtual void do_UnsafePutObject(UnsafePutObject* x); | |
6795
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6725
diff
changeset
|
530 virtual void do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x); |
0 | 531 virtual void do_UnsafePrefetchRead (UnsafePrefetchRead* x); |
532 virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x); | |
533 virtual void do_ProfileCall (ProfileCall* x); | |
1783 | 534 virtual void do_ProfileInvoke (ProfileInvoke* x); |
2166
403dc4c1d7f5
6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents:
1972
diff
changeset
|
535 virtual void do_RuntimeCall (RuntimeCall* x); |
4966
701a83c86f28
7120481: storeStore barrier in constructor with final field
jiangli
parents:
3249
diff
changeset
|
536 virtual void do_MemBar (MemBar* x); |
0 | 537 }; |
538 | |
539 | |
540 class LIRItem: public CompilationResourceObj { | |
541 private: | |
542 Value _value; | |
543 LIRGenerator* _gen; | |
544 LIR_Opr _result; | |
545 bool _destroys_register; | |
546 LIR_Opr _new_result; | |
547 | |
548 LIRGenerator* gen() const { return _gen; } | |
549 | |
550 public: | |
551 LIRItem(Value value, LIRGenerator* gen) { | |
552 _destroys_register = false; | |
553 _gen = gen; | |
554 set_instruction(value); | |
555 } | |
556 | |
557 LIRItem(LIRGenerator* gen) { | |
558 _destroys_register = false; | |
559 _gen = gen; | |
560 _result = LIR_OprFact::illegalOpr; | |
561 set_instruction(NULL); | |
562 } | |
563 | |
564 void set_instruction(Value value) { | |
565 _value = value; | |
566 _result = LIR_OprFact::illegalOpr; | |
567 if (_value != NULL) { | |
568 _gen->walk(_value); | |
569 _result = _value->operand(); | |
570 } | |
571 _new_result = LIR_OprFact::illegalOpr; | |
572 } | |
573 | |
574 Value value() const { return _value; } | |
575 ValueType* type() const { return value()->type(); } | |
576 LIR_Opr result() { | |
577 assert(!_destroys_register || (!_result->is_register() || _result->is_virtual()), | |
578 "shouldn't use set_destroys_register with physical regsiters"); | |
579 if (_destroys_register && _result->is_register()) { | |
580 if (_new_result->is_illegal()) { | |
581 _new_result = _gen->new_register(type()); | |
582 gen()->lir()->move(_result, _new_result); | |
583 } | |
584 return _new_result; | |
585 } else { | |
586 return _result; | |
587 } | |
588 return _result; | |
589 } | |
590 | |
591 void set_result(LIR_Opr opr); | |
592 | |
593 void load_item(); | |
594 void load_byte_item(); | |
595 void load_nonconstant(); | |
596 // load any values which can't be expressed as part of a single store instruction | |
597 void load_for_store(BasicType store_type); | |
598 void load_item_force(LIR_Opr reg); | |
599 | |
600 void dont_load_item() { | |
601 // do nothing | |
602 } | |
603 | |
604 void set_destroys_register() { | |
605 _destroys_register = true; | |
606 } | |
607 | |
608 bool is_constant() const { return value()->as_Constant() != NULL; } | |
609 bool is_stack() { return result()->is_stack(); } | |
610 bool is_register() { return result()->is_register(); } | |
611 | |
612 ciObject* get_jobject_constant() const; | |
613 jint get_jint_constant() const; | |
614 jlong get_jlong_constant() const; | |
615 jfloat get_jfloat_constant() const; | |
616 jdouble get_jdouble_constant() const; | |
617 jint get_address_constant() const; | |
618 }; | |
1972 | 619 |
620 #endif // SHARE_VM_C1_C1_LIRGENERATOR_HPP |