提交 1fd43683 编写于 作者: K kvn

6625997: CastPP, CheckCastPP and Proj nodes are not dead loop safe

Summary: EA and initialization optimizations could bypass these nodes.
Reviewed-by: rasbold, never
上级 ecc663f6
...@@ -1419,7 +1419,8 @@ PhiNode::LoopSafety PhiNode::simple_data_loop_check(Node *in) const { ...@@ -1419,7 +1419,8 @@ PhiNode::LoopSafety PhiNode::simple_data_loop_check(Node *in) const {
// Check inputs of phi's inputs also. // Check inputs of phi's inputs also.
// It is much less expensive then full graph walk. // It is much less expensive then full graph walk.
uint cnt = in->req(); 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); Node* m = in->in(i);
if (m == (Node*)this) if (m == (Node*)this)
return UnsafeLoop; // Unsafe loop return UnsafeLoop; // Unsafe loop
...@@ -1467,7 +1468,8 @@ bool PhiNode::is_unsafe_data_reference(Node *in) const { ...@@ -1467,7 +1468,8 @@ bool PhiNode::is_unsafe_data_reference(Node *in) const {
while (nstack.size() != 0) { while (nstack.size() != 0) {
Node* n = nstack.pop(); Node* n = nstack.pop();
uint cnt = n->req(); 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); Node* m = n->in(i);
if (m == (Node*)this) { if (m == (Node*)this) {
return true; // Data loop return true; // Data loop
......
...@@ -239,10 +239,7 @@ public: ...@@ -239,10 +239,7 @@ public:
// cast pointer to pointer (different type) // cast pointer to pointer (different type)
class CastPPNode: public ConstraintCastNode { class CastPPNode: public ConstraintCastNode {
public: public:
CastPPNode (Node *n, const Type *t ): ConstraintCastNode(n, t) { 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);
}
virtual int Opcode() const; virtual int Opcode() const;
virtual uint ideal_reg() const { return Op_RegP; } virtual uint ideal_reg() const { return Op_RegP; }
virtual Node *Ideal_DU_postCCP( PhaseCCP * ); virtual Node *Ideal_DU_postCCP( PhaseCCP * );
...@@ -254,10 +251,10 @@ class CheckCastPPNode: public TypeNode { ...@@ -254,10 +251,10 @@ class CheckCastPPNode: public TypeNode {
public: public:
CheckCastPPNode( Node *c, Node *n, const Type *t ) : TypeNode(t,2) { CheckCastPPNode( Node *c, Node *n, const Type *t ) : TypeNode(t,2) {
init_class_id(Class_CheckCastPP); init_class_id(Class_CheckCastPP);
init_flags(Flag_is_dead_loop_safe);
init_req(0, c); init_req(0, c);
init_req(1, n); init_req(1, n);
} }
virtual Node *Identity( PhaseTransform *phase ); virtual Node *Identity( PhaseTransform *phase );
virtual const Type *Value( PhaseTransform *phase ) const; virtual const Type *Value( PhaseTransform *phase ) const;
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
......
...@@ -61,6 +61,9 @@ public: ...@@ -61,6 +61,9 @@ public:
: Node( src ), _con(con), _is_io_use(io_use) : Node( src ), _con(con), _is_io_use(io_use)
{ {
init_class_id(Class_Proj); 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()); debug_only(check_con());
} }
const uint _con; // The field in the tuple we are projecting const uint _con; // The field in the tuple we are projecting
......
...@@ -741,8 +741,9 @@ public: ...@@ -741,8 +741,9 @@ public:
bool is_Goto() const { return (_flags & Flag_is_Goto) != 0; } bool is_Goto() const { return (_flags & Flag_is_Goto) != 0; }
// The data node which is safe to leave in dead loop during IGVN optimization. // The data node which is safe to leave in dead loop during IGVN optimization.
bool is_dead_loop_safe() const { bool is_dead_loop_safe() const {
return is_Phi() || is_Proj() || return is_Phi() || (is_Proj() && in(0) == NULL) ||
(_flags & (Flag_is_dead_loop_safe | Flag_is_Con)) != 0; ((_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) // is_Copy() returns copied edge index (0 or 1)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册