src/share/vm/opto/matcher.cpp
Print this page
rev 3688 : 7054512: Compress class pointers after perm gen removal
Summary: support of compress class pointers in the compilers.
Reviewed-by:
*** 1056,1066 ****
// Monitor boxes are also represented directly.
for (i = cnt - 1; i >= debug_cnt; --i) { // For all debug inputs do
Node *m = n->in(i); // Get input
int op = m->Opcode();
assert((op == Op_BoxLock) == jvms->is_monitor_use(i), "boxes only at monitor sites");
! if( op == Op_ConI || op == Op_ConP || op == Op_ConN ||
op == Op_ConF || op == Op_ConD || op == Op_ConL
// || op == Op_BoxLock // %%%% enable this and remove (+++) in chaitin.cpp
) {
m = m->clone();
#ifdef ASSERT
--- 1056,1066 ----
// Monitor boxes are also represented directly.
for (i = cnt - 1; i >= debug_cnt; --i) { // For all debug inputs do
Node *m = n->in(i); // Get input
int op = m->Opcode();
assert((op == Op_BoxLock) == jvms->is_monitor_use(i), "boxes only at monitor sites");
! if( op == Op_ConI || op == Op_ConP || op == Op_ConN || op == Op_ConNKlass ||
op == Op_ConF || op == Op_ConD || op == Op_ConL
// || op == Op_BoxLock // %%%% enable this and remove (+++) in chaitin.cpp
) {
m = m->clone();
#ifdef ASSERT
*** 1448,1458 ****
break; // mem_control? If so, we can use it
}
if (j == max_scan) // No post-domination before scan end?
return true; // Then break the match tree up
}
! if (m->is_DecodeN() && Matcher::narrow_oop_use_complex_address()) {
// These are commonly used in address expressions and can
// efficiently fold into them on X64 in some cases.
return false;
}
}
--- 1448,1459 ----
break; // mem_control? If so, we can use it
}
if (j == max_scan) // No post-domination before scan end?
return true; // Then break the match tree up
}
! if ((m->is_DecodeN() && Matcher::narrow_oop_use_complex_address()) ||
! (m->is_DecodeNKlass() && Matcher::narrow_klass_use_complex_address())) {
// These are commonly used in address expressions and can
// efficiently fold into them on X64 in some cases.
return false;
}
}
*** 1572,1589 ****
// Con nodes reduced using the same rule can share their MachNode
// which reduces the number of copies of a constant in the final
// program. The register allocator is free to split uses later to
// split live ranges.
MachNode* Matcher::find_shared_node(Node* leaf, uint rule) {
! if (!leaf->is_Con() && !leaf->is_DecodeN()) return NULL;
// See if this Con has already been reduced using this rule.
if (_shared_nodes.Size() <= leaf->_idx) return NULL;
MachNode* last = (MachNode*)_shared_nodes.at(leaf->_idx);
if (last != NULL && rule == last->rule()) {
// Don't expect control change for DecodeN
! if (leaf->is_DecodeN())
return last;
// Get the new space root.
Node* xroot = new_node(C->root());
if (xroot == NULL) {
// This shouldn't happen give the order of matching.
--- 1573,1590 ----
// Con nodes reduced using the same rule can share their MachNode
// which reduces the number of copies of a constant in the final
// program. The register allocator is free to split uses later to
// split live ranges.
MachNode* Matcher::find_shared_node(Node* leaf, uint rule) {
! if (!leaf->is_Con() && !leaf->is_DecodeNarrowPtr()) return NULL;
// See if this Con has already been reduced using this rule.
if (_shared_nodes.Size() <= leaf->_idx) return NULL;
MachNode* last = (MachNode*)_shared_nodes.at(leaf->_idx);
if (last != NULL && rule == last->rule()) {
// Don't expect control change for DecodeN
! if (leaf->is_DecodeNarrowPtr())
return last;
// Get the new space root.
Node* xroot = new_node(C->root());
if (xroot == NULL) {
// This shouldn't happen give the order of matching.
*** 1669,1684 ****
}
const Type* mach_at = mach->adr_type();
// DecodeN node consumed by an address may have different type
// then its input. Don't compare types for such case.
if (m->adr_type() != mach_at &&
! (m->in(MemNode::Address)->is_DecodeN() ||
m->in(MemNode::Address)->is_AddP() &&
! m->in(MemNode::Address)->in(AddPNode::Address)->is_DecodeN() ||
m->in(MemNode::Address)->is_AddP() &&
m->in(MemNode::Address)->in(AddPNode::Address)->is_AddP() &&
! m->in(MemNode::Address)->in(AddPNode::Address)->in(AddPNode::Address)->is_DecodeN())) {
mach_at = m->adr_type();
}
if (m->adr_type() != mach_at) {
m->dump();
tty->print_cr("mach:");
--- 1670,1685 ----
}
const Type* mach_at = mach->adr_type();
// DecodeN node consumed by an address may have different type
// then its input. Don't compare types for such case.
if (m->adr_type() != mach_at &&
! (m->in(MemNode::Address)->is_DecodeNarrowPtr() ||
m->in(MemNode::Address)->is_AddP() &&
! m->in(MemNode::Address)->in(AddPNode::Address)->is_DecodeNarrowPtr() ||
m->in(MemNode::Address)->is_AddP() &&
m->in(MemNode::Address)->in(AddPNode::Address)->is_AddP() &&
! m->in(MemNode::Address)->in(AddPNode::Address)->in(AddPNode::Address)->is_DecodeNarrowPtr())) {
mach_at = m->adr_type();
}
if (m->adr_type() != mach_at) {
m->dump();
tty->print_cr("mach:");
*** 1719,1729 ****
if (_allocation_started) {
guarantee(ex == mach, "no expand rules during spill generation");
guarantee(_proj_list.size() == num_proj, "no allocation during spill generation");
}
! if (leaf->is_Con() || leaf->is_DecodeN()) {
// Record the con for sharing
_shared_nodes.map(leaf->_idx, ex);
}
return ex;
--- 1720,1730 ----
if (_allocation_started) {
guarantee(ex == mach, "no expand rules during spill generation");
guarantee(_proj_list.size() == num_proj, "no allocation during spill generation");
}
! if (leaf->is_Con() || leaf->is_DecodeNarrowPtr()) {
// Record the con for sharing
_shared_nodes.map(leaf->_idx, ex);
}
return ex;
*** 2036,2046 ****
if( _must_clone[mop] ) {
mstack.push(m, Visit);
continue; // for(int i = ...)
}
! if( mop == Op_AddP && m->in(AddPNode::Base)->Opcode() == Op_DecodeN ) {
// Bases used in addresses must be shared but since
// they are shared through a DecodeN they may appear
// to have a single use so force sharing here.
set_shared(m->in(AddPNode::Base)->in(1));
}
--- 2037,2047 ----
if( _must_clone[mop] ) {
mstack.push(m, Visit);
continue; // for(int i = ...)
}
! if( mop == Op_AddP && m->in(AddPNode::Base)->is_DecodeNarrowPtr()) {
// Bases used in addresses must be shared but since
// they are shared through a DecodeN they may appear
// to have a single use so force sharing here.
set_shared(m->in(AddPNode::Base)->in(1));
}
*** 2275,2285 ****
bool is_decoden = ((intptr_t)val) & 1;
val = (Node*)(((intptr_t)val) & ~1);
if (has_new_node(val)) {
Node* new_val = new_node(val);
if (is_decoden) {
! assert(val->is_DecodeN() && val->in(0) == NULL, "sanity");
// Note: new_val may have a control edge if
// the original ideal node DecodeN was matched before
// it was unpinned in Matcher::collect_null_checks().
// Unpin the mach node and mark it.
new_val->set_req(0, NULL);
--- 2276,2286 ----
bool is_decoden = ((intptr_t)val) & 1;
val = (Node*)(((intptr_t)val) & ~1);
if (has_new_node(val)) {
Node* new_val = new_node(val);
if (is_decoden) {
! assert(val->is_DecodeNarrowPtr() && val->in(0) == NULL, "sanity");
// Note: new_val may have a control edge if
// the original ideal node DecodeN was matched before
// it was unpinned in Matcher::collect_null_checks().
// Unpin the mach node and mark it.
new_val->set_req(0, NULL);