提交 c23606b8 编写于 作者: N never

6663848: assert(i < Max(),"oob") in C2 with -Xcomp

Summary: NeverBranchNodes aren't handled properly
Reviewed-by: kvn, sgoldman, rasbold, jrose
上级 1fd43683
...@@ -2019,6 +2019,28 @@ Node *CreateExNode::Identity( PhaseTransform *phase ) { ...@@ -2019,6 +2019,28 @@ Node *CreateExNode::Identity( PhaseTransform *phase ) {
} }
//============================================================================= //=============================================================================
//------------------------------Value------------------------------------------
// Check for being unreachable.
const Type *NeverBranchNode::Value( PhaseTransform *phase ) const {
if (!in(0) || in(0)->is_top()) return Type::TOP;
return bottom_type();
}
//------------------------------Ideal------------------------------------------
// Check for no longer being part of a loop
Node *NeverBranchNode::Ideal(PhaseGVN *phase, bool can_reshape) {
if (can_reshape && !in(0)->is_Loop()) {
// Dead code elimination can sometimes delete this projection so
// if it's not there, there's nothing to do.
Node* fallthru = proj_out(0);
if (fallthru != NULL) {
phase->is_IterGVN()->subsume_node(fallthru, in(0));
}
return phase->C->top();
}
return NULL;
}
#ifndef PRODUCT #ifndef PRODUCT
void NeverBranchNode::format( PhaseRegAlloc *ra_, outputStream *st) const { void NeverBranchNode::format( PhaseRegAlloc *ra_, outputStream *st) const {
st->print("%s", Name()); st->print("%s", Name());
......
...@@ -244,6 +244,8 @@ public: ...@@ -244,6 +244,8 @@ public:
MultiBranchNode( uint required ) : MultiNode(required) { MultiBranchNode( uint required ) : MultiNode(required) {
init_class_id(Class_MultiBranch); init_class_id(Class_MultiBranch);
} }
// returns required number of users to be well formed.
virtual int required_outcnt() const = 0;
}; };
//------------------------------IfNode----------------------------------------- //------------------------------IfNode-----------------------------------------
...@@ -333,6 +335,7 @@ public: ...@@ -333,6 +335,7 @@ public:
virtual const Type *bottom_type() const { return TypeTuple::IFBOTH; } virtual const Type *bottom_type() const { return TypeTuple::IFBOTH; }
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
virtual const Type *Value( PhaseTransform *phase ) const; virtual const Type *Value( PhaseTransform *phase ) const;
virtual int required_outcnt() const { return 2; }
virtual const RegMask &out_RegMask() const; virtual const RegMask &out_RegMask() const;
void dominated_by(Node* prev_dom, PhaseIterGVN* igvn); void dominated_by(Node* prev_dom, PhaseIterGVN* igvn);
int is_range_check(Node* &range, Node* &index, jint &offset); int is_range_check(Node* &range, Node* &index, jint &offset);
...@@ -391,6 +394,7 @@ public: ...@@ -391,6 +394,7 @@ public:
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
virtual const Type *bottom_type() const; virtual const Type *bottom_type() const;
virtual bool pinned() const { return true; } virtual bool pinned() const { return true; }
virtual int required_outcnt() const { return _size; }
}; };
//------------------------------JumpNode--------------------------------------- //------------------------------JumpNode---------------------------------------
...@@ -504,7 +508,9 @@ public: ...@@ -504,7 +508,9 @@ public:
virtual int Opcode() const; virtual int Opcode() const;
virtual bool pinned() const { return true; }; virtual bool pinned() const { return true; };
virtual const Type *bottom_type() const { return TypeTuple::IFBOTH; } virtual const Type *bottom_type() const { return TypeTuple::IFBOTH; }
virtual const Type *Value( PhaseTransform *phase ) const;
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
virtual int required_outcnt() const { return 2; }
virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { } virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { }
virtual uint size(PhaseRegAlloc *ra_) const { return 0; } virtual uint size(PhaseRegAlloc *ra_) const { return 0; }
#ifndef PRODUCT #ifndef PRODUCT
......
...@@ -1981,10 +1981,6 @@ static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &fpu ) { ...@@ -1981,10 +1981,6 @@ static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &fpu ) {
#endif #endif
break; break;
} }
case Op_If:
case Op_CountedLoopEnd:
fpu._tests.push(n); // Collect CFG split points
break;
case Op_AddP: { // Assert sane base pointers case Op_AddP: { // Assert sane base pointers
const Node *addp = n->in(AddPNode::Address); const Node *addp = n->in(AddPNode::Address);
...@@ -2083,10 +2079,12 @@ static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &fpu ) { ...@@ -2083,10 +2079,12 @@ static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &fpu ) {
default: default:
assert( !n->is_Call(), "" ); assert( !n->is_Call(), "" );
assert( !n->is_Mem(), "" ); assert( !n->is_Mem(), "" );
if( n->is_If() || n->is_PCTable() )
fpu._tests.push(n); // Collect CFG split points
break; break;
} }
// Collect CFG split points
if (n->is_MultiBranch())
fpu._tests.push(n);
} }
//------------------------------final_graph_reshaping_walk--------------------- //------------------------------final_graph_reshaping_walk---------------------
...@@ -2165,19 +2163,18 @@ bool Compile::final_graph_reshaping() { ...@@ -2165,19 +2163,18 @@ bool Compile::final_graph_reshaping() {
// Check for unreachable (from below) code (i.e., infinite loops). // Check for unreachable (from below) code (i.e., infinite loops).
for( uint i = 0; i < fpu._tests.size(); i++ ) { for( uint i = 0; i < fpu._tests.size(); i++ ) {
Node *n = fpu._tests[i]; MultiBranchNode *n = fpu._tests[i]->as_MultiBranch();
assert( n->is_PCTable() || n->is_If(), "either PCTables or IfNodes" ); // Get number of CFG targets.
// Get number of CFG targets; 2 for IfNodes or _size for PCTables.
// Note that PCTables include exception targets after calls. // Note that PCTables include exception targets after calls.
uint expected_kids = n->is_PCTable() ? n->as_PCTable()->_size : 2; uint required_outcnt = n->required_outcnt();
if (n->outcnt() != expected_kids) { if (n->outcnt() != required_outcnt) {
// Check for a few special cases. Rethrow Nodes never take the // Check for a few special cases. Rethrow Nodes never take the
// 'fall-thru' path, so expected kids is 1 less. // 'fall-thru' path, so expected kids is 1 less.
if (n->is_PCTable() && n->in(0) && n->in(0)->in(0)) { if (n->is_PCTable() && n->in(0) && n->in(0)->in(0)) {
if (n->in(0)->in(0)->is_Call()) { if (n->in(0)->in(0)->is_Call()) {
CallNode *call = n->in(0)->in(0)->as_Call(); CallNode *call = n->in(0)->in(0)->as_Call();
if (call->entry_point() == OptoRuntime::rethrow_stub()) { if (call->entry_point() == OptoRuntime::rethrow_stub()) {
expected_kids--; // Rethrow always has 1 less kid required_outcnt--; // Rethrow always has 1 less kid
} else if (call->req() > TypeFunc::Parms && } else if (call->req() > TypeFunc::Parms &&
call->is_CallDynamicJava()) { call->is_CallDynamicJava()) {
// Check for null receiver. In such case, the optimizer has // Check for null receiver. In such case, the optimizer has
...@@ -2187,7 +2184,7 @@ bool Compile::final_graph_reshaping() { ...@@ -2187,7 +2184,7 @@ bool Compile::final_graph_reshaping() {
Node *arg0 = call->in(TypeFunc::Parms); Node *arg0 = call->in(TypeFunc::Parms);
if (arg0->is_Type() && if (arg0->is_Type() &&
arg0->as_Type()->type()->higher_equal(TypePtr::NULL_PTR)) { arg0->as_Type()->type()->higher_equal(TypePtr::NULL_PTR)) {
expected_kids--; required_outcnt--;
} }
} else if (call->entry_point() == OptoRuntime::new_array_Java() && } else if (call->entry_point() == OptoRuntime::new_array_Java() &&
call->req() > TypeFunc::Parms+1 && call->req() > TypeFunc::Parms+1 &&
...@@ -2198,13 +2195,13 @@ bool Compile::final_graph_reshaping() { ...@@ -2198,13 +2195,13 @@ bool Compile::final_graph_reshaping() {
Node *arg1 = call->in(TypeFunc::Parms+1); Node *arg1 = call->in(TypeFunc::Parms+1);
if (arg1->is_Type() && if (arg1->is_Type() &&
arg1->as_Type()->type()->join(TypeInt::POS)->empty()) { arg1->as_Type()->type()->join(TypeInt::POS)->empty()) {
expected_kids--; required_outcnt--;
} }
} }
} }
} }
// Recheck with a better notion of 'expected_kids' // Recheck with a better notion of 'required_outcnt'
if (n->outcnt() != expected_kids) { if (n->outcnt() != required_outcnt) {
record_method_not_compilable("malformed control flow"); record_method_not_compilable("malformed control flow");
return true; // Not all targets reachable! return true; // Not all targets reachable!
} }
......
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册