# HG changeset patch # User kvn # Date 1209002956 25200 # Node ID 72f4a668df195d424f60c2234f9a78e402a97283 # Parent d942c7e64bd91a7f60e9e807c9fc2150e111d901 6625997: CastPP, CheckCastPP and Proj nodes are not dead loop safe Summary: EA and initialization optimizations could bypass these nodes. Reviewed-by: rasbold, never diff -r d942c7e64bd9 -r 72f4a668df19 src/share/vm/opto/cfgnode.cpp --- a/src/share/vm/opto/cfgnode.cpp Wed Apr 23 13:57:14 2008 -0700 +++ b/src/share/vm/opto/cfgnode.cpp Wed Apr 23 19:09:16 2008 -0700 @@ -1419,7 +1419,8 @@ // Check inputs of phi's inputs also. // It is much less expensive then full graph walk. uint cnt = in->req(); - for (uint i = 1; i < cnt; ++i) { + uint i = (in->is_Proj() && !in->is_CFG()) ? 0 : 1; + for (; i < cnt; ++i) { Node* m = in->in(i); if (m == (Node*)this) return UnsafeLoop; // Unsafe loop @@ -1467,7 +1468,8 @@ while (nstack.size() != 0) { Node* n = nstack.pop(); uint cnt = n->req(); - for (uint i = 1; i < cnt; i++) { // Only data paths + uint i = (n->is_Proj() && !n->is_CFG()) ? 0 : 1; + for (; i < cnt; i++) { Node* m = n->in(i); if (m == (Node*)this) { return true; // Data loop diff -r d942c7e64bd9 -r 72f4a668df19 src/share/vm/opto/connode.hpp --- a/src/share/vm/opto/connode.hpp Wed Apr 23 13:57:14 2008 -0700 +++ b/src/share/vm/opto/connode.hpp Wed Apr 23 19:09:16 2008 -0700 @@ -239,10 +239,7 @@ // cast pointer to pointer (different type) class CastPPNode: public ConstraintCastNode { public: - CastPPNode (Node *n, const Type *t ): ConstraintCastNode(n, t) { - // Only CastPP is safe. CastII can cause optimizer loops. - init_flags(Flag_is_dead_loop_safe); - } + CastPPNode (Node *n, const Type *t ): ConstraintCastNode(n, t) {} virtual int Opcode() const; virtual uint ideal_reg() const { return Op_RegP; } virtual Node *Ideal_DU_postCCP( PhaseCCP * ); @@ -254,10 +251,10 @@ public: CheckCastPPNode( Node *c, Node *n, const Type *t ) : TypeNode(t,2) { init_class_id(Class_CheckCastPP); - init_flags(Flag_is_dead_loop_safe); init_req(0, c); init_req(1, n); } + virtual Node *Identity( PhaseTransform *phase ); virtual const Type *Value( PhaseTransform *phase ) const; virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); diff -r d942c7e64bd9 -r 72f4a668df19 src/share/vm/opto/multnode.hpp --- a/src/share/vm/opto/multnode.hpp Wed Apr 23 13:57:14 2008 -0700 +++ b/src/share/vm/opto/multnode.hpp Wed Apr 23 19:09:16 2008 -0700 @@ -61,6 +61,9 @@ : Node( src ), _con(con), _is_io_use(io_use) { init_class_id(Class_Proj); + // Optimistic setting. Need additional checks in Node::is_dead_loop_safe(). + if (con != TypeFunc::Memory || src->is_Start()) + init_flags(Flag_is_dead_loop_safe); debug_only(check_con()); } const uint _con; // The field in the tuple we are projecting diff -r d942c7e64bd9 -r 72f4a668df19 src/share/vm/opto/node.hpp --- a/src/share/vm/opto/node.hpp Wed Apr 23 13:57:14 2008 -0700 +++ b/src/share/vm/opto/node.hpp Wed Apr 23 19:09:16 2008 -0700 @@ -741,8 +741,9 @@ bool is_Goto() const { return (_flags & Flag_is_Goto) != 0; } // The data node which is safe to leave in dead loop during IGVN optimization. bool is_dead_loop_safe() const { - return is_Phi() || is_Proj() || - (_flags & (Flag_is_dead_loop_safe | Flag_is_Con)) != 0; + return is_Phi() || (is_Proj() && in(0) == NULL) || + ((_flags & (Flag_is_dead_loop_safe | Flag_is_Con)) != 0 && + (!is_Proj() || !in(0)->is_Allocate())); } // is_Copy() returns copied edge index (0 or 1)