diff --git a/src/share/vm/opto/cfgnode.cpp b/src/share/vm/opto/cfgnode.cpp index 48bf400c81d0e30aaa593cfc3a021d6a48a8850f..ebf6eaeb82f88c0838ff46aa9a1ad5ba9300603a 100644 --- a/src/share/vm/opto/cfgnode.cpp +++ b/src/share/vm/opto/cfgnode.cpp @@ -1419,7 +1419,8 @@ PhiNode::LoopSafety PhiNode::simple_data_loop_check(Node *in) const { // 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 @@ bool PhiNode::is_unsafe_data_reference(Node *in) const { 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 --git a/src/share/vm/opto/connode.hpp b/src/share/vm/opto/connode.hpp index 0b5dd3cf977b400a38a91876129a733f2042ad9f..247a364c845dc071091ad549ee562dad8430799d 100644 --- a/src/share/vm/opto/connode.hpp +++ b/src/share/vm/opto/connode.hpp @@ -239,10 +239,7 @@ public: // 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 @@ class CheckCastPPNode: public TypeNode { 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 --git a/src/share/vm/opto/multnode.hpp b/src/share/vm/opto/multnode.hpp index 34a573ffcd3eb349dd4e9317b4d3d2a65ba78666..8c17f9d45f6b4032cb4ccb35d9e438aa9d848898 100644 --- a/src/share/vm/opto/multnode.hpp +++ b/src/share/vm/opto/multnode.hpp @@ -61,6 +61,9 @@ public: : 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 --git a/src/share/vm/opto/node.hpp b/src/share/vm/opto/node.hpp index e957887b3edf340de79439230f35123cbf7b5827..dc44aab22c807ab26361233c3ca04315b5d17db8 100644 --- a/src/share/vm/opto/node.hpp +++ b/src/share/vm/opto/node.hpp @@ -741,8 +741,9 @@ public: 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)