From 4f49057aab44cf910fce83e51c5547864802867c Mon Sep 17 00:00:00 2001 From: kvn Date: Thu, 18 Aug 2016 14:31:02 -0700 Subject: [PATCH] 8162496: missing precedence edge for anti_dependence Summary: fix Implicit Null Check optimization code. Reviewed-by: roland, aph --- src/share/vm/opto/block.cpp | 3 +++ src/share/vm/opto/block.hpp | 7 +++---- src/share/vm/opto/lcm.cpp | 29 ++++++++++++++++++++++++++--- 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/share/vm/opto/block.cpp b/src/share/vm/opto/block.cpp index f0599a19c..245ce429b 100644 --- a/src/share/vm/opto/block.cpp +++ b/src/share/vm/opto/block.cpp @@ -1208,6 +1208,9 @@ void PhaseCFG::verify() const { 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"); } + if (n->needs_anti_dependence_check()) { + verify_anti_dependences(block, n); + } for (uint k = 0; k < n->req(); k++) { Node *def = n->in(k); if (def && def != n) { diff --git a/src/share/vm/opto/block.hpp b/src/share/vm/opto/block.hpp index d085b29df..0c7363ed4 100644 --- a/src/share/vm/opto/block.hpp +++ b/src/share/vm/opto/block.hpp @@ -185,14 +185,13 @@ public: Block* lone_fall_through(); // Return lone fall-through Block or null Block* dom_lca(Block* that); // Compute LCA in dominator tree. -#ifdef ASSERT + bool dominates(Block* that) { int dom_diff = this->_dom_depth - that->_dom_depth; if (dom_diff > 0) return false; for (; dom_diff < 0; dom_diff++) that = that->_idom; return this == that; } -#endif // Report the alignment required by this block. Must be a power of 2. // The previous block will insert nops to get this alignment. @@ -473,9 +472,9 @@ class PhaseCFG : public Phase { MachNode* _goto; 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"); - insert_anti_dependences(LCA, load, true); + const_cast(this)->insert_anti_dependences(LCA, load, true); } bool move_to_next(Block* bx, uint b_index); diff --git a/src/share/vm/opto/lcm.cpp b/src/share/vm/opto/lcm.cpp index 06006ca9d..dd93b0fb9 100644 --- a/src/share/vm/opto/lcm.cpp +++ b/src/share/vm/opto/lcm.cpp @@ -246,6 +246,14 @@ void PhaseCFG::implicit_null_check(Block* block, Node *proj, Node *val, int allo 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 { intptr_t offset = 0; @@ -383,9 +391,12 @@ void PhaseCFG::implicit_null_check(Block* block, Node *proj, Node *val, int allo block->add_inst(best); map_node_to_block(best, block); - // Move the control dependence - if (best->in(0) && best->in(0) == old_block->head()) - best->set_req(0, block->head()); + // Move the control dependence if it is pinned to not-null block. + // Don't change it in other cases: NULL or dominating control. + 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 // 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 latency_from_uses(nul_chk); 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); + } + } + } } -- GitLab