Mercurial > hg > graal-compiler
annotate src/share/vm/opto/machnode.hpp @ 10185:d50cc62e94ff
8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
Summary: In graphKit INT operations were generated to access PtrQueue::_index which has type size_t. This is 64 bit on 64-bit machines. No problems occur on little endian machines as long as the index fits into 32 bit, but on big endian machines the upper part is read, which is zero. This leads to unnecessary branches to the slow path in the runtime.
Reviewed-by: twisti, johnc
Contributed-by: Martin Doerr <martin.doerr@sap.com>
author | johnc |
---|---|
date | Wed, 24 Apr 2013 14:48:43 -0700 |
parents | da91efe96a93 |
children | 9758d9f36299 |
rev | line source |
---|---|
0 | 1 /* |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
4120
diff
changeset
|
2 * Copyright (c) 1997, 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:
1203
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1203
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:
1203
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_OPTO_MACHNODE_HPP |
26 #define SHARE_VM_OPTO_MACHNODE_HPP | |
27 | |
28 #include "opto/callnode.hpp" | |
29 #include "opto/matcher.hpp" | |
30 #include "opto/multnode.hpp" | |
31 #include "opto/node.hpp" | |
32 #include "opto/regmask.hpp" | |
33 | |
0 | 34 class BufferBlob; |
35 class CodeBuffer; | |
36 class JVMState; | |
37 class MachCallDynamicJavaNode; | |
38 class MachCallJavaNode; | |
39 class MachCallLeafNode; | |
40 class MachCallNode; | |
41 class MachCallRuntimeNode; | |
42 class MachCallStaticJavaNode; | |
43 class MachEpilogNode; | |
44 class MachIfNode; | |
45 class MachNullCheckNode; | |
46 class MachOper; | |
47 class MachProjNode; | |
48 class MachPrologNode; | |
49 class MachReturnNode; | |
50 class MachSafePointNode; | |
51 class MachSpillCopyNode; | |
52 class Matcher; | |
53 class PhaseRegAlloc; | |
54 class RegMask; | |
55 class State; | |
56 | |
57 //---------------------------MachOper------------------------------------------ | |
58 class MachOper : public ResourceObj { | |
59 public: | |
60 // Allocate right next to the MachNodes in the same arena | |
61 void *operator new( size_t x, Compile* C ) { return C->node_arena()->Amalloc_D(x); } | |
62 | |
63 // Opcode | |
64 virtual uint opcode() const = 0; | |
65 | |
66 // Number of input edges. | |
67 // Generally at least 1 | |
68 virtual uint num_edges() const { return 1; } | |
69 // Array of Register masks | |
70 virtual const RegMask *in_RegMask(int index) const; | |
71 | |
72 // Methods to output the encoding of the operand | |
73 | |
74 // Negate conditional branches. Error for non-branch Nodes | |
75 virtual void negate(); | |
76 | |
77 // Return the value requested | |
78 // result register lookup, corresponding to int_format | |
79 virtual int reg(PhaseRegAlloc *ra_, const Node *node) const; | |
80 // input register lookup, corresponding to ext_format | |
81 virtual int reg(PhaseRegAlloc *ra_, const Node *node, int idx) const; | |
82 | |
83 // helpers for MacroAssembler generation from ADLC | |
84 Register as_Register(PhaseRegAlloc *ra_, const Node *node) const { | |
85 return ::as_Register(reg(ra_, node)); | |
86 } | |
87 Register as_Register(PhaseRegAlloc *ra_, const Node *node, int idx) const { | |
88 return ::as_Register(reg(ra_, node, idx)); | |
89 } | |
90 FloatRegister as_FloatRegister(PhaseRegAlloc *ra_, const Node *node) const { | |
91 return ::as_FloatRegister(reg(ra_, node)); | |
92 } | |
93 FloatRegister as_FloatRegister(PhaseRegAlloc *ra_, const Node *node, int idx) const { | |
94 return ::as_FloatRegister(reg(ra_, node, idx)); | |
95 } | |
96 | |
97 #if defined(IA32) || defined(AMD64) | |
98 XMMRegister as_XMMRegister(PhaseRegAlloc *ra_, const Node *node) const { | |
99 return ::as_XMMRegister(reg(ra_, node)); | |
100 } | |
101 XMMRegister as_XMMRegister(PhaseRegAlloc *ra_, const Node *node, int idx) const { | |
102 return ::as_XMMRegister(reg(ra_, node, idx)); | |
103 } | |
104 #endif | |
105 | |
106 virtual intptr_t constant() const; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6179
diff
changeset
|
107 virtual relocInfo::relocType constant_reloc() const; |
0 | 108 virtual jdouble constantD() const; |
109 virtual jfloat constantF() const; | |
110 virtual jlong constantL() const; | |
111 virtual TypeOopPtr *oop() const; | |
112 virtual int ccode() const; | |
113 // A zero, default, indicates this value is not needed. | |
114 // May need to lookup the base register, as done in int_ and ext_format | |
115 virtual int base (PhaseRegAlloc *ra_, const Node *node, int idx) const; | |
116 virtual int index(PhaseRegAlloc *ra_, const Node *node, int idx) const; | |
117 virtual int scale() const; | |
118 // Parameters needed to support MEMORY_INTERFACE access to stackSlot | |
119 virtual int disp (PhaseRegAlloc *ra_, const Node *node, int idx) const; | |
120 // Check for PC-Relative displacement | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6179
diff
changeset
|
121 virtual relocInfo::relocType disp_reloc() const; |
0 | 122 virtual int constant_disp() const; // usu. 0, may return Type::OffsetBot |
123 virtual int base_position() const; // base edge position, or -1 | |
124 virtual int index_position() const; // index edge position, or -1 | |
125 | |
126 // Access the TypeKlassPtr of operands with a base==RegI and disp==RegP | |
127 // Only returns non-null value for i486.ad's indOffset32X | |
128 virtual const TypePtr *disp_as_type() const { return NULL; } | |
129 | |
130 // Return the label | |
131 virtual Label *label() const; | |
132 | |
133 // Return the method's address | |
134 virtual intptr_t method() const; | |
135 | |
136 // Hash and compare over operands are currently identical | |
137 virtual uint hash() const; | |
138 virtual uint cmp( const MachOper &oper ) const; | |
139 | |
140 // Virtual clone, since I do not know how big the MachOper is. | |
141 virtual MachOper *clone(Compile* C) const = 0; | |
142 | |
143 // Return ideal Type from simple operands. Fail for complex operands. | |
144 virtual const Type *type() const; | |
145 | |
146 // Set an integer offset if we have one, or error otherwise | |
147 virtual void set_con( jint c0 ) { ShouldNotReachHere(); } | |
148 | |
149 #ifndef PRODUCT | |
150 // Return name of operand | |
151 virtual const char *Name() const { return "???";} | |
152 | |
153 // Methods to output the text version of the operand | |
154 virtual void int_format(PhaseRegAlloc *,const MachNode *node, outputStream *st) const = 0; | |
155 virtual void ext_format(PhaseRegAlloc *,const MachNode *node,int idx, outputStream *st) const=0; | |
156 | |
157 virtual void dump_spec(outputStream *st) const; // Print per-operand info | |
158 #endif | |
159 }; | |
160 | |
161 //------------------------------MachNode--------------------------------------- | |
162 // Base type for all machine specific nodes. All node classes generated by the | |
163 // ADLC inherit from this class. | |
164 class MachNode : public Node { | |
165 public: | |
166 MachNode() : Node((uint)0), _num_opnds(0), _opnds(NULL) { | |
167 init_class_id(Class_Mach); | |
168 } | |
169 // Required boilerplate | |
170 virtual uint size_of() const { return sizeof(MachNode); } | |
171 virtual int Opcode() const; // Always equal to MachNode | |
172 virtual uint rule() const = 0; // Machine-specific opcode | |
173 // Number of inputs which come before the first operand. | |
174 // Generally at least 1, to skip the Control input | |
175 virtual uint oper_input_base() const { return 1; } | |
176 | |
177 // Copy inputs and operands to new node of instruction. | |
178 // Called from cisc_version() and short_branch_version(). | |
179 // !!!! The method's body is defined in ad_<arch>.cpp file. | |
180 void fill_new_machnode(MachNode *n, Compile* C) const; | |
181 | |
182 // Return an equivalent instruction using memory for cisc_operand position | |
183 virtual MachNode *cisc_version(int offset, Compile* C); | |
184 // Modify this instruction's register mask to use stack version for cisc_operand | |
185 virtual void use_cisc_RegMask(); | |
186 | |
187 // Support for short branches | |
188 bool may_be_short_branch() const { return (flags() & Flag_may_be_short_branch) != 0; } | |
189 | |
3851 | 190 // Avoid back to back some instructions on some CPUs. |
191 bool avoid_back_to_back() const { return (flags() & Flag_avoid_back_to_back) != 0; } | |
192 | |
4120
f03a3c8bd5e5
7077312: Provide a CALL effect for instruct declaration in the ad file
roland
parents:
3853
diff
changeset
|
193 // instruction implemented with a call |
f03a3c8bd5e5
7077312: Provide a CALL effect for instruct declaration in the ad file
roland
parents:
3853
diff
changeset
|
194 bool has_call() const { return (flags() & Flag_has_call) != 0; } |
f03a3c8bd5e5
7077312: Provide a CALL effect for instruct declaration in the ad file
roland
parents:
3853
diff
changeset
|
195 |
0 | 196 // First index in _in[] corresponding to operand, or -1 if there is none |
197 int operand_index(uint operand) const; | |
198 | |
199 // Register class input is expected in | |
200 virtual const RegMask &in_RegMask(uint) const; | |
201 | |
202 // cisc-spillable instructions redefine for use by in_RegMask | |
203 virtual const RegMask *cisc_RegMask() const { return NULL; } | |
204 | |
205 // If this instruction is a 2-address instruction, then return the | |
206 // index of the input which must match the output. Not nessecary | |
207 // for instructions which bind the input and output register to the | |
208 // same singleton regiser (e.g., Intel IDIV which binds AX to be | |
209 // both an input and an output). It is nessecary when the input and | |
210 // output have choices - but they must use the same choice. | |
211 virtual uint two_adr( ) const { return 0; } | |
212 | |
213 // Array of complex operand pointers. Each corresponds to zero or | |
214 // more leafs. Must be set by MachNode constructor to point to an | |
215 // internal array of MachOpers. The MachOper array is sized by | |
216 // specific MachNodes described in the ADL. | |
217 uint _num_opnds; | |
218 MachOper **_opnds; | |
219 uint num_opnds() const { return _num_opnds; } | |
220 | |
221 // Emit bytes into cbuf | |
222 virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const; | |
223 // Size of instruction in bytes | |
224 virtual uint size(PhaseRegAlloc *ra_) const; | |
225 // Helper function that computes size by emitting code | |
226 virtual uint emit_size(PhaseRegAlloc *ra_) const; | |
227 | |
228 // Return the alignment required (in units of relocInfo::addr_unit()) | |
229 // for this instruction (must be a power of 2) | |
230 virtual int alignment_required() const { return 1; } | |
231 | |
232 // Return the padding (in bytes) to be emitted before this | |
233 // instruction to properly align it. | |
234 virtual int compute_padding(int current_offset) const { return 0; } | |
235 | |
236 // Return number of relocatable values contained in this instruction | |
237 virtual int reloc() const { return 0; } | |
238 | |
239 // Hash and compare over operands. Used to do GVN on machine Nodes. | |
240 virtual uint hash() const; | |
241 virtual uint cmp( const Node &n ) const; | |
242 | |
243 // Expand method for MachNode, replaces nodes representing pseudo | |
244 // instructions with a set of nodes which represent real machine | |
245 // instructions and compute the same value. | |
1203 | 246 virtual MachNode *Expand( State *, Node_List &proj_list, Node* mem ) { return this; } |
0 | 247 |
248 // Bottom_type call; value comes from operand0 | |
249 virtual const class Type *bottom_type() const { return _opnds[0]->type(); } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6179
diff
changeset
|
250 virtual uint ideal_reg() const { const Type *t = _opnds[0]->type(); return t == TypeInt::CC ? Op_RegFlags : t->ideal_reg(); } |
0 | 251 |
252 // If this is a memory op, return the base pointer and fixed offset. | |
253 // If there are no such, return NULL. If there are multiple addresses | |
254 // or the address is indeterminate (rare cases) then return (Node*)-1, | |
255 // which serves as node bottom. | |
256 // If the offset is not statically determined, set it to Type::OffsetBot. | |
257 // This method is free to ignore stack slots if that helps. | |
258 #define TYPE_PTR_SENTINAL ((const TypePtr*)-1) | |
259 // Passing TYPE_PTR_SENTINAL as adr_type asks for computation of the adr_type if possible | |
260 const Node* get_base_and_disp(intptr_t &offset, const TypePtr* &adr_type) const; | |
261 | |
262 // Helper for get_base_and_disp: find the base and index input nodes. | |
263 // Returns the MachOper as determined by memory_operand(), for use, if | |
264 // needed by the caller. If (MachOper *)-1 is returned, base and index | |
265 // are set to NodeSentinel. If (MachOper *) NULL is returned, base and | |
266 // index are set to NULL. | |
267 const MachOper* memory_inputs(Node* &base, Node* &index) const; | |
268 | |
269 // Helper for memory_inputs: Which operand carries the necessary info? | |
270 // By default, returns NULL, which means there is no such operand. | |
271 // If it returns (MachOper*)-1, this means there are multiple memories. | |
272 virtual const MachOper* memory_operand() const { return NULL; } | |
273 | |
274 // Call "get_base_and_disp" to decide which category of memory is used here. | |
275 virtual const class TypePtr *adr_type() const; | |
276 | |
277 // Apply peephole rule(s) to this instruction | |
278 virtual MachNode *peephole( Block *block, int block_index, PhaseRegAlloc *ra_, int &deleted, Compile* C ); | |
279 | |
280 // Top-level ideal Opcode matched | |
281 virtual int ideal_Opcode() const { return Op_Node; } | |
282 | |
283 // Adds the label for the case | |
284 virtual void add_case_label( int switch_val, Label* blockLabel); | |
285 | |
286 // Set the absolute address for methods | |
287 virtual void method_set( intptr_t addr ); | |
288 | |
289 // Should we clone rather than spill this instruction? | |
290 bool rematerialize() const; | |
291 | |
292 // Get the pipeline info | |
293 static const Pipeline *pipeline_class(); | |
294 virtual const Pipeline *pipeline() const; | |
295 | |
296 #ifndef PRODUCT | |
297 virtual const char *Name() const = 0; // Machine-specific name | |
298 virtual void dump_spec(outputStream *st) const; // Print per-node info | |
299 void dump_format(PhaseRegAlloc *ra, outputStream *st) const; // access to virtual | |
300 #endif | |
301 }; | |
302 | |
303 //------------------------------MachIdealNode---------------------------- | |
304 // Machine specific versions of nodes that must be defined by user. | |
305 // These are not converted by matcher from ideal nodes to machine nodes | |
306 // but are inserted into the code by the compiler. | |
307 class MachIdealNode : public MachNode { | |
308 public: | |
309 MachIdealNode( ) {} | |
310 | |
311 // Define the following defaults for non-matched machine nodes | |
312 virtual uint oper_input_base() const { return 0; } | |
313 virtual uint rule() const { return 9999999; } | |
314 virtual const class Type *bottom_type() const { return _opnds == NULL ? Type::CONTROL : MachNode::bottom_type(); } | |
315 }; | |
316 | |
317 //------------------------------MachTypeNode---------------------------- | |
318 // Machine Nodes that need to retain a known Type. | |
319 class MachTypeNode : public MachNode { | |
320 virtual uint size_of() const { return sizeof(*this); } // Size is bigger | |
321 public: | |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
4120
diff
changeset
|
322 MachTypeNode( ) {} |
0 | 323 const Type *_bottom_type; |
324 | |
325 virtual const class Type *bottom_type() const { return _bottom_type; } | |
326 #ifndef PRODUCT | |
327 virtual void dump_spec(outputStream *st) const; | |
328 #endif | |
329 }; | |
330 | |
331 //------------------------------MachBreakpointNode---------------------------- | |
332 // Machine breakpoint or interrupt Node | |
333 class MachBreakpointNode : public MachIdealNode { | |
334 public: | |
335 MachBreakpointNode( ) {} | |
336 virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const; | |
337 virtual uint size(PhaseRegAlloc *ra_) const; | |
338 | |
339 #ifndef PRODUCT | |
340 virtual const char *Name() const { return "Breakpoint"; } | |
341 virtual void format( PhaseRegAlloc *, outputStream *st ) const; | |
342 #endif | |
343 }; | |
344 | |
2008 | 345 //------------------------------MachConstantBaseNode-------------------------- |
346 // Machine node that represents the base address of the constant table. | |
347 class MachConstantBaseNode : public MachIdealNode { | |
348 public: | |
349 static const RegMask& _out_RegMask; // We need the out_RegMask statically in MachConstantNode::in_RegMask(). | |
350 | |
351 public: | |
352 MachConstantBaseNode() : MachIdealNode() { | |
353 init_class_id(Class_MachConstantBase); | |
354 } | |
355 virtual const class Type* bottom_type() const { return TypeRawPtr::NOTNULL; } | |
356 virtual uint ideal_reg() const { return Op_RegP; } | |
357 virtual uint oper_input_base() const { return 1; } | |
358 | |
359 virtual void emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const; | |
360 virtual uint size(PhaseRegAlloc* ra_) const; | |
361 virtual bool pinned() const { return UseRDPCForConstantTableBase; } | |
362 | |
363 static const RegMask& static_out_RegMask() { return _out_RegMask; } | |
364 virtual const RegMask& out_RegMask() const { return static_out_RegMask(); } | |
365 | |
366 #ifndef PRODUCT | |
367 virtual const char* Name() const { return "MachConstantBaseNode"; } | |
368 virtual void format(PhaseRegAlloc*, outputStream* st) const; | |
369 #endif | |
370 }; | |
371 | |
372 //------------------------------MachConstantNode------------------------------- | |
373 // Machine node that holds a constant which is stored in the constant table. | |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
4120
diff
changeset
|
374 class MachConstantNode : public MachTypeNode { |
2008 | 375 protected: |
376 Compile::Constant _constant; // This node's constant. | |
377 | |
378 public: | |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
4120
diff
changeset
|
379 MachConstantNode() : MachTypeNode() { |
2008 | 380 init_class_id(Class_MachConstant); |
381 } | |
382 | |
383 virtual void eval_constant(Compile* C) { | |
384 #ifdef ASSERT | |
385 tty->print("missing MachConstantNode eval_constant function: "); | |
386 dump(); | |
387 #endif | |
388 ShouldNotCallThis(); | |
389 } | |
390 | |
391 virtual const RegMask &in_RegMask(uint idx) const { | |
392 if (idx == mach_constant_base_node_input()) | |
393 return MachConstantBaseNode::static_out_RegMask(); | |
394 return MachNode::in_RegMask(idx); | |
395 } | |
396 | |
397 // Input edge of MachConstantBaseNode. | |
398 uint mach_constant_base_node_input() const { return req() - 1; } | |
399 | |
400 int constant_offset(); | |
401 int constant_offset() const { return ((MachConstantNode*) this)->constant_offset(); } | |
402 }; | |
403 | |
0 | 404 //------------------------------MachUEPNode----------------------------------- |
405 // Machine Unvalidated Entry Point Node | |
406 class MachUEPNode : public MachIdealNode { | |
407 public: | |
408 MachUEPNode( ) {} | |
409 virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const; | |
410 virtual uint size(PhaseRegAlloc *ra_) const; | |
411 | |
412 #ifndef PRODUCT | |
413 virtual const char *Name() const { return "Unvalidated-Entry-Point"; } | |
414 virtual void format( PhaseRegAlloc *, outputStream *st ) const; | |
415 #endif | |
416 }; | |
417 | |
418 //------------------------------MachPrologNode-------------------------------- | |
419 // Machine function Prolog Node | |
420 class MachPrologNode : public MachIdealNode { | |
421 public: | |
422 MachPrologNode( ) {} | |
423 virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const; | |
424 virtual uint size(PhaseRegAlloc *ra_) const; | |
425 virtual int reloc() const; | |
426 | |
427 #ifndef PRODUCT | |
428 virtual const char *Name() const { return "Prolog"; } | |
429 virtual void format( PhaseRegAlloc *, outputStream *st ) const; | |
430 #endif | |
431 }; | |
432 | |
433 //------------------------------MachEpilogNode-------------------------------- | |
434 // Machine function Epilog Node | |
435 class MachEpilogNode : public MachIdealNode { | |
436 public: | |
437 MachEpilogNode(bool do_poll = false) : _do_polling(do_poll) {} | |
438 virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const; | |
439 virtual uint size(PhaseRegAlloc *ra_) const; | |
440 virtual int reloc() const; | |
441 virtual const Pipeline *pipeline() const; | |
442 | |
443 private: | |
444 bool _do_polling; | |
445 | |
446 public: | |
447 bool do_polling() const { return _do_polling; } | |
448 | |
449 // Offset of safepoint from the beginning of the node | |
450 int safepoint_offset() const; | |
451 | |
452 #ifndef PRODUCT | |
453 virtual const char *Name() const { return "Epilog"; } | |
454 virtual void format( PhaseRegAlloc *, outputStream *st ) const; | |
455 #endif | |
456 }; | |
457 | |
458 //------------------------------MachNopNode----------------------------------- | |
459 // Machine function Nop Node | |
460 class MachNopNode : public MachIdealNode { | |
461 private: | |
462 int _count; | |
463 public: | |
464 MachNopNode( ) : _count(1) {} | |
465 MachNopNode( int count ) : _count(count) {} | |
466 virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const; | |
467 virtual uint size(PhaseRegAlloc *ra_) const; | |
468 | |
469 virtual const class Type *bottom_type() const { return Type::CONTROL; } | |
470 | |
471 virtual int ideal_Opcode() const { return Op_Con; } // bogus; see output.cpp | |
472 virtual const Pipeline *pipeline() const; | |
473 #ifndef PRODUCT | |
474 virtual const char *Name() const { return "Nop"; } | |
475 virtual void format( PhaseRegAlloc *, outputStream *st ) const; | |
476 virtual void dump_spec(outputStream *st) const { } // No per-operand info | |
477 #endif | |
478 }; | |
479 | |
480 //------------------------------MachSpillCopyNode------------------------------ | |
481 // Machine SpillCopy Node. Copies 1 or 2 words from any location to any | |
482 // location (stack or register). | |
483 class MachSpillCopyNode : public MachIdealNode { | |
484 const RegMask *_in; // RegMask for input | |
485 const RegMask *_out; // RegMask for output | |
486 const Type *_type; | |
487 public: | |
488 MachSpillCopyNode( Node *n, const RegMask &in, const RegMask &out ) : | |
489 MachIdealNode(), _in(&in), _out(&out), _type(n->bottom_type()) { | |
490 init_class_id(Class_MachSpillCopy); | |
491 init_flags(Flag_is_Copy); | |
492 add_req(NULL); | |
493 add_req(n); | |
494 } | |
495 virtual uint size_of() const { return sizeof(*this); } | |
496 void set_out_RegMask(const RegMask &out) { _out = &out; } | |
497 void set_in_RegMask(const RegMask &in) { _in = ∈ } | |
498 virtual const RegMask &out_RegMask() const { return *_out; } | |
499 virtual const RegMask &in_RegMask(uint) const { return *_in; } | |
500 virtual const class Type *bottom_type() const { return _type; } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6179
diff
changeset
|
501 virtual uint ideal_reg() const { return _type->ideal_reg(); } |
0 | 502 virtual uint oper_input_base() const { return 1; } |
503 uint implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream* st ) const; | |
504 | |
505 virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const; | |
506 virtual uint size(PhaseRegAlloc *ra_) const; | |
507 | |
508 #ifndef PRODUCT | |
509 virtual const char *Name() const { return "MachSpillCopy"; } | |
510 virtual void format( PhaseRegAlloc *, outputStream *st ) const; | |
511 #endif | |
512 }; | |
513 | |
3853
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3851
diff
changeset
|
514 //------------------------------MachBranchNode-------------------------------- |
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3851
diff
changeset
|
515 // Abstract machine branch Node |
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3851
diff
changeset
|
516 class MachBranchNode : public MachIdealNode { |
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3851
diff
changeset
|
517 public: |
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3851
diff
changeset
|
518 MachBranchNode() : MachIdealNode() { |
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3851
diff
changeset
|
519 init_class_id(Class_MachBranch); |
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3851
diff
changeset
|
520 } |
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3851
diff
changeset
|
521 virtual void label_set(Label* label, uint block_num) = 0; |
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3851
diff
changeset
|
522 virtual void save_label(Label** label, uint* block_num) = 0; |
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3851
diff
changeset
|
523 |
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3851
diff
changeset
|
524 // Support for short branches |
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3851
diff
changeset
|
525 virtual MachNode *short_branch_version(Compile* C) { return NULL; } |
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3851
diff
changeset
|
526 |
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3851
diff
changeset
|
527 virtual bool pinned() const { return true; }; |
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3851
diff
changeset
|
528 }; |
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3851
diff
changeset
|
529 |
0 | 530 //------------------------------MachNullChkNode-------------------------------- |
531 // Machine-dependent null-pointer-check Node. Points a real MachNode that is | |
532 // also some kind of memory op. Turns the indicated MachNode into a | |
533 // conditional branch with good latency on the ptr-not-null path and awful | |
534 // latency on the pointer-is-null path. | |
535 | |
3853
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3851
diff
changeset
|
536 class MachNullCheckNode : public MachBranchNode { |
0 | 537 public: |
538 const uint _vidx; // Index of memop being tested | |
3853
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3851
diff
changeset
|
539 MachNullCheckNode( Node *ctrl, Node *memop, uint vidx ) : MachBranchNode(), _vidx(vidx) { |
0 | 540 init_class_id(Class_MachNullCheck); |
541 add_req(ctrl); | |
542 add_req(memop); | |
543 } | |
3853
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3851
diff
changeset
|
544 virtual uint size_of() const { return sizeof(*this); } |
0 | 545 |
546 virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const; | |
3839 | 547 virtual void label_set(Label* label, uint block_num); |
3853
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3851
diff
changeset
|
548 virtual void save_label(Label** label, uint* block_num); |
0 | 549 virtual void negate() { } |
550 virtual const class Type *bottom_type() const { return TypeTuple::IFBOTH; } | |
551 virtual uint ideal_reg() const { return NotAMachineReg; } | |
552 virtual const RegMask &in_RegMask(uint) const; | |
553 virtual const RegMask &out_RegMask() const { return RegMask::Empty; } | |
554 #ifndef PRODUCT | |
555 virtual const char *Name() const { return "NullCheck"; } | |
556 virtual void format( PhaseRegAlloc *, outputStream *st ) const; | |
557 #endif | |
558 }; | |
559 | |
560 //------------------------------MachProjNode---------------------------------- | |
561 // Machine-dependent Ideal projections (how is that for an oxymoron). Really | |
562 // just MachNodes made by the Ideal world that replicate simple projections | |
563 // but with machine-dependent input & output register masks. Generally | |
564 // produced as part of calling conventions. Normally I make MachNodes as part | |
565 // of the Matcher process, but the Matcher is ill suited to issues involving | |
566 // frame handling, so frame handling is all done in the Ideal world with | |
567 // occasional callbacks to the machine model for important info. | |
568 class MachProjNode : public ProjNode { | |
569 public: | |
3842 | 570 MachProjNode( Node *multi, uint con, const RegMask &out, uint ideal_reg ) : ProjNode(multi,con), _rout(out), _ideal_reg(ideal_reg) { |
571 init_class_id(Class_MachProj); | |
572 } | |
0 | 573 RegMask _rout; |
574 const uint _ideal_reg; | |
575 enum projType { | |
576 unmatched_proj = 0, // Projs for Control, I/O, memory not matched | |
577 fat_proj = 999 // Projs killing many regs, defined by _rout | |
578 }; | |
579 virtual int Opcode() const; | |
580 virtual const Type *bottom_type() const; | |
581 virtual const TypePtr *adr_type() const; | |
582 virtual const RegMask &in_RegMask(uint) const { return RegMask::Empty; } | |
583 virtual const RegMask &out_RegMask() const { return _rout; } | |
584 virtual uint ideal_reg() const { return _ideal_reg; } | |
585 // Need size_of() for virtual ProjNode::clone() | |
586 virtual uint size_of() const { return sizeof(MachProjNode); } | |
587 #ifndef PRODUCT | |
588 virtual void dump_spec(outputStream *st) const; | |
589 #endif | |
590 }; | |
591 | |
592 //------------------------------MachIfNode------------------------------------- | |
593 // Machine-specific versions of IfNodes | |
3853
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3851
diff
changeset
|
594 class MachIfNode : public MachBranchNode { |
0 | 595 virtual uint size_of() const { return sizeof(*this); } // Size is bigger |
596 public: | |
597 float _prob; // Probability branch goes either way | |
598 float _fcnt; // Frequency counter | |
3853
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3851
diff
changeset
|
599 MachIfNode() : MachBranchNode() { |
0 | 600 init_class_id(Class_MachIf); |
601 } | |
3853
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3851
diff
changeset
|
602 // Negate conditional branches. |
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3851
diff
changeset
|
603 virtual void negate() = 0; |
0 | 604 #ifndef PRODUCT |
605 virtual void dump_spec(outputStream *st) const; | |
606 #endif | |
607 }; | |
608 | |
3842 | 609 //------------------------------MachGotoNode----------------------------------- |
610 // Machine-specific versions of GotoNodes | |
3853
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3851
diff
changeset
|
611 class MachGotoNode : public MachBranchNode { |
3842 | 612 public: |
3853
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3851
diff
changeset
|
613 MachGotoNode() : MachBranchNode() { |
3842 | 614 init_class_id(Class_MachGoto); |
615 } | |
616 }; | |
617 | |
0 | 618 //------------------------------MachFastLockNode------------------------------------- |
619 // Machine-specific versions of FastLockNodes | |
620 class MachFastLockNode : public MachNode { | |
621 virtual uint size_of() const { return sizeof(*this); } // Size is bigger | |
622 public: | |
623 BiasedLockingCounters* _counters; | |
624 | |
625 MachFastLockNode() : MachNode() {} | |
626 }; | |
627 | |
628 //------------------------------MachReturnNode-------------------------------- | |
629 // Machine-specific versions of subroutine returns | |
630 class MachReturnNode : public MachNode { | |
631 virtual uint size_of() const; // Size is bigger | |
632 public: | |
633 RegMask *_in_rms; // Input register masks, set during allocation | |
634 ReallocMark _nesting; // assertion check for reallocations | |
635 const TypePtr* _adr_type; // memory effects of call or return | |
636 MachReturnNode() : MachNode() { | |
637 init_class_id(Class_MachReturn); | |
638 _adr_type = TypePtr::BOTTOM; // the default: all of memory | |
639 } | |
640 | |
641 void set_adr_type(const TypePtr* atp) { _adr_type = atp; } | |
642 | |
643 virtual const RegMask &in_RegMask(uint) const; | |
644 virtual bool pinned() const { return true; }; | |
645 virtual const TypePtr *adr_type() const; | |
646 }; | |
647 | |
648 //------------------------------MachSafePointNode----------------------------- | |
649 // Machine-specific versions of safepoints | |
650 class MachSafePointNode : public MachReturnNode { | |
651 public: | |
652 OopMap* _oop_map; // Array of OopMap info (8-bit char) for GC | |
653 JVMState* _jvms; // Pointer to list of JVM State Objects | |
654 uint _jvmadj; // Extra delta to jvms indexes (mach. args) | |
655 OopMap* oop_map() const { return _oop_map; } | |
656 void set_oop_map(OopMap* om) { _oop_map = om; } | |
657 | |
658 MachSafePointNode() : MachReturnNode(), _oop_map(NULL), _jvms(NULL), _jvmadj(0) { | |
659 init_class_id(Class_MachSafePoint); | |
660 } | |
661 | |
662 virtual JVMState* jvms() const { return _jvms; } | |
663 void set_jvms(JVMState* s) { | |
664 _jvms = s; | |
665 } | |
666 virtual const Type *bottom_type() const; | |
667 | |
668 virtual const RegMask &in_RegMask(uint) const; | |
669 | |
670 // Functionality from old debug nodes | |
671 Node *returnadr() const { return in(TypeFunc::ReturnAdr); } | |
672 Node *frameptr () const { return in(TypeFunc::FramePtr); } | |
673 | |
674 Node *local(const JVMState* jvms, uint idx) const { | |
675 assert(verify_jvms(jvms), "jvms must match"); | |
676 return in(_jvmadj + jvms->locoff() + idx); | |
677 } | |
678 Node *stack(const JVMState* jvms, uint idx) const { | |
679 assert(verify_jvms(jvms), "jvms must match"); | |
680 return in(_jvmadj + jvms->stkoff() + idx); | |
681 } | |
682 Node *monitor_obj(const JVMState* jvms, uint idx) const { | |
683 assert(verify_jvms(jvms), "jvms must match"); | |
684 return in(_jvmadj + jvms->monitor_obj_offset(idx)); | |
685 } | |
686 Node *monitor_box(const JVMState* jvms, uint idx) const { | |
687 assert(verify_jvms(jvms), "jvms must match"); | |
688 return in(_jvmadj + jvms->monitor_box_offset(idx)); | |
689 } | |
690 void set_local(const JVMState* jvms, uint idx, Node *c) { | |
691 assert(verify_jvms(jvms), "jvms must match"); | |
692 set_req(_jvmadj + jvms->locoff() + idx, c); | |
693 } | |
694 void set_stack(const JVMState* jvms, uint idx, Node *c) { | |
695 assert(verify_jvms(jvms), "jvms must match"); | |
696 set_req(_jvmadj + jvms->stkoff() + idx, c); | |
697 } | |
698 void set_monitor(const JVMState* jvms, uint idx, Node *c) { | |
699 assert(verify_jvms(jvms), "jvms must match"); | |
700 set_req(_jvmadj + jvms->monoff() + idx, c); | |
701 } | |
702 }; | |
703 | |
704 //------------------------------MachCallNode---------------------------------- | |
705 // Machine-specific versions of subroutine calls | |
706 class MachCallNode : public MachSafePointNode { | |
707 protected: | |
708 virtual uint hash() const { return NO_HASH; } // CFG nodes do not hash | |
709 virtual uint cmp( const Node &n ) const; | |
710 virtual uint size_of() const = 0; // Size is bigger | |
711 public: | |
712 const TypeFunc *_tf; // Function type | |
713 address _entry_point; // Address of the method being called | |
714 float _cnt; // Estimate of number of times called | |
715 uint _argsize; // Size of argument block on stack | |
716 | |
717 const TypeFunc* tf() const { return _tf; } | |
718 const address entry_point() const { return _entry_point; } | |
719 const float cnt() const { return _cnt; } | |
720 uint argsize() const { return _argsize; } | |
721 | |
722 void set_tf(const TypeFunc* tf) { _tf = tf; } | |
723 void set_entry_point(address p) { _entry_point = p; } | |
724 void set_cnt(float c) { _cnt = c; } | |
725 void set_argsize(int s) { _argsize = s; } | |
726 | |
727 MachCallNode() : MachSafePointNode() { | |
728 init_class_id(Class_MachCall); | |
729 } | |
730 | |
731 virtual const Type *bottom_type() const; | |
732 virtual bool pinned() const { return false; } | |
733 virtual const Type *Value( PhaseTransform *phase ) const; | |
734 virtual const RegMask &in_RegMask(uint) const; | |
735 virtual int ret_addr_offset() { return 0; } | |
736 | |
737 bool returns_long() const { return tf()->return_type() == T_LONG; } | |
738 bool return_value_is_used() const; | |
739 #ifndef PRODUCT | |
740 virtual void dump_spec(outputStream *st) const; | |
741 #endif | |
742 }; | |
743 | |
744 //------------------------------MachCallJavaNode------------------------------ | |
745 // "Base" class for machine-specific versions of subroutine calls | |
746 class MachCallJavaNode : public MachCallNode { | |
747 protected: | |
748 virtual uint cmp( const Node &n ) const; | |
749 virtual uint size_of() const; // Size is bigger | |
750 public: | |
751 ciMethod* _method; // Method being direct called | |
752 int _bci; // Byte Code index of call byte code | |
753 bool _optimized_virtual; // Tells if node is a static call or an optimized virtual | |
1137 | 754 bool _method_handle_invoke; // Tells if the call has to preserve SP |
0 | 755 MachCallJavaNode() : MachCallNode() { |
756 init_class_id(Class_MachCallJava); | |
757 } | |
1137 | 758 |
759 virtual const RegMask &in_RegMask(uint) const; | |
760 | |
0 | 761 #ifndef PRODUCT |
762 virtual void dump_spec(outputStream *st) const; | |
763 #endif | |
764 }; | |
765 | |
766 //------------------------------MachCallStaticJavaNode------------------------ | |
767 // Machine-specific versions of monomorphic subroutine calls | |
768 class MachCallStaticJavaNode : public MachCallJavaNode { | |
769 virtual uint cmp( const Node &n ) const; | |
770 virtual uint size_of() const; // Size is bigger | |
771 public: | |
772 const char *_name; // Runtime wrapper name | |
773 MachCallStaticJavaNode() : MachCallJavaNode() { | |
774 init_class_id(Class_MachCallStaticJava); | |
775 } | |
776 | |
777 // If this is an uncommon trap, return the request code, else zero. | |
778 int uncommon_trap_request() const; | |
779 | |
780 virtual int ret_addr_offset(); | |
781 #ifndef PRODUCT | |
782 virtual void dump_spec(outputStream *st) const; | |
783 void dump_trap_args(outputStream *st) const; | |
784 #endif | |
785 }; | |
786 | |
787 //------------------------------MachCallDynamicJavaNode------------------------ | |
788 // Machine-specific versions of possibly megamorphic subroutine calls | |
789 class MachCallDynamicJavaNode : public MachCallJavaNode { | |
790 public: | |
791 int _vtable_index; | |
792 MachCallDynamicJavaNode() : MachCallJavaNode() { | |
793 init_class_id(Class_MachCallDynamicJava); | |
794 DEBUG_ONLY(_vtable_index = -99); // throw an assert if uninitialized | |
795 } | |
796 virtual int ret_addr_offset(); | |
797 #ifndef PRODUCT | |
798 virtual void dump_spec(outputStream *st) const; | |
799 #endif | |
800 }; | |
801 | |
802 //------------------------------MachCallRuntimeNode---------------------------- | |
803 // Machine-specific versions of subroutine calls | |
804 class MachCallRuntimeNode : public MachCallNode { | |
805 virtual uint cmp( const Node &n ) const; | |
806 virtual uint size_of() const; // Size is bigger | |
807 public: | |
808 const char *_name; // Printable name, if _method is NULL | |
809 MachCallRuntimeNode() : MachCallNode() { | |
810 init_class_id(Class_MachCallRuntime); | |
811 } | |
812 virtual int ret_addr_offset(); | |
813 #ifndef PRODUCT | |
814 virtual void dump_spec(outputStream *st) const; | |
815 #endif | |
816 }; | |
817 | |
818 class MachCallLeafNode: public MachCallRuntimeNode { | |
819 public: | |
820 MachCallLeafNode() : MachCallRuntimeNode() { | |
821 init_class_id(Class_MachCallLeaf); | |
822 } | |
823 }; | |
824 | |
825 //------------------------------MachHaltNode----------------------------------- | |
826 // Machine-specific versions of halt nodes | |
827 class MachHaltNode : public MachReturnNode { | |
828 public: | |
829 virtual JVMState* jvms() const; | |
830 }; | |
831 | |
832 | |
833 //------------------------------MachTempNode----------------------------------- | |
834 // Node used by the adlc to construct inputs to represent temporary registers | |
835 class MachTempNode : public MachNode { | |
836 private: | |
837 MachOper *_opnd_array[1]; | |
838 | |
839 public: | |
840 virtual const RegMask &out_RegMask() const { return *_opnds[0]->in_RegMask(0); } | |
841 virtual uint rule() const { return 9999999; } | |
842 virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {} | |
843 | |
844 MachTempNode(MachOper* oper) { | |
845 init_class_id(Class_MachTemp); | |
846 _num_opnds = 1; | |
847 _opnds = _opnd_array; | |
848 add_req(NULL); | |
849 _opnds[0] = oper; | |
850 } | |
851 virtual uint size_of() const { return sizeof(MachTempNode); } | |
852 | |
853 #ifndef PRODUCT | |
854 virtual void format(PhaseRegAlloc *, outputStream *st ) const {} | |
855 virtual const char *Name() const { return "MachTemp";} | |
856 #endif | |
857 }; | |
858 | |
859 | |
860 | |
861 //------------------------------labelOper-------------------------------------- | |
862 // Machine-independent version of label operand | |
863 class labelOper : public MachOper { | |
864 private: | |
865 virtual uint num_edges() const { return 0; } | |
866 public: | |
867 // Supported for fixed size branches | |
868 Label* _label; // Label for branch(es) | |
869 | |
870 uint _block_num; | |
871 | |
872 labelOper() : _block_num(0), _label(0) {} | |
873 | |
874 labelOper(Label* label, uint block_num) : _label(label), _block_num(block_num) {} | |
875 | |
876 labelOper(labelOper* l) : _label(l->_label) , _block_num(l->_block_num) {} | |
877 | |
878 virtual MachOper *clone(Compile* C) const; | |
879 | |
3839 | 880 virtual Label *label() const { assert(_label != NULL, "need Label"); return _label; } |
0 | 881 |
882 virtual uint opcode() const; | |
883 | |
884 virtual uint hash() const; | |
885 virtual uint cmp( const MachOper &oper ) const; | |
886 #ifndef PRODUCT | |
887 virtual const char *Name() const { return "Label";} | |
888 | |
889 virtual void int_format(PhaseRegAlloc *ra, const MachNode *node, outputStream *st) const; | |
890 virtual void ext_format(PhaseRegAlloc *ra, const MachNode *node, int idx, outputStream *st) const { int_format( ra, node, st ); } | |
891 #endif | |
892 }; | |
893 | |
894 | |
895 //------------------------------methodOper-------------------------------------- | |
896 // Machine-independent version of method operand | |
897 class methodOper : public MachOper { | |
898 private: | |
899 virtual uint num_edges() const { return 0; } | |
900 public: | |
901 intptr_t _method; // Address of method | |
902 methodOper() : _method(0) {} | |
903 methodOper(intptr_t method) : _method(method) {} | |
904 | |
905 virtual MachOper *clone(Compile* C) const; | |
906 | |
907 virtual intptr_t method() const { return _method; } | |
908 | |
909 virtual uint opcode() const; | |
910 | |
911 virtual uint hash() const; | |
912 virtual uint cmp( const MachOper &oper ) const; | |
913 #ifndef PRODUCT | |
914 virtual const char *Name() const { return "Method";} | |
915 | |
916 virtual void int_format(PhaseRegAlloc *ra, const MachNode *node, outputStream *st) const; | |
917 virtual void ext_format(PhaseRegAlloc *ra, const MachNode *node, int idx, outputStream *st) const { int_format( ra, node, st ); } | |
918 #endif | |
919 }; | |
1972 | 920 |
921 #endif // SHARE_VM_OPTO_MACHNODE_HPP |