提交 4f49057a 编写于 作者: K kvn

8162496: missing precedence edge for anti_dependence

Summary: fix Implicit Null Check optimization code.
Reviewed-by: roland, aph
上级 f38b0dfb
...@@ -1208,6 +1208,9 @@ void PhaseCFG::verify() const { ...@@ -1208,6 +1208,9 @@ void PhaseCFG::verify() const {
if (j >= 1 && n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_CreateEx) { if (j >= 1 && n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_CreateEx) {
assert(j == 1 || block->get_node(j-1)->is_Phi(), "CreateEx must be first instruction in block"); assert(j == 1 || block->get_node(j-1)->is_Phi(), "CreateEx must be first instruction in block");
} }
if (n->needs_anti_dependence_check()) {
verify_anti_dependences(block, n);
}
for (uint k = 0; k < n->req(); k++) { for (uint k = 0; k < n->req(); k++) {
Node *def = n->in(k); Node *def = n->in(k);
if (def && def != n) { if (def && def != n) {
......
...@@ -185,14 +185,13 @@ public: ...@@ -185,14 +185,13 @@ public:
Block* lone_fall_through(); // Return lone fall-through Block or null Block* lone_fall_through(); // Return lone fall-through Block or null
Block* dom_lca(Block* that); // Compute LCA in dominator tree. Block* dom_lca(Block* that); // Compute LCA in dominator tree.
#ifdef ASSERT
bool dominates(Block* that) { bool dominates(Block* that) {
int dom_diff = this->_dom_depth - that->_dom_depth; int dom_diff = this->_dom_depth - that->_dom_depth;
if (dom_diff > 0) return false; if (dom_diff > 0) return false;
for (; dom_diff < 0; dom_diff++) that = that->_idom; for (; dom_diff < 0; dom_diff++) that = that->_idom;
return this == that; return this == that;
} }
#endif
// Report the alignment required by this block. Must be a power of 2. // Report the alignment required by this block. Must be a power of 2.
// The previous block will insert nops to get this alignment. // The previous block will insert nops to get this alignment.
...@@ -473,9 +472,9 @@ class PhaseCFG : public Phase { ...@@ -473,9 +472,9 @@ class PhaseCFG : public Phase {
MachNode* _goto; MachNode* _goto;
Block* insert_anti_dependences(Block* LCA, Node* load, bool verify = false); Block* insert_anti_dependences(Block* LCA, Node* load, bool verify = false);
void verify_anti_dependences(Block* LCA, Node* load) { void verify_anti_dependences(Block* LCA, Node* load) const {
assert(LCA == get_block_for_node(load), "should already be scheduled"); assert(LCA == get_block_for_node(load), "should already be scheduled");
insert_anti_dependences(LCA, load, true); const_cast<PhaseCFG*>(this)->insert_anti_dependences(LCA, load, true);
} }
bool move_to_next(Block* bx, uint b_index); bool move_to_next(Block* bx, uint b_index);
......
...@@ -246,6 +246,14 @@ void PhaseCFG::implicit_null_check(Block* block, Node *proj, Node *val, int allo ...@@ -246,6 +246,14 @@ void PhaseCFG::implicit_null_check(Block* block, Node *proj, Node *val, int allo
continue; continue;
} }
// Check that node's control edge is not-null block's head or dominates it,
// otherwise we can't hoist it because there are other control dependencies.
Node* ctrl = mach->in(0);
if (ctrl != NULL && !(ctrl == not_null_block->head() ||
get_block_for_node(ctrl)->dominates(not_null_block))) {
continue;
}
// check if the offset is not too high for implicit exception // check if the offset is not too high for implicit exception
{ {
intptr_t offset = 0; intptr_t offset = 0;
...@@ -383,9 +391,12 @@ void PhaseCFG::implicit_null_check(Block* block, Node *proj, Node *val, int allo ...@@ -383,9 +391,12 @@ void PhaseCFG::implicit_null_check(Block* block, Node *proj, Node *val, int allo
block->add_inst(best); block->add_inst(best);
map_node_to_block(best, block); map_node_to_block(best, block);
// Move the control dependence // Move the control dependence if it is pinned to not-null block.
if (best->in(0) && best->in(0) == old_block->head()) // Don't change it in other cases: NULL or dominating control.
best->set_req(0, block->head()); if (best->in(0) == not_null_block->head()) {
// Set it to control edge of null check.
best->set_req(0, proj->in(0)->in(0));
}
// Check for flag-killing projections that also need to be hoisted // Check for flag-killing projections that also need to be hoisted
// Should be DU safe because no edge updates. // Should be DU safe because no edge updates.
...@@ -441,6 +452,18 @@ void PhaseCFG::implicit_null_check(Block* block, Node *proj, Node *val, int allo ...@@ -441,6 +452,18 @@ void PhaseCFG::implicit_null_check(Block* block, Node *proj, Node *val, int allo
latency_from_uses(nul_chk); latency_from_uses(nul_chk);
latency_from_uses(best); latency_from_uses(best);
// insert anti-dependences to defs in this block
if (! best->needs_anti_dependence_check()) {
for (uint k = 1; k < block->number_of_nodes(); k++) {
Node *n = block->get_node(k);
if (n->needs_anti_dependence_check() &&
n->in(LoadNode::Memory) == best->in(StoreNode::Memory)) {
// Found anti-dependent load
insert_anti_dependences(block, n);
}
}
}
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册