hotspot/src/share/vm/opto/lcm.cpp
Print this page
rev 611 : Merge
*** 1,10 ****
#ifdef USE_PRAGMA_IDENT_SRC
#pragma ident "@(#)lcm.cpp 1.102 07/05/17 15:58:55 JVM"
#endif
/*
! * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
--- 1,10 ----
#ifdef USE_PRAGMA_IDENT_SRC
#pragma ident "@(#)lcm.cpp 1.102 07/05/17 15:58:55 JVM"
#endif
/*
! * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*** 59,68 ****
--- 59,71 ----
} else {
assert(_nodes[_nodes.size()-2] == proj, "proj is one or the other");
not_null_block = _succs[0];
null_block = _succs[1];
}
+ while (null_block->is_Empty() == Block::empty_with_goto) {
+ null_block = null_block->_succs[0];
+ }
// Search the exception block for an uncommon trap.
// (See Parse::do_if and Parse::do_ifnull for the reason
// we need an uncommon trap. Briefly, we need a way to
// detect failure of this optimization, as in 6366351.)
*** 111,122 ****
--- 114,127 ----
case Op_LoadD:
case Op_LoadF:
case Op_LoadI:
case Op_LoadL:
case Op_LoadP:
+ case Op_LoadN:
case Op_LoadS:
case Op_LoadKlass:
+ case Op_LoadNKlass:
case Op_LoadRange:
case Op_LoadD_unaligned:
case Op_LoadL_unaligned:
break;
case Op_StoreB:
*** 125,141 ****
--- 130,148 ----
case Op_StoreD:
case Op_StoreF:
case Op_StoreI:
case Op_StoreL:
case Op_StoreP:
+ case Op_StoreN:
was_store = true; // Memory op is a store op
// Stores will have their address in slot 2 (memory in slot 1).
// If the value being nul-checked is in another slot, it means we
// are storing the checked value, which does NOT check the value!
if( mach->in(2) != val ) continue;
break; // Found a memory op?
case Op_StrComp:
+ case Op_AryEq:
// Not a legit memory op for implicit null check regardless of
// embedded loads
continue;
default: // Also check for embedded loads
if( !mach->needs_anti_dependence_check() )
*** 146,155 ****
--- 153,166 ----
{
intptr_t offset = 0;
const TypePtr *adr_type = NULL; // Do not need this return value here
const Node* base = mach->get_base_and_disp(offset, adr_type);
if (base == NULL || base == NodeSentinel) {
+ // Narrow oop address doesn't have base, only index
+ if( val->bottom_type()->isa_narrowoop() &&
+ MacroAssembler::needs_explicit_null_check(offset) )
+ continue; // Give up if offset is beyond page size
// cannot reason about it; is probably not implicit null exception
} else {
const TypePtr* tptr = base->bottom_type()->is_ptr();
// Give up if offset is not a compile-time constant
if( offset == Type::OffsetBot || tptr->_offset == Type::OffsetBot )
*** 319,329 ****
}
uint choice = 0; // Bigger is most important
uint latency = 0; // Bigger is scheduled first
uint score = 0; // Bigger is better
! uint idx; // Index in worklist
for( uint i=0; i<cnt; i++ ) { // Inspect entire worklist
// Order in worklist is used to break ties.
// See caller for how this is used to delay scheduling
// of induction variable increments to after the other
--- 330,340 ----
}
uint choice = 0; // Bigger is most important
uint latency = 0; // Bigger is scheduled first
uint score = 0; // Bigger is better
! int idx = -1; // Index in worklist
for( uint i=0; i<cnt; i++ ) { // Inspect entire worklist
// Order in worklist is used to break ties.
// See caller for how this is used to delay scheduling
// of induction variable increments to after the other
*** 409,421 ****
score = n_score;
idx = i; // Also keep index in worklist
}
} // End of for all ready nodes in worklist
! Node *n = worklist[idx]; // Get the winner
! worklist.map(idx,worklist.pop()); // Compress worklist
return n;
}
//------------------------------set_next_call----------------------------------
--- 420,433 ----
score = n_score;
idx = i; // Also keep index in worklist
}
} // End of for all ready nodes in worklist
! assert(idx >= 0, "index should be set");
! Node *n = worklist[(uint)idx]; // Get the winner
! worklist.map((uint)idx, worklist.pop()); // Compress worklist
return n;
}
//------------------------------set_next_call----------------------------------
*** 584,594 ****
}
ready_cnt[n->_idx] = local; // Count em up
// A few node types require changing a required edge to a precedence edge
// before allocation.
! if( UseConcMarkSweepGC ) {
if( n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_StoreCM ) {
// Note: Required edges with an index greater than oper_input_base
// are not supported by the allocator.
// Note2: Can only depend on unmatched edge being last,
// can not depend on its absolute position.
--- 596,606 ----
}
ready_cnt[n->_idx] = local; // Count em up
// A few node types require changing a required edge to a precedence edge
// before allocation.
! if( UseConcMarkSweepGC || UseG1GC ) {
if( n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_StoreCM ) {
// Note: Required edges with an index greater than oper_input_base
// are not supported by the allocator.
// Note2: Can only depend on unmatched edge being last,
// can not depend on its absolute position.
*** 596,606 ****
n->del_req(n->req() - 1);
n->add_prec(oop_store);
assert(cfg->_bbs[oop_store->_idx]->_dom_depth <= this->_dom_depth, "oop_store must dominate card-mark");
}
}
! if( n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_MemBarAcquire ) {
Node *x = n->in(TypeFunc::Parms);
n->del_req(TypeFunc::Parms);
n->add_prec(x);
}
}
--- 608,625 ----
n->del_req(n->req() - 1);
n->add_prec(oop_store);
assert(cfg->_bbs[oop_store->_idx]->_dom_depth <= this->_dom_depth, "oop_store must dominate card-mark");
}
}
! if( n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_MemBarAcquire &&
! n->req() > TypeFunc::Parms ) {
! // MemBarAcquire could be created without Precedent edge.
! // del_req() replaces the specified edge with the last input edge
! // and then removes the last edge. If the specified edge > number of
! // edges the last edge will be moved outside of the input edges array
! // and the edge will be lost. This is why this code should be
! // executed only when Precedent (== TypeFunc::Parms) edge is present.
Node *x = n->in(TypeFunc::Parms);
n->del_req(TypeFunc::Parms);
n->add_prec(x);
}
}
*** 628,637 ****
--- 647,660 ----
if (m->is_iteratively_computed()) {
// Push induction variable increments last to allow other uses
// of the phi to be scheduled first. The select() method breaks
// ties in scheduling by worklist order.
delay.push(m);
+ } else if (m->is_Mach() && m->as_Mach()->ideal_Opcode() == Op_CreateEx) {
+ // Force the CreateEx to the top of the list so it's processed
+ // first and ends up at the start of the block.
+ worklist.insert(0, m);
} else {
worklist.push(m); // Then on to worklist!
}
}
}