Path: blob/master/src/hotspot/share/opto/cfgnode.hpp
40930 views
/*1* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#ifndef SHARE_OPTO_CFGNODE_HPP25#define SHARE_OPTO_CFGNODE_HPP2627#include "opto/multnode.hpp"28#include "opto/node.hpp"29#include "opto/opcodes.hpp"30#include "opto/type.hpp"3132// Portions of code courtesy of Clifford Click3334// Optimization - Graph Style3536class Matcher;37class Node;38class RegionNode;39class TypeNode;40class PhiNode;41class GotoNode;42class MultiNode;43class MultiBranchNode;44class IfNode;45class PCTableNode;46class JumpNode;47class CatchNode;48class NeverBranchNode;49class ProjNode;50class CProjNode;51class IfTrueNode;52class IfFalseNode;53class CatchProjNode;54class JProjNode;55class JumpProjNode;56class SCMemProjNode;57class PhaseIdealLoop;5859//------------------------------RegionNode-------------------------------------60// The class of RegionNodes, which can be mapped to basic blocks in the61// program. Their inputs point to Control sources. PhiNodes (described62// below) have an input point to a RegionNode. Merged data inputs to PhiNodes63// correspond 1-to-1 with RegionNode inputs. The zero input of a PhiNode is64// the RegionNode, and the zero input of the RegionNode is itself.65class RegionNode : public Node {66private:67bool _is_unreachable_region;6869bool is_possible_unsafe_loop(const PhaseGVN* phase) const;70bool is_unreachable_from_root(const PhaseGVN* phase) const;71public:72// Node layout (parallels PhiNode):73enum { Region, // Generally points to self.74Control // Control arcs are [1..len)75};7677RegionNode(uint required) : Node(required), _is_unreachable_region(false) {78init_class_id(Class_Region);79init_req(0, this);80}8182Node* is_copy() const {83const Node* r = _in[Region];84if (r == NULL)85return nonnull_req();86return NULL; // not a copy!87}88PhiNode* has_phi() const; // returns an arbitrary phi user, or NULL89PhiNode* has_unique_phi() const; // returns the unique phi user, or NULL90// Is this region node unreachable from root?91bool is_unreachable_region(const PhaseGVN* phase);92virtual int Opcode() const;93virtual uint size_of() const { return sizeof(*this); }94virtual bool pinned() const { return (const Node*)in(0) == this; }95virtual bool is_CFG() const { return true; }96virtual uint hash() const { return NO_HASH; } // CFG nodes do not hash97virtual bool depends_only_on_test() const { return false; }98virtual const Type* bottom_type() const { return Type::CONTROL; }99virtual const Type* Value(PhaseGVN* phase) const;100virtual Node* Identity(PhaseGVN* phase);101virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);102virtual const RegMask &out_RegMask() const;103bool try_clean_mem_phi(PhaseGVN* phase);104bool optimize_trichotomy(PhaseIterGVN* igvn);105};106107//------------------------------JProjNode--------------------------------------108// jump projection for node that produces multiple control-flow paths109class JProjNode : public ProjNode {110public:111JProjNode( Node* ctrl, uint idx ) : ProjNode(ctrl,idx) {}112virtual int Opcode() const;113virtual bool is_CFG() const { return true; }114virtual uint hash() const { return NO_HASH; } // CFG nodes do not hash115virtual const Node* is_block_proj() const { return in(0); }116virtual const RegMask& out_RegMask() const;117virtual uint ideal_reg() const { return 0; }118};119120//------------------------------PhiNode----------------------------------------121// PhiNodes merge values from different Control paths. Slot 0 points to the122// controlling RegionNode. Other slots map 1-for-1 with incoming control flow123// paths to the RegionNode.124class PhiNode : public TypeNode {125friend class PhaseRenumberLive;126127const TypePtr* const _adr_type; // non-null only for Type::MEMORY nodes.128// The following fields are only used for data PhiNodes to indicate129// that the PhiNode represents the value of a known instance field.130int _inst_mem_id; // Instance memory id (node index of the memory Phi)131int _inst_id; // Instance id of the memory slice.132const int _inst_index; // Alias index of the instance memory slice.133// Array elements references have the same alias_idx but different offset.134const int _inst_offset; // Offset of the instance memory slice.135// Size is bigger to hold the _adr_type field.136virtual uint hash() const; // Check the type137virtual bool cmp( const Node &n ) const;138virtual uint size_of() const { return sizeof(*this); }139140// Determine if CMoveNode::is_cmove_id can be used at this join point.141Node* is_cmove_id(PhaseTransform* phase, int true_path);142bool wait_for_region_igvn(PhaseGVN* phase);143bool is_data_loop(RegionNode* r, Node* uin, const PhaseGVN* phase);144145public:146// Node layout (parallels RegionNode):147enum { Region, // Control input is the Phi's region.148Input // Input values are [1..len)149};150151PhiNode( Node *r, const Type *t, const TypePtr* at = NULL,152const int imid = -1,153const int iid = TypeOopPtr::InstanceTop,154const int iidx = Compile::AliasIdxTop,155const int ioffs = Type::OffsetTop )156: TypeNode(t,r->req()),157_adr_type(at),158_inst_mem_id(imid),159_inst_id(iid),160_inst_index(iidx),161_inst_offset(ioffs)162{163init_class_id(Class_Phi);164init_req(0, r);165verify_adr_type();166}167// create a new phi with in edges matching r and set (initially) to x168static PhiNode* make( Node* r, Node* x );169// extra type arguments override the new phi's bottom_type and adr_type170static PhiNode* make( Node* r, Node* x, const Type *t, const TypePtr* at = NULL );171// create a new phi with narrowed memory type172PhiNode* slice_memory(const TypePtr* adr_type) const;173PhiNode* split_out_instance(const TypePtr* at, PhaseIterGVN *igvn) const;174// like make(r, x), but does not initialize the in edges to x175static PhiNode* make_blank( Node* r, Node* x );176177// Accessors178RegionNode* region() const { Node* r = in(Region); assert(!r || r->is_Region(), ""); return (RegionNode*)r; }179180bool is_tripcount(BasicType bt) const;181182// Determine a unique non-trivial input, if any.183// Ignore casts if it helps. Return NULL on failure.184Node* unique_input(PhaseTransform *phase, bool uncast);185Node* unique_input(PhaseTransform *phase) {186Node* uin = unique_input(phase, false);187if (uin == NULL) {188uin = unique_input(phase, true);189}190return uin;191}192193// Check for a simple dead loop.194enum LoopSafety { Safe = 0, Unsafe, UnsafeLoop };195LoopSafety simple_data_loop_check(Node *in) const;196// Is it unsafe data loop? It becomes a dead loop if this phi node removed.197bool is_unsafe_data_reference(Node *in) const;198int is_diamond_phi(bool check_control_only = false) const;199virtual int Opcode() const;200virtual bool pinned() const { return in(0) != 0; }201virtual const TypePtr *adr_type() const { verify_adr_type(true); return _adr_type; }202203void set_inst_mem_id(int inst_mem_id) { _inst_mem_id = inst_mem_id; }204const int inst_mem_id() const { return _inst_mem_id; }205const int inst_id() const { return _inst_id; }206const int inst_index() const { return _inst_index; }207const int inst_offset() const { return _inst_offset; }208bool is_same_inst_field(const Type* tp, int mem_id, int id, int index, int offset) {209return type()->basic_type() == tp->basic_type() &&210inst_mem_id() == mem_id &&211inst_id() == id &&212inst_index() == index &&213inst_offset() == offset &&214type()->higher_equal(tp);215}216217virtual const Type* Value(PhaseGVN* phase) const;218virtual Node* Identity(PhaseGVN* phase);219virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);220virtual const RegMask &out_RegMask() const;221virtual const RegMask &in_RegMask(uint) const;222#ifndef PRODUCT223virtual void related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const;224virtual void dump_spec(outputStream *st) const;225#endif226#ifdef ASSERT227void verify_adr_type(VectorSet& visited, const TypePtr* at) const;228void verify_adr_type(bool recursive = false) const;229#else //ASSERT230void verify_adr_type(bool recursive = false) const {}231#endif //ASSERT232};233234//------------------------------GotoNode---------------------------------------235// GotoNodes perform direct branches.236class GotoNode : public Node {237public:238GotoNode( Node *control ) : Node(control) {}239virtual int Opcode() const;240virtual bool pinned() const { return true; }241virtual bool is_CFG() const { return true; }242virtual uint hash() const { return NO_HASH; } // CFG nodes do not hash243virtual const Node *is_block_proj() const { return this; }244virtual bool depends_only_on_test() const { return false; }245virtual const Type *bottom_type() const { return Type::CONTROL; }246virtual const Type* Value(PhaseGVN* phase) const;247virtual Node* Identity(PhaseGVN* phase);248virtual const RegMask &out_RegMask() const;249250#ifndef PRODUCT251virtual void related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const;252#endif253};254255//------------------------------CProjNode--------------------------------------256// control projection for node that produces multiple control-flow paths257class CProjNode : public ProjNode {258public:259CProjNode( Node *ctrl, uint idx ) : ProjNode(ctrl,idx) {}260virtual int Opcode() const;261virtual bool is_CFG() const { return true; }262virtual uint hash() const { return NO_HASH; } // CFG nodes do not hash263virtual const Node *is_block_proj() const { return in(0); }264virtual const RegMask &out_RegMask() const;265virtual uint ideal_reg() const { return 0; }266};267268//---------------------------MultiBranchNode-----------------------------------269// This class defines a MultiBranchNode, a MultiNode which yields multiple270// control values. These are distinguished from other types of MultiNodes271// which yield multiple values, but control is always and only projection #0.272class MultiBranchNode : public MultiNode {273public:274MultiBranchNode( uint required ) : MultiNode(required) {275init_class_id(Class_MultiBranch);276}277// returns required number of users to be well formed.278virtual int required_outcnt() const = 0;279};280281//------------------------------IfNode-----------------------------------------282// Output selected Control, based on a boolean test283class IfNode : public MultiBranchNode {284// Size is bigger to hold the probability field. However, _prob does not285// change the semantics so it does not appear in the hash & cmp functions.286virtual uint size_of() const { return sizeof(*this); }287288private:289// Helper methods for fold_compares290bool cmpi_folds(PhaseIterGVN* igvn, bool fold_ne = false);291bool is_ctrl_folds(Node* ctrl, PhaseIterGVN* igvn);292bool has_shared_region(ProjNode* proj, ProjNode*& success, ProjNode*& fail);293bool has_only_uncommon_traps(ProjNode* proj, ProjNode*& success, ProjNode*& fail, PhaseIterGVN* igvn);294Node* merge_uncommon_traps(ProjNode* proj, ProjNode* success, ProjNode* fail, PhaseIterGVN* igvn);295static void improve_address_types(Node* l, Node* r, ProjNode* fail, PhaseIterGVN* igvn);296bool is_cmp_with_loadrange(ProjNode* proj);297bool is_null_check(ProjNode* proj, PhaseIterGVN* igvn);298bool is_side_effect_free_test(ProjNode* proj, PhaseIterGVN* igvn);299void reroute_side_effect_free_unc(ProjNode* proj, ProjNode* dom_proj, PhaseIterGVN* igvn);300ProjNode* uncommon_trap_proj(CallStaticJavaNode*& call) const;301bool fold_compares_helper(ProjNode* proj, ProjNode* success, ProjNode* fail, PhaseIterGVN* igvn);302static bool is_dominator_unc(CallStaticJavaNode* dom_unc, CallStaticJavaNode* unc);303304protected:305ProjNode* range_check_trap_proj(int& flip, Node*& l, Node*& r);306Node* Ideal_common(PhaseGVN *phase, bool can_reshape);307Node* search_identical(int dist);308309Node* simple_subsuming(PhaseIterGVN* igvn);310311public:312313// Degrees of branch prediction probability by order of magnitude:314// PROB_UNLIKELY_1e(N) is a 1 in 1eN chance.315// PROB_LIKELY_1e(N) is a 1 - PROB_UNLIKELY_1e(N)316#define PROB_UNLIKELY_MAG(N) (1e- ## N ## f)317#define PROB_LIKELY_MAG(N) (1.0f-PROB_UNLIKELY_MAG(N))318319// Maximum and minimum branch prediction probabilties320// 1 in 1,000,000 (magnitude 6)321//322// Although PROB_NEVER == PROB_MIN and PROB_ALWAYS == PROB_MAX323// they are used to distinguish different situations:324//325// The name PROB_MAX (PROB_MIN) is for probabilities which correspond to326// very likely (unlikely) but with a concrete possibility of a rare327// contrary case. These constants would be used for pinning328// measurements, and as measures for assertions that have high329// confidence, but some evidence of occasional failure.330//331// The name PROB_ALWAYS (PROB_NEVER) is to stand for situations for which332// there is no evidence at all that the contrary case has ever occurred.333334#define PROB_NEVER PROB_UNLIKELY_MAG(6)335#define PROB_ALWAYS PROB_LIKELY_MAG(6)336337#define PROB_MIN PROB_UNLIKELY_MAG(6)338#define PROB_MAX PROB_LIKELY_MAG(6)339340// Static branch prediction probabilities341// 1 in 10 (magnitude 1)342#define PROB_STATIC_INFREQUENT PROB_UNLIKELY_MAG(1)343#define PROB_STATIC_FREQUENT PROB_LIKELY_MAG(1)344345// Fair probability 50/50346#define PROB_FAIR (0.5f)347348// Unknown probability sentinel349#define PROB_UNKNOWN (-1.0f)350351// Probability "constructors", to distinguish as a probability any manifest352// constant without a names353#define PROB_LIKELY(x) ((float) (x))354#define PROB_UNLIKELY(x) (1.0f - (float)(x))355356// Other probabilities in use, but without a unique name, are documented357// here for lack of a better place:358//359// 1 in 1000 probabilities (magnitude 3):360// threshold for converting to conditional move361// likelihood of null check failure if a null HAS been seen before362// likelihood of slow path taken in library calls363//364// 1 in 10,000 probabilities (magnitude 4):365// threshold for making an uncommon trap probability more extreme366// threshold for for making a null check implicit367// likelihood of needing a gc if eden top moves during an allocation368// likelihood of a predicted call failure369//370// 1 in 100,000 probabilities (magnitude 5):371// threshold for ignoring counts when estimating path frequency372// likelihood of FP clipping failure373// likelihood of catching an exception from a try block374// likelihood of null check failure if a null has NOT been seen before375//376// Magic manifest probabilities such as 0.83, 0.7, ... can be found in377// gen_subtype_check() and catch_inline_exceptions().378379float _prob; // Probability of true path being taken.380float _fcnt; // Frequency counter381IfNode( Node *control, Node *b, float p, float fcnt )382: MultiBranchNode(2), _prob(p), _fcnt(fcnt) {383init_class_id(Class_If);384init_req(0,control);385init_req(1,b);386}387virtual int Opcode() const;388virtual bool pinned() const { return true; }389virtual const Type *bottom_type() const { return TypeTuple::IFBOTH; }390virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);391virtual const Type* Value(PhaseGVN* phase) const;392virtual int required_outcnt() const { return 2; }393virtual const RegMask &out_RegMask() const;394Node* fold_compares(PhaseIterGVN* phase);395static Node* up_one_dom(Node* curr, bool linear_only = false);396Node* dominated_by(Node* prev_dom, PhaseIterGVN* igvn);397398// Takes the type of val and filters it through the test represented399// by if_proj and returns a more refined type if one is produced.400// Returns NULL is it couldn't improve the type.401static const TypeInt* filtered_int_type(PhaseGVN* phase, Node* val, Node* if_proj);402403#ifndef PRODUCT404virtual void dump_spec(outputStream *st) const;405virtual void related(GrowableArray <Node *> *in_rel, GrowableArray <Node *> *out_rel, bool compact) const;406#endif407};408409class RangeCheckNode : public IfNode {410private:411int is_range_check(Node* &range, Node* &index, jint &offset);412413public:414RangeCheckNode(Node* control, Node *b, float p, float fcnt)415: IfNode(control, b, p, fcnt) {416init_class_id(Class_RangeCheck);417}418419virtual int Opcode() const;420virtual Node* Ideal(PhaseGVN *phase, bool can_reshape);421};422423class IfProjNode : public CProjNode {424public:425IfProjNode(IfNode *ifnode, uint idx) : CProjNode(ifnode,idx) {}426virtual Node* Identity(PhaseGVN* phase);427428protected:429// Type of If input when this branch is always taken430virtual bool always_taken(const TypeTuple* t) const = 0;431432#ifndef PRODUCT433public:434virtual void related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const;435#endif436};437438class IfTrueNode : public IfProjNode {439public:440IfTrueNode( IfNode *ifnode ) : IfProjNode(ifnode,1) {441init_class_id(Class_IfTrue);442}443virtual int Opcode() const;444445protected:446virtual bool always_taken(const TypeTuple* t) const { return t == TypeTuple::IFTRUE; }447};448449class IfFalseNode : public IfProjNode {450public:451IfFalseNode( IfNode *ifnode ) : IfProjNode(ifnode,0) {452init_class_id(Class_IfFalse);453}454virtual int Opcode() const;455456protected:457virtual bool always_taken(const TypeTuple* t) const { return t == TypeTuple::IFFALSE; }458};459460461//------------------------------PCTableNode------------------------------------462// Build an indirect branch table. Given a control and a table index,463// control is passed to the Projection matching the table index. Used to464// implement switch statements and exception-handling capabilities.465// Undefined behavior if passed-in index is not inside the table.466class PCTableNode : public MultiBranchNode {467virtual uint hash() const; // Target count; table size468virtual bool cmp( const Node &n ) const;469virtual uint size_of() const { return sizeof(*this); }470471public:472const uint _size; // Number of targets473474PCTableNode( Node *ctrl, Node *idx, uint size ) : MultiBranchNode(2), _size(size) {475init_class_id(Class_PCTable);476init_req(0, ctrl);477init_req(1, idx);478}479virtual int Opcode() const;480virtual const Type* Value(PhaseGVN* phase) const;481virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);482virtual const Type *bottom_type() const;483virtual bool pinned() const { return true; }484virtual int required_outcnt() const { return _size; }485};486487//------------------------------JumpNode---------------------------------------488// Indirect branch. Uses PCTable above to implement a switch statement.489// It emits as a table load and local branch.490class JumpNode : public PCTableNode {491virtual uint size_of() const { return sizeof(*this); }492public:493float* _probs; // probability of each projection494float _fcnt; // total number of times this Jump was executed495JumpNode( Node* control, Node* switch_val, uint size, float* probs, float cnt)496: PCTableNode(control, switch_val, size),497_probs(probs), _fcnt(cnt) {498init_class_id(Class_Jump);499}500virtual int Opcode() const;501virtual const RegMask& out_RegMask() const;502virtual const Node* is_block_proj() const { return this; }503#ifndef PRODUCT504virtual void related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const;505#endif506};507508class JumpProjNode : public JProjNode {509virtual uint hash() const;510virtual bool cmp( const Node &n ) const;511virtual uint size_of() const { return sizeof(*this); }512513private:514const int _dest_bci;515const uint _proj_no;516const int _switch_val;517public:518JumpProjNode(Node* jumpnode, uint proj_no, int dest_bci, int switch_val)519: JProjNode(jumpnode, proj_no), _dest_bci(dest_bci), _proj_no(proj_no), _switch_val(switch_val) {520init_class_id(Class_JumpProj);521}522523virtual int Opcode() const;524virtual const Type* bottom_type() const { return Type::CONTROL; }525int dest_bci() const { return _dest_bci; }526int switch_val() const { return _switch_val; }527uint proj_no() const { return _proj_no; }528#ifndef PRODUCT529virtual void dump_spec(outputStream *st) const;530virtual void dump_compact_spec(outputStream *st) const;531virtual void related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const;532#endif533};534535//------------------------------CatchNode--------------------------------------536// Helper node to fork exceptions. "Catch" catches any exceptions thrown by537// a just-prior call. Looks like a PCTableNode but emits no code - just the538// table. The table lookup and branch is implemented by RethrowNode.539class CatchNode : public PCTableNode {540public:541CatchNode( Node *ctrl, Node *idx, uint size ) : PCTableNode(ctrl,idx,size){542init_class_id(Class_Catch);543}544virtual int Opcode() const;545virtual const Type* Value(PhaseGVN* phase) const;546};547548// CatchProjNode controls which exception handler is targetted after a call.549// It is passed in the bci of the target handler, or no_handler_bci in case550// the projection doesn't lead to an exception handler.551class CatchProjNode : public CProjNode {552virtual uint hash() const;553virtual bool cmp( const Node &n ) const;554virtual uint size_of() const { return sizeof(*this); }555556private:557const int _handler_bci;558559public:560enum {561fall_through_index = 0, // the fall through projection index562catch_all_index = 1, // the projection index for catch-alls563no_handler_bci = -1 // the bci for fall through or catch-all projs564};565566CatchProjNode(Node* catchnode, uint proj_no, int handler_bci)567: CProjNode(catchnode, proj_no), _handler_bci(handler_bci) {568init_class_id(Class_CatchProj);569assert(proj_no != fall_through_index || handler_bci < 0, "fall through case must have bci < 0");570}571572virtual int Opcode() const;573virtual Node* Identity(PhaseGVN* phase);574virtual const Type *bottom_type() const { return Type::CONTROL; }575int handler_bci() const { return _handler_bci; }576bool is_handler_proj() const { return _handler_bci >= 0; }577#ifndef PRODUCT578virtual void dump_spec(outputStream *st) const;579#endif580};581582583//---------------------------------CreateExNode--------------------------------584// Helper node to create the exception coming back from a call585class CreateExNode : public TypeNode {586public:587CreateExNode(const Type* t, Node* control, Node* i_o) : TypeNode(t, 2) {588init_req(0, control);589init_req(1, i_o);590}591virtual int Opcode() const;592virtual Node* Identity(PhaseGVN* phase);593virtual bool pinned() const { return true; }594uint match_edge(uint idx) const { return 0; }595virtual uint ideal_reg() const { return Op_RegP; }596};597598//------------------------------NeverBranchNode-------------------------------599// The never-taken branch. Used to give the appearance of exiting infinite600// loops to those algorithms that like all paths to be reachable. Encodes601// empty.602class NeverBranchNode : public MultiBranchNode {603public:604NeverBranchNode( Node *ctrl ) : MultiBranchNode(1) { init_req(0,ctrl); }605virtual int Opcode() const;606virtual bool pinned() const { return true; };607virtual const Type *bottom_type() const { return TypeTuple::IFBOTH; }608virtual const Type* Value(PhaseGVN* phase) const;609virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);610virtual int required_outcnt() const { return 2; }611virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { }612virtual uint size(PhaseRegAlloc *ra_) const { return 0; }613#ifndef PRODUCT614virtual void format( PhaseRegAlloc *, outputStream *st ) const;615#endif616};617618#endif // SHARE_OPTO_CFGNODE_HPP619620621