mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-18 18:14:38 +02:00
8162496: missing precedence edge for anti_dependence
Fix Implicit Null Check optimization code. Reviewed-by: roland, aph
This commit is contained in:
parent
c645d7bb87
commit
c6d82df571
3 changed files with 32 additions and 7 deletions
|
@ -1212,6 +1212,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) {
|
||||||
|
|
|
@ -186,14 +186,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.
|
||||||
|
@ -481,9 +480,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);
|
||||||
|
|
|
@ -240,6 +240,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;
|
||||||
|
@ -379,9 +387,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.
|
||||||
|
@ -437,6 +448,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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue