6625997: CastPP, CheckCastPP and Proj nodes are not dead loop safe
authorkvn
Wed, 23 Apr 2008 19:09:16 -0700
changeset 373 427fb4ca6a1e
parent 372 b0d8a9fd3646
child 374 585c671c9c0e
6625997: CastPP, CheckCastPP and Proj nodes are not dead loop safe Summary: EA and initialization optimizations could bypass these nodes. Reviewed-by: rasbold, never
hotspot/src/share/vm/opto/cfgnode.cpp
hotspot/src/share/vm/opto/connode.hpp
hotspot/src/share/vm/opto/multnode.hpp
hotspot/src/share/vm/opto/node.hpp
--- a/hotspot/src/share/vm/opto/cfgnode.cpp	Wed Apr 23 13:57:14 2008 -0700
+++ b/hotspot/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
--- a/hotspot/src/share/vm/opto/connode.hpp	Wed Apr 23 13:57:14 2008 -0700
+++ b/hotspot/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);
--- a/hotspot/src/share/vm/opto/multnode.hpp	Wed Apr 23 13:57:14 2008 -0700
+++ b/hotspot/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
--- a/hotspot/src/share/vm/opto/node.hpp	Wed Apr 23 13:57:14 2008 -0700
+++ b/hotspot/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)