0N/A/*
3845N/A * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
0N/A * published by the Free Software Foundation.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
1472N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1472N/A * or visit www.oracle.com if you need additional information or have any
1472N/A * questions.
0N/A *
0N/A */
0N/A
1879N/A#ifndef SHARE_VM_OPTO_MACHNODE_HPP
1879N/A#define SHARE_VM_OPTO_MACHNODE_HPP
1879N/A
1879N/A#include "opto/callnode.hpp"
1879N/A#include "opto/matcher.hpp"
1879N/A#include "opto/multnode.hpp"
1879N/A#include "opto/node.hpp"
1879N/A#include "opto/regmask.hpp"
1879N/A
0N/Aclass BufferBlob;
0N/Aclass CodeBuffer;
0N/Aclass JVMState;
0N/Aclass MachCallDynamicJavaNode;
0N/Aclass MachCallJavaNode;
0N/Aclass MachCallLeafNode;
0N/Aclass MachCallNode;
0N/Aclass MachCallRuntimeNode;
0N/Aclass MachCallStaticJavaNode;
0N/Aclass MachEpilogNode;
0N/Aclass MachIfNode;
0N/Aclass MachNullCheckNode;
0N/Aclass MachOper;
0N/Aclass MachProjNode;
0N/Aclass MachPrologNode;
0N/Aclass MachReturnNode;
0N/Aclass MachSafePointNode;
0N/Aclass MachSpillCopyNode;
0N/Aclass Matcher;
0N/Aclass PhaseRegAlloc;
0N/Aclass RegMask;
0N/Aclass State;
0N/A
0N/A//---------------------------MachOper------------------------------------------
0N/Aclass MachOper : public ResourceObj {
0N/Apublic:
0N/A // Allocate right next to the MachNodes in the same arena
0N/A void *operator new( size_t x, Compile* C ) { return C->node_arena()->Amalloc_D(x); }
0N/A
0N/A // Opcode
0N/A virtual uint opcode() const = 0;
0N/A
0N/A // Number of input edges.
0N/A // Generally at least 1
0N/A virtual uint num_edges() const { return 1; }
0N/A // Array of Register masks
0N/A virtual const RegMask *in_RegMask(int index) const;
0N/A
0N/A // Methods to output the encoding of the operand
0N/A
0N/A // Negate conditional branches. Error for non-branch Nodes
0N/A virtual void negate();
0N/A
0N/A // Return the value requested
0N/A // result register lookup, corresponding to int_format
0N/A virtual int reg(PhaseRegAlloc *ra_, const Node *node) const;
0N/A // input register lookup, corresponding to ext_format
0N/A virtual int reg(PhaseRegAlloc *ra_, const Node *node, int idx) const;
0N/A
0N/A // helpers for MacroAssembler generation from ADLC
0N/A Register as_Register(PhaseRegAlloc *ra_, const Node *node) const {
0N/A return ::as_Register(reg(ra_, node));
0N/A }
0N/A Register as_Register(PhaseRegAlloc *ra_, const Node *node, int idx) const {
0N/A return ::as_Register(reg(ra_, node, idx));
0N/A }
0N/A FloatRegister as_FloatRegister(PhaseRegAlloc *ra_, const Node *node) const {
0N/A return ::as_FloatRegister(reg(ra_, node));
0N/A }
0N/A FloatRegister as_FloatRegister(PhaseRegAlloc *ra_, const Node *node, int idx) const {
0N/A return ::as_FloatRegister(reg(ra_, node, idx));
0N/A }
0N/A
0N/A#if defined(IA32) || defined(AMD64)
0N/A XMMRegister as_XMMRegister(PhaseRegAlloc *ra_, const Node *node) const {
0N/A return ::as_XMMRegister(reg(ra_, node));
0N/A }
0N/A XMMRegister as_XMMRegister(PhaseRegAlloc *ra_, const Node *node, int idx) const {
0N/A return ::as_XMMRegister(reg(ra_, node, idx));
0N/A }
0N/A#endif
0N/A
0N/A virtual intptr_t constant() const;
0N/A virtual bool constant_is_oop() const;
0N/A virtual jdouble constantD() const;
0N/A virtual jfloat constantF() const;
0N/A virtual jlong constantL() const;
0N/A virtual TypeOopPtr *oop() const;
0N/A virtual int ccode() const;
0N/A // A zero, default, indicates this value is not needed.
0N/A // May need to lookup the base register, as done in int_ and ext_format
0N/A virtual int base (PhaseRegAlloc *ra_, const Node *node, int idx) const;
0N/A virtual int index(PhaseRegAlloc *ra_, const Node *node, int idx) const;
0N/A virtual int scale() const;
0N/A // Parameters needed to support MEMORY_INTERFACE access to stackSlot
0N/A virtual int disp (PhaseRegAlloc *ra_, const Node *node, int idx) const;
0N/A // Check for PC-Relative displacement
0N/A virtual bool disp_is_oop() const;
0N/A virtual int constant_disp() const; // usu. 0, may return Type::OffsetBot
0N/A virtual int base_position() const; // base edge position, or -1
0N/A virtual int index_position() const; // index edge position, or -1
0N/A
0N/A // Access the TypeKlassPtr of operands with a base==RegI and disp==RegP
0N/A // Only returns non-null value for i486.ad's indOffset32X
0N/A virtual const TypePtr *disp_as_type() const { return NULL; }
0N/A
0N/A // Return the label
0N/A virtual Label *label() const;
0N/A
0N/A // Return the method's address
0N/A virtual intptr_t method() const;
0N/A
0N/A // Hash and compare over operands are currently identical
0N/A virtual uint hash() const;
0N/A virtual uint cmp( const MachOper &oper ) const;
0N/A
0N/A // Virtual clone, since I do not know how big the MachOper is.
0N/A virtual MachOper *clone(Compile* C) const = 0;
0N/A
0N/A // Return ideal Type from simple operands. Fail for complex operands.
0N/A virtual const Type *type() const;
0N/A
0N/A // Set an integer offset if we have one, or error otherwise
0N/A virtual void set_con( jint c0 ) { ShouldNotReachHere(); }
0N/A
0N/A#ifndef PRODUCT
0N/A // Return name of operand
0N/A virtual const char *Name() const { return "???";}
0N/A
0N/A // Methods to output the text version of the operand
0N/A virtual void int_format(PhaseRegAlloc *,const MachNode *node, outputStream *st) const = 0;
0N/A virtual void ext_format(PhaseRegAlloc *,const MachNode *node,int idx, outputStream *st) const=0;
0N/A
0N/A virtual void dump_spec(outputStream *st) const; // Print per-operand info
0N/A#endif
0N/A};
0N/A
0N/A//------------------------------MachNode---------------------------------------
0N/A// Base type for all machine specific nodes. All node classes generated by the
0N/A// ADLC inherit from this class.
0N/Aclass MachNode : public Node {
0N/Apublic:
0N/A MachNode() : Node((uint)0), _num_opnds(0), _opnds(NULL) {
0N/A init_class_id(Class_Mach);
0N/A }
0N/A // Required boilerplate
0N/A virtual uint size_of() const { return sizeof(MachNode); }
0N/A virtual int Opcode() const; // Always equal to MachNode
0N/A virtual uint rule() const = 0; // Machine-specific opcode
0N/A // Number of inputs which come before the first operand.
0N/A // Generally at least 1, to skip the Control input
0N/A virtual uint oper_input_base() const { return 1; }
0N/A
0N/A // Copy inputs and operands to new node of instruction.
0N/A // Called from cisc_version() and short_branch_version().
0N/A // !!!! The method's body is defined in ad_<arch>.cpp file.
0N/A void fill_new_machnode(MachNode *n, Compile* C) const;
0N/A
0N/A // Return an equivalent instruction using memory for cisc_operand position
0N/A virtual MachNode *cisc_version(int offset, Compile* C);
0N/A // Modify this instruction's register mask to use stack version for cisc_operand
0N/A virtual void use_cisc_RegMask();
0N/A
0N/A // Support for short branches
0N/A bool may_be_short_branch() const { return (flags() & Flag_may_be_short_branch) != 0; }
0N/A
2676N/A // Avoid back to back some instructions on some CPUs.
2676N/A bool avoid_back_to_back() const { return (flags() & Flag_avoid_back_to_back) != 0; }
2676N/A
2963N/A // instruction implemented with a call
2963N/A bool has_call() const { return (flags() & Flag_has_call) != 0; }
2963N/A
0N/A // First index in _in[] corresponding to operand, or -1 if there is none
0N/A int operand_index(uint operand) const;
0N/A
0N/A // Register class input is expected in
0N/A virtual const RegMask &in_RegMask(uint) const;
0N/A
0N/A // cisc-spillable instructions redefine for use by in_RegMask
0N/A virtual const RegMask *cisc_RegMask() const { return NULL; }
0N/A
0N/A // If this instruction is a 2-address instruction, then return the
0N/A // index of the input which must match the output. Not nessecary
0N/A // for instructions which bind the input and output register to the
0N/A // same singleton regiser (e.g., Intel IDIV which binds AX to be
0N/A // both an input and an output). It is nessecary when the input and
0N/A // output have choices - but they must use the same choice.
0N/A virtual uint two_adr( ) const { return 0; }
0N/A
0N/A // Array of complex operand pointers. Each corresponds to zero or
0N/A // more leafs. Must be set by MachNode constructor to point to an
0N/A // internal array of MachOpers. The MachOper array is sized by
0N/A // specific MachNodes described in the ADL.
0N/A uint _num_opnds;
0N/A MachOper **_opnds;
0N/A uint num_opnds() const { return _num_opnds; }
0N/A
0N/A // Emit bytes into cbuf
0N/A virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const;
0N/A // Size of instruction in bytes
0N/A virtual uint size(PhaseRegAlloc *ra_) const;
0N/A // Helper function that computes size by emitting code
0N/A virtual uint emit_size(PhaseRegAlloc *ra_) const;
0N/A
0N/A // Return the alignment required (in units of relocInfo::addr_unit())
0N/A // for this instruction (must be a power of 2)
0N/A virtual int alignment_required() const { return 1; }
0N/A
0N/A // Return the padding (in bytes) to be emitted before this
0N/A // instruction to properly align it.
0N/A virtual int compute_padding(int current_offset) const { return 0; }
0N/A
0N/A // Return number of relocatable values contained in this instruction
0N/A virtual int reloc() const { return 0; }
0N/A
0N/A // Hash and compare over operands. Used to do GVN on machine Nodes.
0N/A virtual uint hash() const;
0N/A virtual uint cmp( const Node &n ) const;
0N/A
0N/A // Expand method for MachNode, replaces nodes representing pseudo
0N/A // instructions with a set of nodes which represent real machine
0N/A // instructions and compute the same value.
1203N/A virtual MachNode *Expand( State *, Node_List &proj_list, Node* mem ) { return this; }
0N/A
0N/A // Bottom_type call; value comes from operand0
0N/A virtual const class Type *bottom_type() const { return _opnds[0]->type(); }
0N/A virtual uint ideal_reg() const { const Type *t = _opnds[0]->type(); return t == TypeInt::CC ? Op_RegFlags : Matcher::base2reg[t->base()]; }
0N/A
0N/A // If this is a memory op, return the base pointer and fixed offset.
0N/A // If there are no such, return NULL. If there are multiple addresses
0N/A // or the address is indeterminate (rare cases) then return (Node*)-1,
0N/A // which serves as node bottom.
0N/A // If the offset is not statically determined, set it to Type::OffsetBot.
0N/A // This method is free to ignore stack slots if that helps.
0N/A #define TYPE_PTR_SENTINAL ((const TypePtr*)-1)
0N/A // Passing TYPE_PTR_SENTINAL as adr_type asks for computation of the adr_type if possible
0N/A const Node* get_base_and_disp(intptr_t &offset, const TypePtr* &adr_type) const;
0N/A
0N/A // Helper for get_base_and_disp: find the base and index input nodes.
0N/A // Returns the MachOper as determined by memory_operand(), for use, if
0N/A // needed by the caller. If (MachOper *)-1 is returned, base and index
0N/A // are set to NodeSentinel. If (MachOper *) NULL is returned, base and
0N/A // index are set to NULL.
0N/A const MachOper* memory_inputs(Node* &base, Node* &index) const;
0N/A
0N/A // Helper for memory_inputs: Which operand carries the necessary info?
0N/A // By default, returns NULL, which means there is no such operand.
0N/A // If it returns (MachOper*)-1, this means there are multiple memories.
0N/A virtual const MachOper* memory_operand() const { return NULL; }
0N/A
0N/A // Call "get_base_and_disp" to decide which category of memory is used here.
0N/A virtual const class TypePtr *adr_type() const;
0N/A
0N/A // Apply peephole rule(s) to this instruction
0N/A virtual MachNode *peephole( Block *block, int block_index, PhaseRegAlloc *ra_, int &deleted, Compile* C );
0N/A
0N/A // Top-level ideal Opcode matched
0N/A virtual int ideal_Opcode() const { return Op_Node; }
0N/A
0N/A // Adds the label for the case
0N/A virtual void add_case_label( int switch_val, Label* blockLabel);
0N/A
0N/A // Set the absolute address for methods
0N/A virtual void method_set( intptr_t addr );
0N/A
0N/A // Should we clone rather than spill this instruction?
0N/A bool rematerialize() const;
0N/A
0N/A // Get the pipeline info
0N/A static const Pipeline *pipeline_class();
0N/A virtual const Pipeline *pipeline() const;
0N/A
0N/A#ifndef PRODUCT
0N/A virtual const char *Name() const = 0; // Machine-specific name
0N/A virtual void dump_spec(outputStream *st) const; // Print per-node info
0N/A void dump_format(PhaseRegAlloc *ra, outputStream *st) const; // access to virtual
0N/A#endif
0N/A};
0N/A
0N/A//------------------------------MachIdealNode----------------------------
0N/A// Machine specific versions of nodes that must be defined by user.
0N/A// These are not converted by matcher from ideal nodes to machine nodes
0N/A// but are inserted into the code by the compiler.
0N/Aclass MachIdealNode : public MachNode {
0N/Apublic:
0N/A MachIdealNode( ) {}
0N/A
0N/A // Define the following defaults for non-matched machine nodes
0N/A virtual uint oper_input_base() const { return 0; }
0N/A virtual uint rule() const { return 9999999; }
0N/A virtual const class Type *bottom_type() const { return _opnds == NULL ? Type::CONTROL : MachNode::bottom_type(); }
0N/A};
0N/A
0N/A//------------------------------MachTypeNode----------------------------
0N/A// Machine Nodes that need to retain a known Type.
0N/Aclass MachTypeNode : public MachNode {
0N/A virtual uint size_of() const { return sizeof(*this); } // Size is bigger
0N/Apublic:
3845N/A MachTypeNode( ) {}
0N/A const Type *_bottom_type;
0N/A
0N/A virtual const class Type *bottom_type() const { return _bottom_type; }
0N/A#ifndef PRODUCT
0N/A virtual void dump_spec(outputStream *st) const;
0N/A#endif
0N/A};
0N/A
0N/A//------------------------------MachBreakpointNode----------------------------
0N/A// Machine breakpoint or interrupt Node
0N/Aclass MachBreakpointNode : public MachIdealNode {
0N/Apublic:
0N/A MachBreakpointNode( ) {}
0N/A virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const;
0N/A virtual uint size(PhaseRegAlloc *ra_) const;
0N/A
0N/A#ifndef PRODUCT
0N/A virtual const char *Name() const { return "Breakpoint"; }
0N/A virtual void format( PhaseRegAlloc *, outputStream *st ) const;
0N/A#endif
0N/A};
0N/A
1915N/A//------------------------------MachConstantBaseNode--------------------------
1915N/A// Machine node that represents the base address of the constant table.
1915N/Aclass MachConstantBaseNode : public MachIdealNode {
1915N/Apublic:
1915N/A static const RegMask& _out_RegMask; // We need the out_RegMask statically in MachConstantNode::in_RegMask().
1915N/A
1915N/Apublic:
1915N/A MachConstantBaseNode() : MachIdealNode() {
1915N/A init_class_id(Class_MachConstantBase);
1915N/A }
1915N/A virtual const class Type* bottom_type() const { return TypeRawPtr::NOTNULL; }
1915N/A virtual uint ideal_reg() const { return Op_RegP; }
1915N/A virtual uint oper_input_base() const { return 1; }
1915N/A
1915N/A virtual void emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const;
1915N/A virtual uint size(PhaseRegAlloc* ra_) const;
1915N/A virtual bool pinned() const { return UseRDPCForConstantTableBase; }
1915N/A
1915N/A static const RegMask& static_out_RegMask() { return _out_RegMask; }
1915N/A virtual const RegMask& out_RegMask() const { return static_out_RegMask(); }
1915N/A
1915N/A#ifndef PRODUCT
1915N/A virtual const char* Name() const { return "MachConstantBaseNode"; }
1915N/A virtual void format(PhaseRegAlloc*, outputStream* st) const;
1915N/A#endif
1915N/A};
1915N/A
1915N/A//------------------------------MachConstantNode-------------------------------
1915N/A// Machine node that holds a constant which is stored in the constant table.
3845N/Aclass MachConstantNode : public MachTypeNode {
1915N/Aprotected:
1915N/A Compile::Constant _constant; // This node's constant.
1915N/A
1915N/Apublic:
3845N/A MachConstantNode() : MachTypeNode() {
1915N/A init_class_id(Class_MachConstant);
1915N/A }
1915N/A
1915N/A virtual void eval_constant(Compile* C) {
1915N/A#ifdef ASSERT
1915N/A tty->print("missing MachConstantNode eval_constant function: ");
1915N/A dump();
1915N/A#endif
1915N/A ShouldNotCallThis();
1915N/A }
1915N/A
1915N/A virtual const RegMask &in_RegMask(uint idx) const {
1915N/A if (idx == mach_constant_base_node_input())
1915N/A return MachConstantBaseNode::static_out_RegMask();
1915N/A return MachNode::in_RegMask(idx);
1915N/A }
1915N/A
1915N/A // Input edge of MachConstantBaseNode.
1915N/A uint mach_constant_base_node_input() const { return req() - 1; }
1915N/A
1915N/A int constant_offset();
1915N/A int constant_offset() const { return ((MachConstantNode*) this)->constant_offset(); }
1915N/A};
1915N/A
0N/A//------------------------------MachUEPNode-----------------------------------
0N/A// Machine Unvalidated Entry Point Node
0N/Aclass MachUEPNode : public MachIdealNode {
0N/Apublic:
0N/A MachUEPNode( ) {}
0N/A virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const;
0N/A virtual uint size(PhaseRegAlloc *ra_) const;
0N/A
0N/A#ifndef PRODUCT
0N/A virtual const char *Name() const { return "Unvalidated-Entry-Point"; }
0N/A virtual void format( PhaseRegAlloc *, outputStream *st ) const;
0N/A#endif
0N/A};
0N/A
0N/A//------------------------------MachPrologNode--------------------------------
0N/A// Machine function Prolog Node
0N/Aclass MachPrologNode : public MachIdealNode {
0N/Apublic:
0N/A MachPrologNode( ) {}
0N/A virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const;
0N/A virtual uint size(PhaseRegAlloc *ra_) const;
0N/A virtual int reloc() const;
0N/A
0N/A#ifndef PRODUCT
0N/A virtual const char *Name() const { return "Prolog"; }
0N/A virtual void format( PhaseRegAlloc *, outputStream *st ) const;
0N/A#endif
0N/A};
0N/A
0N/A//------------------------------MachEpilogNode--------------------------------
0N/A// Machine function Epilog Node
0N/Aclass MachEpilogNode : public MachIdealNode {
0N/Apublic:
0N/A MachEpilogNode(bool do_poll = false) : _do_polling(do_poll) {}
0N/A virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const;
0N/A virtual uint size(PhaseRegAlloc *ra_) const;
0N/A virtual int reloc() const;
0N/A virtual const Pipeline *pipeline() const;
0N/A
0N/Aprivate:
0N/A bool _do_polling;
0N/A
0N/Apublic:
0N/A bool do_polling() const { return _do_polling; }
0N/A
0N/A // Offset of safepoint from the beginning of the node
0N/A int safepoint_offset() const;
0N/A
0N/A#ifndef PRODUCT
0N/A virtual const char *Name() const { return "Epilog"; }
0N/A virtual void format( PhaseRegAlloc *, outputStream *st ) const;
0N/A#endif
0N/A};
0N/A
0N/A//------------------------------MachNopNode-----------------------------------
0N/A// Machine function Nop Node
0N/Aclass MachNopNode : public MachIdealNode {
0N/Aprivate:
0N/A int _count;
0N/Apublic:
0N/A MachNopNode( ) : _count(1) {}
0N/A MachNopNode( int count ) : _count(count) {}
0N/A virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const;
0N/A virtual uint size(PhaseRegAlloc *ra_) const;
0N/A
0N/A virtual const class Type *bottom_type() const { return Type::CONTROL; }
0N/A
0N/A virtual int ideal_Opcode() const { return Op_Con; } // bogus; see output.cpp
0N/A virtual const Pipeline *pipeline() const;
0N/A#ifndef PRODUCT
0N/A virtual const char *Name() const { return "Nop"; }
0N/A virtual void format( PhaseRegAlloc *, outputStream *st ) const;
0N/A virtual void dump_spec(outputStream *st) const { } // No per-operand info
0N/A#endif
0N/A};
0N/A
0N/A//------------------------------MachSpillCopyNode------------------------------
0N/A// Machine SpillCopy Node. Copies 1 or 2 words from any location to any
0N/A// location (stack or register).
0N/Aclass MachSpillCopyNode : public MachIdealNode {
0N/A const RegMask *_in; // RegMask for input
0N/A const RegMask *_out; // RegMask for output
0N/A const Type *_type;
0N/Apublic:
0N/A MachSpillCopyNode( Node *n, const RegMask &in, const RegMask &out ) :
0N/A MachIdealNode(), _in(&in), _out(&out), _type(n->bottom_type()) {
0N/A init_class_id(Class_MachSpillCopy);
0N/A init_flags(Flag_is_Copy);
0N/A add_req(NULL);
0N/A add_req(n);
0N/A }
0N/A virtual uint size_of() const { return sizeof(*this); }
0N/A void set_out_RegMask(const RegMask &out) { _out = &out; }
0N/A void set_in_RegMask(const RegMask &in) { _in = &in; }
0N/A virtual const RegMask &out_RegMask() const { return *_out; }
0N/A virtual const RegMask &in_RegMask(uint) const { return *_in; }
0N/A virtual const class Type *bottom_type() const { return _type; }
0N/A virtual uint ideal_reg() const { return Matcher::base2reg[_type->base()]; }
0N/A virtual uint oper_input_base() const { return 1; }
0N/A uint implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream* st ) const;
0N/A
0N/A virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const;
0N/A virtual uint size(PhaseRegAlloc *ra_) const;
0N/A
0N/A#ifndef PRODUCT
0N/A virtual const char *Name() const { return "MachSpillCopy"; }
0N/A virtual void format( PhaseRegAlloc *, outputStream *st ) const;
0N/A#endif
0N/A};
0N/A
2678N/A//------------------------------MachBranchNode--------------------------------
2678N/A// Abstract machine branch Node
2678N/Aclass MachBranchNode : public MachIdealNode {
2678N/Apublic:
2678N/A MachBranchNode() : MachIdealNode() {
2678N/A init_class_id(Class_MachBranch);
2678N/A }
2678N/A virtual void label_set(Label* label, uint block_num) = 0;
2678N/A virtual void save_label(Label** label, uint* block_num) = 0;
2678N/A
2678N/A // Support for short branches
2678N/A virtual MachNode *short_branch_version(Compile* C) { return NULL; }
2678N/A
2678N/A virtual bool pinned() const { return true; };
2678N/A};
2678N/A
0N/A//------------------------------MachNullChkNode--------------------------------
0N/A// Machine-dependent null-pointer-check Node. Points a real MachNode that is
0N/A// also some kind of memory op. Turns the indicated MachNode into a
0N/A// conditional branch with good latency on the ptr-not-null path and awful
0N/A// latency on the pointer-is-null path.
0N/A
2678N/Aclass MachNullCheckNode : public MachBranchNode {
0N/Apublic:
0N/A const uint _vidx; // Index of memop being tested
2678N/A MachNullCheckNode( Node *ctrl, Node *memop, uint vidx ) : MachBranchNode(), _vidx(vidx) {
0N/A init_class_id(Class_MachNullCheck);
0N/A add_req(ctrl);
0N/A add_req(memop);
0N/A }
2678N/A virtual uint size_of() const { return sizeof(*this); }
0N/A
0N/A virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const;
2664N/A virtual void label_set(Label* label, uint block_num);
2678N/A virtual void save_label(Label** label, uint* block_num);
0N/A virtual void negate() { }
0N/A virtual const class Type *bottom_type() const { return TypeTuple::IFBOTH; }
0N/A virtual uint ideal_reg() const { return NotAMachineReg; }
0N/A virtual const RegMask &in_RegMask(uint) const;
0N/A virtual const RegMask &out_RegMask() const { return RegMask::Empty; }
0N/A#ifndef PRODUCT
0N/A virtual const char *Name() const { return "NullCheck"; }
0N/A virtual void format( PhaseRegAlloc *, outputStream *st ) const;
0N/A#endif
0N/A};
0N/A
0N/A//------------------------------MachProjNode----------------------------------
0N/A// Machine-dependent Ideal projections (how is that for an oxymoron). Really
0N/A// just MachNodes made by the Ideal world that replicate simple projections
0N/A// but with machine-dependent input & output register masks. Generally
0N/A// produced as part of calling conventions. Normally I make MachNodes as part
0N/A// of the Matcher process, but the Matcher is ill suited to issues involving
0N/A// frame handling, so frame handling is all done in the Ideal world with
0N/A// occasional callbacks to the machine model for important info.
0N/Aclass MachProjNode : public ProjNode {
0N/Apublic:
2667N/A MachProjNode( Node *multi, uint con, const RegMask &out, uint ideal_reg ) : ProjNode(multi,con), _rout(out), _ideal_reg(ideal_reg) {
2667N/A init_class_id(Class_MachProj);
2667N/A }
0N/A RegMask _rout;
0N/A const uint _ideal_reg;
0N/A enum projType {
0N/A unmatched_proj = 0, // Projs for Control, I/O, memory not matched
0N/A fat_proj = 999 // Projs killing many regs, defined by _rout
0N/A };
0N/A virtual int Opcode() const;
0N/A virtual const Type *bottom_type() const;
0N/A virtual const TypePtr *adr_type() const;
0N/A virtual const RegMask &in_RegMask(uint) const { return RegMask::Empty; }
0N/A virtual const RegMask &out_RegMask() const { return _rout; }
0N/A virtual uint ideal_reg() const { return _ideal_reg; }
0N/A // Need size_of() for virtual ProjNode::clone()
0N/A virtual uint size_of() const { return sizeof(MachProjNode); }
0N/A#ifndef PRODUCT
0N/A virtual void dump_spec(outputStream *st) const;
0N/A#endif
0N/A};
0N/A
0N/A//------------------------------MachIfNode-------------------------------------
0N/A// Machine-specific versions of IfNodes
2678N/Aclass MachIfNode : public MachBranchNode {
0N/A virtual uint size_of() const { return sizeof(*this); } // Size is bigger
0N/Apublic:
0N/A float _prob; // Probability branch goes either way
0N/A float _fcnt; // Frequency counter
2678N/A MachIfNode() : MachBranchNode() {
0N/A init_class_id(Class_MachIf);
0N/A }
2678N/A // Negate conditional branches.
2678N/A virtual void negate() = 0;
0N/A#ifndef PRODUCT
0N/A virtual void dump_spec(outputStream *st) const;
0N/A#endif
0N/A};
0N/A
2667N/A//------------------------------MachGotoNode-----------------------------------
2667N/A// Machine-specific versions of GotoNodes
2678N/Aclass MachGotoNode : public MachBranchNode {
2667N/Apublic:
2678N/A MachGotoNode() : MachBranchNode() {
2667N/A init_class_id(Class_MachGoto);
2667N/A }
2667N/A};
2667N/A
0N/A//------------------------------MachFastLockNode-------------------------------------
0N/A// Machine-specific versions of FastLockNodes
0N/Aclass MachFastLockNode : public MachNode {
0N/A virtual uint size_of() const { return sizeof(*this); } // Size is bigger
0N/Apublic:
0N/A BiasedLockingCounters* _counters;
0N/A
0N/A MachFastLockNode() : MachNode() {}
0N/A};
0N/A
0N/A//------------------------------MachReturnNode--------------------------------
0N/A// Machine-specific versions of subroutine returns
0N/Aclass MachReturnNode : public MachNode {
0N/A virtual uint size_of() const; // Size is bigger
0N/Apublic:
0N/A RegMask *_in_rms; // Input register masks, set during allocation
0N/A ReallocMark _nesting; // assertion check for reallocations
0N/A const TypePtr* _adr_type; // memory effects of call or return
0N/A MachReturnNode() : MachNode() {
0N/A init_class_id(Class_MachReturn);
0N/A _adr_type = TypePtr::BOTTOM; // the default: all of memory
0N/A }
0N/A
0N/A void set_adr_type(const TypePtr* atp) { _adr_type = atp; }
0N/A
0N/A virtual const RegMask &in_RegMask(uint) const;
0N/A virtual bool pinned() const { return true; };
0N/A virtual const TypePtr *adr_type() const;
0N/A};
0N/A
0N/A//------------------------------MachSafePointNode-----------------------------
0N/A// Machine-specific versions of safepoints
0N/Aclass MachSafePointNode : public MachReturnNode {
0N/Apublic:
0N/A OopMap* _oop_map; // Array of OopMap info (8-bit char) for GC
0N/A JVMState* _jvms; // Pointer to list of JVM State Objects
0N/A uint _jvmadj; // Extra delta to jvms indexes (mach. args)
0N/A OopMap* oop_map() const { return _oop_map; }
0N/A void set_oop_map(OopMap* om) { _oop_map = om; }
0N/A
0N/A MachSafePointNode() : MachReturnNode(), _oop_map(NULL), _jvms(NULL), _jvmadj(0) {
0N/A init_class_id(Class_MachSafePoint);
0N/A }
0N/A
0N/A virtual JVMState* jvms() const { return _jvms; }
0N/A void set_jvms(JVMState* s) {
0N/A _jvms = s;
0N/A }
0N/A virtual const Type *bottom_type() const;
0N/A
0N/A virtual const RegMask &in_RegMask(uint) const;
0N/A
0N/A // Functionality from old debug nodes
0N/A Node *returnadr() const { return in(TypeFunc::ReturnAdr); }
0N/A Node *frameptr () const { return in(TypeFunc::FramePtr); }
0N/A
0N/A Node *local(const JVMState* jvms, uint idx) const {
0N/A assert(verify_jvms(jvms), "jvms must match");
0N/A return in(_jvmadj + jvms->locoff() + idx);
0N/A }
0N/A Node *stack(const JVMState* jvms, uint idx) const {
0N/A assert(verify_jvms(jvms), "jvms must match");
0N/A return in(_jvmadj + jvms->stkoff() + idx);
0N/A }
0N/A Node *monitor_obj(const JVMState* jvms, uint idx) const {
0N/A assert(verify_jvms(jvms), "jvms must match");
0N/A return in(_jvmadj + jvms->monitor_obj_offset(idx));
0N/A }
0N/A Node *monitor_box(const JVMState* jvms, uint idx) const {
0N/A assert(verify_jvms(jvms), "jvms must match");
0N/A return in(_jvmadj + jvms->monitor_box_offset(idx));
0N/A }
0N/A void set_local(const JVMState* jvms, uint idx, Node *c) {
0N/A assert(verify_jvms(jvms), "jvms must match");
0N/A set_req(_jvmadj + jvms->locoff() + idx, c);
0N/A }
0N/A void set_stack(const JVMState* jvms, uint idx, Node *c) {
0N/A assert(verify_jvms(jvms), "jvms must match");
0N/A set_req(_jvmadj + jvms->stkoff() + idx, c);
0N/A }
0N/A void set_monitor(const JVMState* jvms, uint idx, Node *c) {
0N/A assert(verify_jvms(jvms), "jvms must match");
0N/A set_req(_jvmadj + jvms->monoff() + idx, c);
0N/A }
0N/A};
0N/A
0N/A//------------------------------MachCallNode----------------------------------
0N/A// Machine-specific versions of subroutine calls
0N/Aclass MachCallNode : public MachSafePointNode {
0N/Aprotected:
0N/A virtual uint hash() const { return NO_HASH; } // CFG nodes do not hash
0N/A virtual uint cmp( const Node &n ) const;
0N/A virtual uint size_of() const = 0; // Size is bigger
0N/Apublic:
0N/A const TypeFunc *_tf; // Function type
0N/A address _entry_point; // Address of the method being called
0N/A float _cnt; // Estimate of number of times called
0N/A uint _argsize; // Size of argument block on stack
0N/A
0N/A const TypeFunc* tf() const { return _tf; }
0N/A const address entry_point() const { return _entry_point; }
0N/A const float cnt() const { return _cnt; }
0N/A uint argsize() const { return _argsize; }
0N/A
0N/A void set_tf(const TypeFunc* tf) { _tf = tf; }
0N/A void set_entry_point(address p) { _entry_point = p; }
0N/A void set_cnt(float c) { _cnt = c; }
0N/A void set_argsize(int s) { _argsize = s; }
0N/A
0N/A MachCallNode() : MachSafePointNode() {
0N/A init_class_id(Class_MachCall);
0N/A }
0N/A
0N/A virtual const Type *bottom_type() const;
0N/A virtual bool pinned() const { return false; }
0N/A virtual const Type *Value( PhaseTransform *phase ) const;
0N/A virtual const RegMask &in_RegMask(uint) const;
0N/A virtual int ret_addr_offset() { return 0; }
0N/A
0N/A bool returns_long() const { return tf()->return_type() == T_LONG; }
0N/A bool return_value_is_used() const;
0N/A#ifndef PRODUCT
0N/A virtual void dump_spec(outputStream *st) const;
0N/A#endif
0N/A};
0N/A
0N/A//------------------------------MachCallJavaNode------------------------------
0N/A// "Base" class for machine-specific versions of subroutine calls
0N/Aclass MachCallJavaNode : public MachCallNode {
0N/Aprotected:
0N/A virtual uint cmp( const Node &n ) const;
0N/A virtual uint size_of() const; // Size is bigger
0N/Apublic:
0N/A ciMethod* _method; // Method being direct called
0N/A int _bci; // Byte Code index of call byte code
0N/A bool _optimized_virtual; // Tells if node is a static call or an optimized virtual
1137N/A bool _method_handle_invoke; // Tells if the call has to preserve SP
0N/A MachCallJavaNode() : MachCallNode() {
0N/A init_class_id(Class_MachCallJava);
0N/A }
1137N/A
1137N/A virtual const RegMask &in_RegMask(uint) const;
1137N/A
0N/A#ifndef PRODUCT
0N/A virtual void dump_spec(outputStream *st) const;
0N/A#endif
0N/A};
0N/A
0N/A//------------------------------MachCallStaticJavaNode------------------------
0N/A// Machine-specific versions of monomorphic subroutine calls
0N/Aclass MachCallStaticJavaNode : public MachCallJavaNode {
0N/A virtual uint cmp( const Node &n ) const;
0N/A virtual uint size_of() const; // Size is bigger
0N/Apublic:
0N/A const char *_name; // Runtime wrapper name
0N/A MachCallStaticJavaNode() : MachCallJavaNode() {
0N/A init_class_id(Class_MachCallStaticJava);
0N/A }
0N/A
0N/A // If this is an uncommon trap, return the request code, else zero.
0N/A int uncommon_trap_request() const;
0N/A
0N/A virtual int ret_addr_offset();
0N/A#ifndef PRODUCT
0N/A virtual void dump_spec(outputStream *st) const;
0N/A void dump_trap_args(outputStream *st) const;
0N/A#endif
0N/A};
0N/A
0N/A//------------------------------MachCallDynamicJavaNode------------------------
0N/A// Machine-specific versions of possibly megamorphic subroutine calls
0N/Aclass MachCallDynamicJavaNode : public MachCallJavaNode {
0N/Apublic:
0N/A int _vtable_index;
0N/A MachCallDynamicJavaNode() : MachCallJavaNode() {
0N/A init_class_id(Class_MachCallDynamicJava);
0N/A DEBUG_ONLY(_vtable_index = -99); // throw an assert if uninitialized
0N/A }
0N/A virtual int ret_addr_offset();
0N/A#ifndef PRODUCT
0N/A virtual void dump_spec(outputStream *st) const;
0N/A#endif
0N/A};
0N/A
0N/A//------------------------------MachCallRuntimeNode----------------------------
0N/A// Machine-specific versions of subroutine calls
0N/Aclass MachCallRuntimeNode : public MachCallNode {
0N/A virtual uint cmp( const Node &n ) const;
0N/A virtual uint size_of() const; // Size is bigger
0N/Apublic:
0N/A const char *_name; // Printable name, if _method is NULL
0N/A MachCallRuntimeNode() : MachCallNode() {
0N/A init_class_id(Class_MachCallRuntime);
0N/A }
0N/A virtual int ret_addr_offset();
0N/A#ifndef PRODUCT
0N/A virtual void dump_spec(outputStream *st) const;
0N/A#endif
0N/A};
0N/A
0N/Aclass MachCallLeafNode: public MachCallRuntimeNode {
0N/Apublic:
0N/A MachCallLeafNode() : MachCallRuntimeNode() {
0N/A init_class_id(Class_MachCallLeaf);
0N/A }
0N/A};
0N/A
0N/A//------------------------------MachHaltNode-----------------------------------
0N/A// Machine-specific versions of halt nodes
0N/Aclass MachHaltNode : public MachReturnNode {
0N/Apublic:
0N/A virtual JVMState* jvms() const;
0N/A};
0N/A
0N/A
0N/A//------------------------------MachTempNode-----------------------------------
0N/A// Node used by the adlc to construct inputs to represent temporary registers
0N/Aclass MachTempNode : public MachNode {
0N/Aprivate:
0N/A MachOper *_opnd_array[1];
0N/A
0N/Apublic:
0N/A virtual const RegMask &out_RegMask() const { return *_opnds[0]->in_RegMask(0); }
0N/A virtual uint rule() const { return 9999999; }
0N/A virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {}
0N/A
0N/A MachTempNode(MachOper* oper) {
0N/A init_class_id(Class_MachTemp);
0N/A _num_opnds = 1;
0N/A _opnds = _opnd_array;
0N/A add_req(NULL);
0N/A _opnds[0] = oper;
0N/A }
0N/A virtual uint size_of() const { return sizeof(MachTempNode); }
0N/A
0N/A#ifndef PRODUCT
0N/A virtual void format(PhaseRegAlloc *, outputStream *st ) const {}
0N/A virtual const char *Name() const { return "MachTemp";}
0N/A#endif
0N/A};
0N/A
0N/A
0N/A
0N/A//------------------------------labelOper--------------------------------------
0N/A// Machine-independent version of label operand
0N/Aclass labelOper : public MachOper {
0N/Aprivate:
0N/A virtual uint num_edges() const { return 0; }
0N/Apublic:
0N/A // Supported for fixed size branches
0N/A Label* _label; // Label for branch(es)
0N/A
0N/A uint _block_num;
0N/A
0N/A labelOper() : _block_num(0), _label(0) {}
0N/A
0N/A labelOper(Label* label, uint block_num) : _label(label), _block_num(block_num) {}
0N/A
0N/A labelOper(labelOper* l) : _label(l->_label) , _block_num(l->_block_num) {}
0N/A
0N/A virtual MachOper *clone(Compile* C) const;
0N/A
2664N/A virtual Label *label() const { assert(_label != NULL, "need Label"); return _label; }
0N/A
0N/A virtual uint opcode() const;
0N/A
0N/A virtual uint hash() const;
0N/A virtual uint cmp( const MachOper &oper ) const;
0N/A#ifndef PRODUCT
0N/A virtual const char *Name() const { return "Label";}
0N/A
0N/A virtual void int_format(PhaseRegAlloc *ra, const MachNode *node, outputStream *st) const;
0N/A virtual void ext_format(PhaseRegAlloc *ra, const MachNode *node, int idx, outputStream *st) const { int_format( ra, node, st ); }
0N/A#endif
0N/A};
0N/A
0N/A
0N/A//------------------------------methodOper--------------------------------------
0N/A// Machine-independent version of method operand
0N/Aclass methodOper : public MachOper {
0N/Aprivate:
0N/A virtual uint num_edges() const { return 0; }
0N/Apublic:
0N/A intptr_t _method; // Address of method
0N/A methodOper() : _method(0) {}
0N/A methodOper(intptr_t method) : _method(method) {}
0N/A
0N/A virtual MachOper *clone(Compile* C) const;
0N/A
0N/A virtual intptr_t method() const { return _method; }
0N/A
0N/A virtual uint opcode() const;
0N/A
0N/A virtual uint hash() const;
0N/A virtual uint cmp( const MachOper &oper ) const;
0N/A#ifndef PRODUCT
0N/A virtual const char *Name() const { return "Method";}
0N/A
0N/A virtual void int_format(PhaseRegAlloc *ra, const MachNode *node, outputStream *st) const;
0N/A virtual void ext_format(PhaseRegAlloc *ra, const MachNode *node, int idx, outputStream *st) const { int_format( ra, node, st ); }
0N/A#endif
0N/A};
1879N/A
1879N/A#endif // SHARE_VM_OPTO_MACHNODE_HPP