hotspot/src/share/vm/opto/cfgnode.hpp

Print this page
rev 611 : Merge

*** 1,10 **** #ifdef USE_PRAGMA_IDENT_HDR #pragma ident "@(#)cfgnode.hpp 1.117 07/10/23 13:12:52 JVM" #endif /* ! * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. --- 1,10 ---- #ifdef USE_PRAGMA_IDENT_HDR #pragma ident "@(#)cfgnode.hpp 1.117 07/10/23 13:12:52 JVM" #endif /* ! * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.
*** 111,149 **** // paths to the RegionNode. For speed reasons (to avoid another pass) we // can turn PhiNodes into copys in-place by NULL'ing out their RegionNode // input in slot 0. class PhiNode : public TypeNode { const TypePtr* const _adr_type; // non-null only for Type::MEMORY nodes. // Size is bigger to hold the _adr_type field. virtual uint hash() const; // Check the type virtual uint cmp( const Node &n ) const; virtual uint size_of() const { return sizeof(*this); } - // Determine a unique non-trivial input, if any. - // Ignore casts if it helps. Return NULL on failure. - Node* unique_input(PhaseTransform *phase); // Determine if CMoveNode::is_cmove_id can be used at this join point. Node* is_cmove_id(PhaseTransform* phase, int true_path); public: // Node layout (parallels RegionNode): enum { Region, // Control input is the Phi's region. Input // Input values are [1..len) }; ! PhiNode( Node *r, const Type *t, const TypePtr* at = NULL ) ! : TypeNode(t,r->req()), _adr_type(at) { init_class_id(Class_Phi); init_req(0, r); verify_adr_type(); } // create a new phi with in edges matching r and set (initially) to x static PhiNode* make( Node* r, Node* x ); // extra type arguments override the new phi's bottom_type and adr_type static PhiNode* make( Node* r, Node* x, const Type *t, const TypePtr* at = NULL ); // create a new phi with narrowed memory type PhiNode* slice_memory(const TypePtr* adr_type) const; // like make(r, x), but does not initialize the in edges to x static PhiNode* make_blank( Node* r, Node* x ); // Accessors RegionNode* region() const { Node* r = in(Region); assert(!r || r->is_Region(), ""); return (RegionNode*)r; } --- 111,159 ---- // paths to the RegionNode. For speed reasons (to avoid another pass) we // can turn PhiNodes into copys in-place by NULL'ing out their RegionNode // input in slot 0. class PhiNode : public TypeNode { const TypePtr* const _adr_type; // non-null only for Type::MEMORY nodes. + const int _inst_id; // Instance id of the memory slice. + const int _inst_index; // Alias index of the instance memory slice. + // Array elements references have the same alias_idx but different offset. + const int _inst_offset; // Offset of the instance memory slice. // Size is bigger to hold the _adr_type field. virtual uint hash() const; // Check the type virtual uint cmp( const Node &n ) const; virtual uint size_of() const { return sizeof(*this); } // Determine if CMoveNode::is_cmove_id can be used at this join point. Node* is_cmove_id(PhaseTransform* phase, int true_path); public: // Node layout (parallels RegionNode): enum { Region, // Control input is the Phi's region. Input // Input values are [1..len) }; ! PhiNode( Node *r, const Type *t, const TypePtr* at = NULL, ! const int iid = TypeOopPtr::InstanceTop, ! const int iidx = Compile::AliasIdxTop, ! const int ioffs = Type::OffsetTop ) ! : TypeNode(t,r->req()), ! _adr_type(at), ! _inst_id(iid), ! _inst_index(iidx), ! _inst_offset(ioffs) ! { init_class_id(Class_Phi); init_req(0, r); verify_adr_type(); } // create a new phi with in edges matching r and set (initially) to x static PhiNode* make( Node* r, Node* x ); // extra type arguments override the new phi's bottom_type and adr_type static PhiNode* make( Node* r, Node* x, const Type *t, const TypePtr* at = NULL ); // create a new phi with narrowed memory type PhiNode* slice_memory(const TypePtr* adr_type) const; + PhiNode* split_out_instance(const TypePtr* at, PhaseIterGVN *igvn) const; // like make(r, x), but does not initialize the in edges to x static PhiNode* make_blank( Node* r, Node* x ); // Accessors RegionNode* region() const { Node* r = in(Region); assert(!r || r->is_Region(), ""); return (RegionNode*)r; }
*** 153,171 **** --- 163,199 ---- DEBUG_ONLY(const Node* r = _in[Region];) assert(r != NULL && r->is_Region(), "Not valid control"); return NULL; // not a copy! } + bool is_tripcount() const; + + // Determine a unique non-trivial input, if any. + // Ignore casts if it helps. Return NULL on failure. + Node* unique_input(PhaseTransform *phase); + // Check for a simple dead loop. enum LoopSafety { Safe = 0, Unsafe, UnsafeLoop }; LoopSafety simple_data_loop_check(Node *in) const; // Is it unsafe data loop? It becomes a dead loop if this phi node removed. bool is_unsafe_data_reference(Node *in) const; int is_diamond_phi() const; virtual int Opcode() const; virtual bool pinned() const { return in(0) != 0; } virtual const TypePtr *adr_type() const { verify_adr_type(true); return _adr_type; } + + const int inst_id() const { return _inst_id; } + const int inst_index() const { return _inst_index; } + const int inst_offset() const { return _inst_offset; } + bool is_same_inst_field(const Type* tp, int id, int index, int offset) { + return type()->basic_type() == tp->basic_type() && + inst_id() == id && + inst_index() == index && + inst_offset() == offset && + type()->higher_equal(tp); + } + virtual const Type *Value( PhaseTransform *phase ) const; virtual Node *Identity( PhaseTransform *phase ); virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); virtual const RegMask &out_RegMask() const; virtual const RegMask &in_RegMask(uint) const;
*** 219,228 **** --- 247,258 ---- class MultiBranchNode : public MultiNode { public: MultiBranchNode( uint required ) : MultiNode(required) { init_class_id(Class_MultiBranch); } + // returns required number of users to be well formed. + virtual int required_outcnt() const = 0; }; //------------------------------IfNode----------------------------------------- // Output selected Control, based on a boolean test class IfNode : public MultiBranchNode {
*** 308,317 **** --- 338,348 ---- virtual int Opcode() const; virtual bool pinned() const { return true; } virtual const Type *bottom_type() const { return TypeTuple::IFBOTH; } virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); virtual const Type *Value( PhaseTransform *phase ) const; + virtual int required_outcnt() const { return 2; } virtual const RegMask &out_RegMask() const; void dominated_by(Node* prev_dom, PhaseIterGVN* igvn); int is_range_check(Node* &range, Node* &index, jint &offset); Node* fold_compares(PhaseGVN* phase); static Node* up_one_dom(Node* curr, bool linear_only = false);
*** 366,375 **** --- 397,407 ---- virtual int Opcode() const; virtual const Type *Value( PhaseTransform *phase ) const; virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); virtual const Type *bottom_type() const; virtual bool pinned() const { return true; } + virtual int required_outcnt() const { return _size; } }; //------------------------------JumpNode--------------------------------------- // Indirect branch. Uses PCTable above to implement a switch statement. // It emits as a table load and local branch.
*** 479,489 **** public: NeverBranchNode( Node *ctrl ) : MultiBranchNode(1) { init_req(0,ctrl); } virtual int Opcode() const; virtual bool pinned() const { return true; }; virtual const Type *bottom_type() const { return TypeTuple::IFBOTH; } ! virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { } virtual uint size(PhaseRegAlloc *ra_) const { return 0; } #ifndef PRODUCT virtual void format( PhaseRegAlloc *, outputStream *st ) const; #endif --- 511,523 ---- public: NeverBranchNode( Node *ctrl ) : MultiBranchNode(1) { init_req(0,ctrl); } virtual int Opcode() const; virtual bool pinned() const { return true; }; virtual const Type *bottom_type() const { return TypeTuple::IFBOTH; } ! virtual const Type *Value( PhaseTransform *phase ) const; ! virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); ! virtual int required_outcnt() const { return 2; } virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { } virtual uint size(PhaseRegAlloc *ra_) const { return 0; } #ifndef PRODUCT virtual void format( PhaseRegAlloc *, outputStream *st ) const; #endif