aboutsummaryrefslogtreecommitdiff
path: root/src/share
diff options
context:
space:
mode:
authorkvn <none@none>2008-04-23 19:09:16 -0700
committerkvn <none@none>2008-04-23 19:09:16 -0700
commitbb6484ee053730dc6bcab567a8b17c0e5ae2829e (patch)
treed826920ead48efae2966b80459b6fff9f39894bf /src/share
parentaac45ecc8cc694200a034d911b9f0052255514b4 (diff)
6625997: CastPP, CheckCastPP and Proj nodes are not dead loop safe
Summary: EA and initialization optimizations could bypass these nodes. Reviewed-by: rasbold, never
Diffstat (limited to 'src/share')
-rw-r--r--src/share/vm/opto/cfgnode.cpp6
-rw-r--r--src/share/vm/opto/connode.hpp7
-rw-r--r--src/share/vm/opto/multnode.hpp3
-rw-r--r--src/share/vm/opto/node.hpp5
4 files changed, 12 insertions, 9 deletions
diff --git a/src/share/vm/opto/cfgnode.cpp b/src/share/vm/opto/cfgnode.cpp
index 48bf400c8..ebf6eaeb8 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 0b5dd3cf9..247a364c8 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 34a573ffc..8c17f9d45 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 e957887b3..dc44aab22 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)