6953576: bottom_type for matched AddPNodes doesn't always agree with ideal
Reviewed-by: kvn
--- a/hotspot/src/share/vm/adlc/formssel.cpp Tue May 18 13:45:03 2010 -0700
+++ b/hotspot/src/share/vm/adlc/formssel.cpp Tue May 18 23:58:32 2010 -0700
@@ -735,7 +735,7 @@
// This instruction captures the machine-independent bottom_type
// Expected use is for pointer vs oop determination for LoadP
-bool InstructForm::captures_bottom_type() const {
+bool InstructForm::captures_bottom_type(FormDict &globals) const {
if( _matrule && _matrule->_rChild &&
(!strcmp(_matrule->_rChild->_opType,"CastPP") || // new result type
!strcmp(_matrule->_rChild->_opType,"CastX2P") || // new result type
@@ -748,6 +748,8 @@
else if ( is_ideal_load() == Form::idealP ) return true;
else if ( is_ideal_store() != Form::none ) return true;
+ if (needs_base_oop_edge(globals)) return true;
+
return false;
}
@@ -1061,7 +1063,7 @@
// Base class for this instruction, MachNode except for calls
-const char *InstructForm::mach_base_class() const {
+const char *InstructForm::mach_base_class(FormDict &globals) const {
if( is_ideal_call() == Form::JAVA_STATIC ) {
return "MachCallStaticJavaNode";
}
@@ -1092,7 +1094,7 @@
else if (is_ideal_nop()) {
return "MachNopNode";
}
- else if (captures_bottom_type()) {
+ else if (captures_bottom_type(globals)) {
return "MachTypeNode";
} else {
return "MachNode";
--- a/hotspot/src/share/vm/adlc/formssel.hpp Tue May 18 13:45:03 2010 -0700
+++ b/hotspot/src/share/vm/adlc/formssel.hpp Tue May 18 23:58:32 2010 -0700
@@ -188,7 +188,7 @@
// This instruction captures the machine-independent bottom_type
// Expected use is for pointer vs oop determination for LoadP
- virtual bool captures_bottom_type() const;
+ virtual bool captures_bottom_type(FormDict& globals) const;
virtual const char *cost(); // Access ins_cost attribute
virtual uint num_opnds(); // Count of num_opnds for MachNode class
@@ -229,7 +229,7 @@
const char *reduce_left(FormDict &globals) const;
// Base class for this instruction, MachNode except for calls
- virtual const char *mach_base_class() const;
+ virtual const char *mach_base_class(FormDict &globals) const;
// Check if this instruction can cisc-spill to 'alternate'
bool cisc_spills_to(ArchDesc &AD, InstructForm *alternate);
@@ -252,7 +252,7 @@
bool has_short_branch_form() { return _short_branch_form != NULL; }
// Output short branch prototypes and method bodies
void declare_short_branch_methods(FILE *fp_cpp);
- bool define_short_branch_methods(FILE *fp_cpp);
+ bool define_short_branch_methods(ArchDesc &AD, FILE *fp_cpp);
uint alignment() { return _alignment; }
void set_alignment(uint val) { _alignment = val; }
--- a/hotspot/src/share/vm/adlc/output_c.cpp Tue May 18 13:45:03 2010 -0700
+++ b/hotspot/src/share/vm/adlc/output_c.cpp Tue May 18 23:58:32 2010 -0700
@@ -1382,7 +1382,7 @@
inst_num, unmatched_edge);
}
// If new instruction captures bottom type
- if( root_form->captures_bottom_type() ) {
+ if( root_form->captures_bottom_type(globals) ) {
// Get bottom type from instruction whose result we are replacing
fprintf(fp, " root->_bottom_type = inst%d->bottom_type();\n", inst_num);
}
@@ -2963,7 +2963,7 @@
used |= instr->define_cisc_version(*this, fp);
// Output code to convert to the short branch version, if applicable
- used |= instr->define_short_branch_methods(fp);
+ used |= instr->define_short_branch_methods(*this, fp);
}
// Construct the method called by cisc_version() to copy inputs and operands.
@@ -3708,7 +3708,7 @@
}
// Fill in the bottom_type where requested
- if ( inst->captures_bottom_type() ) {
+ if ( inst->captures_bottom_type(_globalNames) ) {
fprintf(fp_cpp, "%s node->_bottom_type = _leaf->bottom_type();\n", indent);
}
if( inst->is_ideal_if() ) {
@@ -3762,7 +3762,7 @@
// Create the MachNode object
fprintf(fp_cpp, " %sNode *node = new (C) %sNode();\n", name, name);
// Fill in the bottom_type where requested
- if ( this->captures_bottom_type() ) {
+ if ( this->captures_bottom_type(AD.globalNames()) ) {
fprintf(fp_cpp, " node->_bottom_type = bottom_type();\n");
}
@@ -3798,7 +3798,7 @@
//---------------------------define_short_branch_methods-----------------------
// Build definitions for short branch methods
-bool InstructForm::define_short_branch_methods(FILE *fp_cpp) {
+bool InstructForm::define_short_branch_methods(ArchDesc &AD, FILE *fp_cpp) {
if (has_short_branch_form()) {
InstructForm *short_branch = short_branch_form();
const char *name = short_branch->_ident;
@@ -3813,7 +3813,7 @@
fprintf(fp_cpp, " node->_fcnt = _fcnt;\n");
}
// Fill in the bottom_type where requested
- if ( this->captures_bottom_type() ) {
+ if ( this->captures_bottom_type(AD.globalNames()) ) {
fprintf(fp_cpp, " node->_bottom_type = bottom_type();\n");
}
--- a/hotspot/src/share/vm/adlc/output_h.cpp Tue May 18 13:45:03 2010 -0700
+++ b/hotspot/src/share/vm/adlc/output_h.cpp Tue May 18 23:58:32 2010 -0700
@@ -1493,7 +1493,7 @@
// Build class definition for this instruction
fprintf(fp,"\n");
fprintf(fp,"class %sNode : public %s { \n",
- instr->_ident, instr->mach_base_class() );
+ instr->_ident, instr->mach_base_class(_globalNames) );
fprintf(fp,"private:\n");
fprintf(fp," MachOper *_opnd_array[%d];\n", instr->num_opnds() );
if ( instr->is_ideal_jump() ) {
@@ -1566,7 +1566,7 @@
// Use MachNode::ideal_Opcode() for nodes based on MachNode class
// if the ideal_Opcode == Op_Node.
if ( strcmp("Node", instr->ideal_Opcode(_globalNames)) != 0 ||
- strcmp("MachNode", instr->mach_base_class()) != 0 ) {
+ strcmp("MachNode", instr->mach_base_class(_globalNames)) != 0 ) {
fprintf(fp," virtual int ideal_Opcode() const { return Op_%s; }\n",
instr->ideal_Opcode(_globalNames) );
}
@@ -1631,7 +1631,7 @@
// Use MachNode::oper_input_base() for nodes based on MachNode class
// if the base == 1.
if ( instr->oper_input_base(_globalNames) != 1 ||
- strcmp("MachNode", instr->mach_base_class()) != 0 ) {
+ strcmp("MachNode", instr->mach_base_class(_globalNames)) != 0 ) {
fprintf(fp," virtual uint oper_input_base() const { return %d; }\n",
instr->oper_input_base(_globalNames));
}
@@ -1906,11 +1906,6 @@
fprintf(fp," const Type *bottom_type() const { const Type *t = in(oper_input_base()+%d)->bottom_type(); return (req() <= oper_input_base()+%d) ? t : t->meet(in(oper_input_base()+%d)->bottom_type()); } // CMoveN\n",
offset, offset+1, offset+1);
}
- else if( instr->needs_base_oop_edge(_globalNames) ) {
- // Special hack for ideal AddP. Bottom type is an oop IFF it has a
- // legal base-pointer input. Otherwise it is NOT an oop.
- fprintf(fp," const Type *bottom_type() const { return AddPNode::mach_bottom_type(this); } // AddP\n");
- }
else if (instr->is_tls_instruction()) {
// Special hack for tlsLoadP
fprintf(fp," const Type *bottom_type() const { return TypeRawPtr::BOTTOM; } // tlsLoadP\n");
--- a/hotspot/src/share/vm/opto/addnode.cpp Tue May 18 13:45:03 2010 -0700
+++ b/hotspot/src/share/vm/opto/addnode.cpp Tue May 18 23:58:32 2010 -0700
@@ -714,71 +714,6 @@
return idx > Base;
}
-//---------------------------mach_bottom_type----------------------------------
-// Utility function for use by ADLC. Implements bottom_type for matched AddP.
-const Type *AddPNode::mach_bottom_type( const MachNode* n) {
- Node* base = n->in(Base);
- const Type *t = base->bottom_type();
- if ( t == Type::TOP ) {
- // an untyped pointer
- return TypeRawPtr::BOTTOM;
- }
- const TypePtr* tp = t->isa_oopptr();
- if ( tp == NULL ) return t;
- if ( tp->_offset == TypePtr::OffsetBot ) return tp;
-
- // We must carefully add up the various offsets...
- intptr_t offset = 0;
- const TypePtr* tptr = NULL;
-
- uint numopnds = n->num_opnds();
- uint index = n->oper_input_base();
- for ( uint i = 1; i < numopnds; i++ ) {
- MachOper *opnd = n->_opnds[i];
- // Check for any interesting operand info.
- // In particular, check for both memory and non-memory operands.
- // %%%%% Clean this up: use xadd_offset
- intptr_t con = opnd->constant();
- if ( con == TypePtr::OffsetBot ) goto bottom_out;
- offset += con;
- con = opnd->constant_disp();
- if ( con == TypePtr::OffsetBot ) goto bottom_out;
- offset += con;
- if( opnd->scale() != 0 ) goto bottom_out;
-
- // Check each operand input edge. Find the 1 allowed pointer
- // edge. Other edges must be index edges; track exact constant
- // inputs and otherwise assume the worst.
- for ( uint j = opnd->num_edges(); j > 0; j-- ) {
- Node* edge = n->in(index++);
- const Type* et = edge->bottom_type();
- const TypeX* eti = et->isa_intptr_t();
- if ( eti == NULL ) {
- // there must be one pointer among the operands
- guarantee(tptr == NULL, "must be only one pointer operand");
- if (UseCompressedOops && Universe::narrow_oop_shift() == 0) {
- // 32-bits narrow oop can be the base of address expressions
- tptr = et->make_ptr()->isa_oopptr();
- } else {
- // only regular oops are expected here
- tptr = et->isa_oopptr();
- }
- guarantee(tptr != NULL, "non-int operand must be pointer");
- if (tptr->higher_equal(tp->add_offset(tptr->offset())))
- tp = tptr; // Set more precise type for bailout
- continue;
- }
- if ( eti->_hi != eti->_lo ) goto bottom_out;
- offset += eti->_lo;
- }
- }
- guarantee(tptr != NULL, "must be exactly one pointer operand");
- return tptr->add_offset(offset);
-
- bottom_out:
- return tp->add_offset(TypePtr::OffsetBot);
-}
-
//=============================================================================
//------------------------------Identity---------------------------------------
Node *OrINode::Identity( PhaseTransform *phase ) {
--- a/hotspot/src/share/vm/opto/addnode.hpp Tue May 18 13:45:03 2010 -0700
+++ b/hotspot/src/share/vm/opto/addnode.hpp Tue May 18 23:58:32 2010 -0700
@@ -151,7 +151,6 @@
// Do not match base-ptr edge
virtual uint match_edge(uint idx) const;
- static const Type *mach_bottom_type(const MachNode* n); // used by ad_<arch>.hpp
};
//------------------------------OrINode----------------------------------------