/* * Copyright (c) 1997, 2022, Oracle and/or its affiliates. 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. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. *
*/
class Matcher; class Node; class RegionNode; class TypeNode; class PhiNode; class GotoNode; class MultiNode; class MultiBranchNode; class IfNode; class PCTableNode; class JumpNode; class CatchNode; class NeverBranchNode; class BlackholeNode; class ProjNode; class CProjNode; class IfTrueNode; class IfFalseNode; class CatchProjNode; class JProjNode; class JumpProjNode; class SCMemProjNode; class PhaseIdealLoop;
//------------------------------RegionNode------------------------------------- // The class of RegionNodes, which can be mapped to basic blocks in the // program. Their inputs point to Control sources. PhiNodes (described // below) have an input point to a RegionNode. Merged data inputs to PhiNodes // correspond 1-to-1 with RegionNode inputs. The zero input of a PhiNode is // the RegionNode, and the zero input of the RegionNode is itself. class RegionNode : public Node { private: bool _is_unreachable_region;
bool is_possible_unsafe_loop(const PhaseGVN* phase) const; bool is_unreachable_from_root(const PhaseGVN* phase) const; public: // Node layout (parallels PhiNode): enum { Region, // Generally points to self.
Control // Control arcs are [1..len)
};
//------------------------------PhiNode---------------------------------------- // PhiNodes merge values from different Control paths. Slot 0 points to the // controlling RegionNode. Other slots map 1-for-1 with incoming control flow // paths to the RegionNode. class PhiNode : public TypeNode { friendclass PhaseRenumberLive;
const TypePtr* const _adr_type; // non-null only for Type::MEMORY nodes. // The following fields are only used for data PhiNodes to indicate // that the PhiNode represents the value of a known instance field. int _inst_mem_id; // Instance memory id (node index of the memory Phi) int _inst_id; // Instance id of the memory slice. constint _inst_index; // Alias index of the instance memory slice. // Array elements references have the same alias_idx but different offset. constint _inst_offset; // Offset of the instance memory slice. // Size is bigger to hold the _adr_type field. virtual uint hash() const; // Check the type virtualbool cmp( const Node &n ) const; virtual uint size_of() const { returnsizeof(*this); }
// Determine if CMoveNode::is_cmove_id can be used at this join point.
Node* is_cmove_id(PhaseTransform* phase, int true_path); bool wait_for_region_igvn(PhaseGVN* phase); bool is_data_loop(RegionNode* r, Node* uin, const PhaseGVN* phase);
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, constint imid = -1, constint iid = TypeOopPtr::InstanceTop, constint iidx = Compile::AliasIdxTop, constint ioffs = Type::OffsetTop )
: TypeNode(t,r->req()),
_adr_type(at),
_inst_mem_id(imid),
_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 );
//---------------------------MultiBranchNode----------------------------------- // This class defines a MultiBranchNode, a MultiNode which yields multiple // control values. These are distinguished from other types of MultiNodes // which yield multiple values, but control is always and only projection #0. class MultiBranchNode : public MultiNode { public:
MultiBranchNode( uint required ) : MultiNode(required) {
init_class_id(Class_MultiBranch);
} // returns required number of users to be well formed. virtualint required_outcnt() const = 0;
};
//------------------------------IfNode----------------------------------------- // Output selected Control, based on a boolean test class IfNode : public MultiBranchNode { // Size is bigger to hold the probability field. However, _prob does not // change the semantics so it does not appear in the hash & cmp functions. virtual uint size_of() const { returnsizeof(*this); }
// Degrees of branch prediction probability by order of magnitude: // PROB_UNLIKELY_1e(N) is a 1 in 1eN chance. // PROB_LIKELY_1e(N) is a 1 - PROB_UNLIKELY_1e(N) #define PROB_UNLIKELY_MAG(N) (1e- ## N ## f) #define PROB_LIKELY_MAG(N) (1.0f-PROB_UNLIKELY_MAG(N))
// Maximum and minimum branch prediction probabilties // 1 in 1,000,000 (magnitude 6) // // Although PROB_NEVER == PROB_MIN and PROB_ALWAYS == PROB_MAX // they are used to distinguish different situations: // // The name PROB_MAX (PROB_MIN) is for probabilities which correspond to // very likely (unlikely) but with a concrete possibility of a rare // contrary case. These constants would be used for pinning // measurements, and as measures for assertions that have high // confidence, but some evidence of occasional failure. // // The name PROB_ALWAYS (PROB_NEVER) is to stand for situations for which // there is no evidence at all that the contrary case has ever occurred.
// Fair probability 50/50 #define PROB_FAIR (0.5f)
// Unknown probability sentinel #define PROB_UNKNOWN (-1.0f)
// Probability "constructors", to distinguish as a probability any manifest // constant without a names #define PROB_LIKELY(x) ((float) (x)) #define PROB_UNLIKELY(x) (1.0f - (float)(x))
// Other probabilities in use, but without a unique name, are documented // here for lack of a better place: // // 1 in 1000 probabilities (magnitude 3): // threshold for converting to conditional move // likelihood of null check failure if a null HAS been seen before // likelihood of slow path taken in library calls // // 1 in 10,000 probabilities (magnitude 4): // threshold for making an uncommon trap probability more extreme // threshold for for making a null check implicit // likelihood of needing a gc if eden top moves during an allocation // likelihood of a predicted call failure // // 1 in 100,000 probabilities (magnitude 5): // threshold for ignoring counts when estimating path frequency // likelihood of FP clipping failure // likelihood of catching an exception from a try block // likelihood of null check failure if a null has NOT been seen before // // Magic manifest probabilities such as 0.83, 0.7, ... can be found in // gen_subtype_check() and catch_inline_exceptions().
// Takes the type of val and filters it through the test represented // by if_proj and returns a more refined type if one is produced. // Returns NULL is it couldn't improve the type. staticconst TypeInt* filtered_int_type(PhaseGVN* phase, Node* val, Node* if_proj);
//------------------------------PCTableNode------------------------------------ // Build an indirect branch table. Given a control and a table index, // control is passed to the Projection matching the table index. Used to // implement switch statements and exception-handling capabilities. // Undefined behavior if passed-in index is not inside the table. class PCTableNode : public MultiBranchNode { virtual uint hash() const; // Target count; table size virtualbool cmp( const Node &n ) const; virtual uint size_of() const { returnsizeof(*this); }
//------------------------------JumpNode--------------------------------------- // Indirect branch. Uses PCTable above to implement a switch statement. // It emits as a table load and local branch. class JumpNode : public PCTableNode { virtual uint size_of() const { returnsizeof(*this); } public: float* _probs; // probability of each projection float _fcnt; // total number of times this Jump was executed
JumpNode( Node* control, Node* switch_val, uint size, float* probs, float cnt)
: PCTableNode(control, switch_val, size),
_probs(probs), _fcnt(cnt) {
init_class_id(Class_Jump);
} virtualint Opcode() const; virtualconst RegMask& out_RegMask() const; virtualconst Node* is_block_proj() const { returnthis; }
};
//------------------------------CatchNode-------------------------------------- // Helper node to fork exceptions. "Catch" catches any exceptions thrown by // a just-prior call. Looks like a PCTableNode but emits no code - just the // table. The table lookup and branch is implemented by RethrowNode. class CatchNode : public PCTableNode { public:
CatchNode( Node *ctrl, Node *idx, uint size ) : PCTableNode(ctrl,idx,size){
init_class_id(Class_Catch);
} virtualint Opcode() const; virtualconst Type* Value(PhaseGVN* phase) const;
};
// CatchProjNode controls which exception handler is targeted after a call. // It is passed in the bci of the target handler, or no_handler_bci in case // the projection doesn't lead to an exception handler. class CatchProjNode : public CProjNode { virtual uint hash() const; virtualbool cmp( const Node &n ) const; virtual uint size_of() const { returnsizeof(*this); }
private: constint _handler_bci;
public: enum {
fall_through_index = 0, // the fall through projection index
catch_all_index = 1, // the projection index for catch-alls
no_handler_bci = -1 // the bci for fall through or catch-all projs
};
CatchProjNode(Node* catchnode, uint proj_no, int handler_bci)
: CProjNode(catchnode, proj_no), _handler_bci(handler_bci) {
init_class_id(Class_CatchProj);
assert(proj_no != fall_through_index || handler_bci < 0, "fall through case must have bci < 0");
}
//---------------------------------CreateExNode-------------------------------- // Helper node to create the exception coming back from a call class CreateExNode : public TypeNode { public:
CreateExNode(const Type* t, Node* control, Node* i_o) : TypeNode(t, 2) {
init_req(0, control);
init_req(1, i_o);
} virtualint Opcode() const; virtual Node* Identity(PhaseGVN* phase); virtualbool pinned() const { returntrue; }
uint match_edge(uint idx) const { return 0; } virtual uint ideal_reg() const { return Op_RegP; }
};
//------------------------------NeverBranchNode------------------------------- // The never-taken branch. Used to give the appearance of exiting infinite // loops to those algorithms that like all paths to be reachable. Encodes // empty. class NeverBranchNode : public MultiBranchNode { public:
NeverBranchNode( Node *ctrl ) : MultiBranchNode(1) { init_req(0,ctrl); } virtualint Opcode() const; virtualbool pinned() const { returntrue; }; virtualconst Type *bottom_type() const { return TypeTuple::IFBOTH; } virtualconst Type* Value(PhaseGVN* phase) const; virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); virtualint required_outcnt() const { return 2; } virtualvoid emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { } virtual uint size(PhaseRegAlloc *ra_) const { return 0; } #ifndef PRODUCT virtualvoid format( PhaseRegAlloc *, outputStream *st ) const; #endif
};
//------------------------------BlackholeNode---------------------------- // Blackhole all arguments. This node would survive through the compiler // the effects on its arguments, and would be finally matched to nothing. class BlackholeNode : public MultiNode { public:
BlackholeNode(Node* ctrl) : MultiNode(1) {
init_req(TypeFunc::Control, ctrl);
} virtualint Opcode() const; virtual uint ideal_reg() const { return 0; } // not matched in the AD file virtualconst Type* bottom_type() const { return TypeTuple::MEMBAR; }
const RegMask &in_RegMask(uint idx) const { // Fake the incoming arguments mask for blackholes: accept all registers // and all stack slots. This would avoid any redundant register moves // for blackhole inputs. return RegMask::All;
} #ifndef PRODUCT virtualvoid format(PhaseRegAlloc* ra, outputStream* st) const; #endif
};
#endif// SHARE_OPTO_CFGNODE_HPP
Messung V0.5
¤ Dauer der Verarbeitung: 0.2 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.