提交 2c9153d6 编写于 作者: K kvn

6809798: SafePointScalarObject node placed into incorrect block during GCM

Summary: Replace the control edge of a pinned node before scheduling.
Reviewed-by: never
上级 9ed90787
...@@ -909,6 +909,10 @@ void PhaseCFG::verify( ) const { ...@@ -909,6 +909,10 @@ void PhaseCFG::verify( ) const {
!(n->jvms() != NULL && n->jvms()->is_monitor_use(k)) ) { !(n->jvms() != NULL && n->jvms()->is_monitor_use(k)) ) {
assert( b->find_node(def) < j, "uses must follow definitions" ); assert( b->find_node(def) < j, "uses must follow definitions" );
} }
if( def->is_SafePointScalarObject() ) {
assert(_bbs[def->_idx] == b, "SafePointScalarObject Node should be at the same block as its SafePoint node");
assert(_bbs[def->_idx] == _bbs[def->in(0)->_idx], "SafePointScalarObject Node should be at the same block as its control edge");
}
} }
} }
} }
......
...@@ -347,6 +347,8 @@ class PhaseCFG : public Phase { ...@@ -347,6 +347,8 @@ class PhaseCFG : public Phase {
// Helper function to insert a node into a block // Helper function to insert a node into a block
void schedule_node_into_block( Node *n, Block *b ); void schedule_node_into_block( Node *n, Block *b );
void PhaseCFG::replace_block_proj_ctrl( Node *n );
// Set the basic block for pinned Nodes // Set the basic block for pinned Nodes
void schedule_pinned_nodes( VectorSet &visited ); void schedule_pinned_nodes( VectorSet &visited );
......
...@@ -975,6 +975,7 @@ SafePointScalarObjectNode::SafePointScalarObjectNode(const TypeOopPtr* tp, ...@@ -975,6 +975,7 @@ SafePointScalarObjectNode::SafePointScalarObjectNode(const TypeOopPtr* tp,
} }
bool SafePointScalarObjectNode::pinned() const { return true; } bool SafePointScalarObjectNode::pinned() const { return true; }
bool SafePointScalarObjectNode::depends_only_on_test() const { return false; }
uint SafePointScalarObjectNode::ideal_reg() const { uint SafePointScalarObjectNode::ideal_reg() const {
return 0; // No matching to machine instruction return 0; // No matching to machine instruction
......
...@@ -437,6 +437,10 @@ public: ...@@ -437,6 +437,10 @@ public:
// of the SafePoint node for which it was generated. // of the SafePoint node for which it was generated.
virtual bool pinned() const; // { return true; } virtual bool pinned() const; // { return true; }
// SafePointScalarObject depends on the SafePoint node
// for which it was generated.
virtual bool depends_only_on_test() const; // { return false; }
virtual uint size_of() const { return sizeof(*this); } virtual uint size_of() const { return sizeof(*this); }
// Assumes that "this" is an argument to a safepoint node "s", and that // Assumes that "this" is an argument to a safepoint node "s", and that
......
...@@ -57,6 +57,37 @@ void PhaseCFG::schedule_node_into_block( Node *n, Block *b ) { ...@@ -57,6 +57,37 @@ void PhaseCFG::schedule_node_into_block( Node *n, Block *b ) {
} }
} }
//----------------------------replace_block_proj_ctrl-------------------------
// Nodes that have is_block_proj() nodes as their control need to use
// the appropriate Region for their actual block as their control since
// the projection will be in a predecessor block.
void PhaseCFG::replace_block_proj_ctrl( Node *n ) {
const Node *in0 = n->in(0);
assert(in0 != NULL, "Only control-dependent");
const Node *p = in0->is_block_proj();
if (p != NULL && p != n) { // Control from a block projection?
assert(!n->pinned() || n->is_SafePointScalarObject(), "only SafePointScalarObject pinned node is expected here");
// Find trailing Region
Block *pb = _bbs[in0->_idx]; // Block-projection already has basic block
uint j = 0;
if (pb->_num_succs != 1) { // More then 1 successor?
// Search for successor
uint max = pb->_nodes.size();
assert( max > 1, "" );
uint start = max - pb->_num_succs;
// Find which output path belongs to projection
for (j = start; j < max; j++) {
if( pb->_nodes[j] == in0 )
break;
}
assert( j < max, "must find" );
// Change control to match head of successor basic block
j -= start;
}
n->set_req(0, pb->_succs[j]->head());
}
}
//------------------------------schedule_pinned_nodes-------------------------- //------------------------------schedule_pinned_nodes--------------------------
// Set the basic block for Nodes pinned into blocks // Set the basic block for Nodes pinned into blocks
...@@ -68,8 +99,10 @@ void PhaseCFG::schedule_pinned_nodes( VectorSet &visited ) { ...@@ -68,8 +99,10 @@ void PhaseCFG::schedule_pinned_nodes( VectorSet &visited ) {
Node *n = spstack.pop(); Node *n = spstack.pop();
if( !visited.test_set(n->_idx) ) { // Test node and flag it as visited if( !visited.test_set(n->_idx) ) { // Test node and flag it as visited
if( n->pinned() && !_bbs.lookup(n->_idx) ) { // Pinned? Nail it down! if( n->pinned() && !_bbs.lookup(n->_idx) ) { // Pinned? Nail it down!
assert( n->in(0), "pinned Node must have Control" );
// Before setting block replace block_proj control edge
replace_block_proj_ctrl(n);
Node *input = n->in(0); Node *input = n->in(0);
assert( input, "pinned Node must have Control" );
while( !input->is_block_start() ) while( !input->is_block_start() )
input = input->in(0); input = input->in(0);
Block *b = _bbs[input->_idx]; // Basic block of controlling input Block *b = _bbs[input->_idx]; // Basic block of controlling input
...@@ -158,34 +191,12 @@ bool PhaseCFG::schedule_early(VectorSet &visited, Node_List &roots) { ...@@ -158,34 +191,12 @@ bool PhaseCFG::schedule_early(VectorSet &visited, Node_List &roots) {
uint i = nstack_top_i; uint i = nstack_top_i;
if (i == 0) { if (i == 0) {
// Special control input processing. // Fixup some control. Constants without control get attached
// While I am here, go ahead and look for Nodes which are taking control // to root and nodes that use is_block_proj() nodes should be attached
// from a is_block_proj Node. After I inserted RegionNodes to make proper // to the region that starts their block.
// blocks, the control at a is_block_proj more properly comes from the
// Region being controlled by the block_proj Node.
const Node *in0 = n->in(0); const Node *in0 = n->in(0);
if (in0 != NULL) { // Control-dependent? if (in0 != NULL) { // Control-dependent?
const Node *p = in0->is_block_proj(); replace_block_proj_ctrl(n);
if (p != NULL && p != n) { // Control from a block projection?
// Find trailing Region
Block *pb = _bbs[in0->_idx]; // Block-projection already has basic block
uint j = 0;
if (pb->_num_succs != 1) { // More then 1 successor?
// Search for successor
uint max = pb->_nodes.size();
assert( max > 1, "" );
uint start = max - pb->_num_succs;
// Find which output path belongs to projection
for (j = start; j < max; j++) {
if( pb->_nodes[j] == in0 )
break;
}
assert( j < max, "must find" );
// Change control to match head of successor basic block
j -= start;
}
n->set_req(0, pb->_succs[j]->head());
}
} else { // n->in(0) == NULL } else { // n->in(0) == NULL
if (n->req() == 1) { // This guy is a constant with NO inputs? if (n->req() == 1) { // This guy is a constant with NO inputs?
n->set_req(0, _root); n->set_req(0, _root);
...@@ -226,6 +237,8 @@ bool PhaseCFG::schedule_early(VectorSet &visited, Node_List &roots) { ...@@ -226,6 +237,8 @@ bool PhaseCFG::schedule_early(VectorSet &visited, Node_List &roots) {
if (!n->pinned()) { if (!n->pinned()) {
// Set earliest legal block. // Set earliest legal block.
_bbs.map(n->_idx, find_deepest_input(n, _bbs)); _bbs.map(n->_idx, find_deepest_input(n, _bbs));
} else {
assert(_bbs[n->_idx] == _bbs[n->in(0)->_idx], "Pinned Node should be at the same block as its control edge");
} }
if (nstack.is_empty()) { if (nstack.is_empty()) {
......
...@@ -64,6 +64,7 @@ void PhaseMacroExpand::copy_call_debug_info(CallNode *oldcall, CallNode * newcal ...@@ -64,6 +64,7 @@ void PhaseMacroExpand::copy_call_debug_info(CallNode *oldcall, CallNode * newcal
uint old_unique = C->unique(); uint old_unique = C->unique();
Node* new_in = old_sosn->clone(jvms_adj, sosn_map); Node* new_in = old_sosn->clone(jvms_adj, sosn_map);
if (old_unique != C->unique()) { if (old_unique != C->unique()) {
new_in->set_req(0, newcall->in(0)); // reset control edge
new_in = transform_later(new_in); // Register new node. new_in = transform_later(new_in); // Register new node.
} }
old_in = new_in; old_in = new_in;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册