mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-20 19:14:38 +02:00
6953576: bottom_type for matched AddPNodes doesn't always agree with ideal
Reviewed-by: kvn
This commit is contained in:
parent
b03699b985
commit
00d1e12daf
6 changed files with 17 additions and 86 deletions
|
@ -735,7 +735,7 @@ int InstructForm::memory_operand(FormDict &globals) const {
|
||||||
|
|
||||||
// This instruction captures the machine-independent bottom_type
|
// This instruction captures the machine-independent bottom_type
|
||||||
// Expected use is for pointer vs oop determination for LoadP
|
// 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 &&
|
if( _matrule && _matrule->_rChild &&
|
||||||
(!strcmp(_matrule->_rChild->_opType,"CastPP") || // new result type
|
(!strcmp(_matrule->_rChild->_opType,"CastPP") || // new result type
|
||||||
!strcmp(_matrule->_rChild->_opType,"CastX2P") || // new result type
|
!strcmp(_matrule->_rChild->_opType,"CastX2P") || // new result type
|
||||||
|
@ -748,6 +748,8 @@ bool InstructForm::captures_bottom_type() const {
|
||||||
else if ( is_ideal_load() == Form::idealP ) return true;
|
else if ( is_ideal_load() == Form::idealP ) return true;
|
||||||
else if ( is_ideal_store() != Form::none ) return true;
|
else if ( is_ideal_store() != Form::none ) return true;
|
||||||
|
|
||||||
|
if (needs_base_oop_edge(globals)) return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1061,7 +1063,7 @@ const char *InstructForm::reduce_left(FormDict &globals) const {
|
||||||
|
|
||||||
|
|
||||||
// Base class for this instruction, MachNode except for calls
|
// 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 ) {
|
if( is_ideal_call() == Form::JAVA_STATIC ) {
|
||||||
return "MachCallStaticJavaNode";
|
return "MachCallStaticJavaNode";
|
||||||
}
|
}
|
||||||
|
@ -1092,7 +1094,7 @@ const char *InstructForm::mach_base_class() const {
|
||||||
else if (is_ideal_nop()) {
|
else if (is_ideal_nop()) {
|
||||||
return "MachNopNode";
|
return "MachNopNode";
|
||||||
}
|
}
|
||||||
else if (captures_bottom_type()) {
|
else if (captures_bottom_type(globals)) {
|
||||||
return "MachTypeNode";
|
return "MachTypeNode";
|
||||||
} else {
|
} else {
|
||||||
return "MachNode";
|
return "MachNode";
|
||||||
|
|
|
@ -188,7 +188,7 @@ public:
|
||||||
|
|
||||||
// This instruction captures the machine-independent bottom_type
|
// This instruction captures the machine-independent bottom_type
|
||||||
// Expected use is for pointer vs oop determination for LoadP
|
// 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 const char *cost(); // Access ins_cost attribute
|
||||||
virtual uint num_opnds(); // Count of num_opnds for MachNode class
|
virtual uint num_opnds(); // Count of num_opnds for MachNode class
|
||||||
|
@ -229,7 +229,7 @@ public:
|
||||||
const char *reduce_left(FormDict &globals) const;
|
const char *reduce_left(FormDict &globals) const;
|
||||||
|
|
||||||
// Base class for this instruction, MachNode except for calls
|
// 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'
|
// Check if this instruction can cisc-spill to 'alternate'
|
||||||
bool cisc_spills_to(ArchDesc &AD, InstructForm *alternate);
|
bool cisc_spills_to(ArchDesc &AD, InstructForm *alternate);
|
||||||
|
@ -252,7 +252,7 @@ public:
|
||||||
bool has_short_branch_form() { return _short_branch_form != NULL; }
|
bool has_short_branch_form() { return _short_branch_form != NULL; }
|
||||||
// Output short branch prototypes and method bodies
|
// Output short branch prototypes and method bodies
|
||||||
void declare_short_branch_methods(FILE *fp_cpp);
|
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; }
|
uint alignment() { return _alignment; }
|
||||||
void set_alignment(uint val) { _alignment = val; }
|
void set_alignment(uint val) { _alignment = val; }
|
||||||
|
|
|
@ -1382,7 +1382,7 @@ static void generate_peepreplace( FILE *fp, FormDict &globals, PeepMatch *pmatch
|
||||||
inst_num, unmatched_edge);
|
inst_num, unmatched_edge);
|
||||||
}
|
}
|
||||||
// If new instruction captures bottom type
|
// 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
|
// Get bottom type from instruction whose result we are replacing
|
||||||
fprintf(fp, " root->_bottom_type = inst%d->bottom_type();\n", inst_num);
|
fprintf(fp, " root->_bottom_type = inst%d->bottom_type();\n", inst_num);
|
||||||
}
|
}
|
||||||
|
@ -2963,7 +2963,7 @@ void ArchDesc::defineClasses(FILE *fp) {
|
||||||
used |= instr->define_cisc_version(*this, fp);
|
used |= instr->define_cisc_version(*this, fp);
|
||||||
|
|
||||||
// Output code to convert to the short branch version, if applicable
|
// 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.
|
// Construct the method called by cisc_version() to copy inputs and operands.
|
||||||
|
@ -3708,7 +3708,7 @@ void ArchDesc::buildMachNode(FILE *fp_cpp, InstructForm *inst, const char *inden
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill in the bottom_type where requested
|
// 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);
|
fprintf(fp_cpp, "%s node->_bottom_type = _leaf->bottom_type();\n", indent);
|
||||||
}
|
}
|
||||||
if( inst->is_ideal_if() ) {
|
if( inst->is_ideal_if() ) {
|
||||||
|
@ -3762,7 +3762,7 @@ bool InstructForm::define_cisc_version(ArchDesc &AD, FILE *fp_cpp) {
|
||||||
// Create the MachNode object
|
// Create the MachNode object
|
||||||
fprintf(fp_cpp, " %sNode *node = new (C) %sNode();\n", name, name);
|
fprintf(fp_cpp, " %sNode *node = new (C) %sNode();\n", name, name);
|
||||||
// Fill in the bottom_type where requested
|
// 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");
|
fprintf(fp_cpp, " node->_bottom_type = bottom_type();\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3798,7 +3798,7 @@ void InstructForm::declare_short_branch_methods(FILE *fp_hpp) {
|
||||||
|
|
||||||
//---------------------------define_short_branch_methods-----------------------
|
//---------------------------define_short_branch_methods-----------------------
|
||||||
// Build definitions for 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()) {
|
if (has_short_branch_form()) {
|
||||||
InstructForm *short_branch = short_branch_form();
|
InstructForm *short_branch = short_branch_form();
|
||||||
const char *name = short_branch->_ident;
|
const char *name = short_branch->_ident;
|
||||||
|
@ -3813,7 +3813,7 @@ bool InstructForm::define_short_branch_methods(FILE *fp_cpp) {
|
||||||
fprintf(fp_cpp, " node->_fcnt = _fcnt;\n");
|
fprintf(fp_cpp, " node->_fcnt = _fcnt;\n");
|
||||||
}
|
}
|
||||||
// Fill in the bottom_type where requested
|
// 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");
|
fprintf(fp_cpp, " node->_bottom_type = bottom_type();\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1493,7 +1493,7 @@ void ArchDesc::declareClasses(FILE *fp) {
|
||||||
// Build class definition for this instruction
|
// Build class definition for this instruction
|
||||||
fprintf(fp,"\n");
|
fprintf(fp,"\n");
|
||||||
fprintf(fp,"class %sNode : public %s { \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,"private:\n");
|
||||||
fprintf(fp," MachOper *_opnd_array[%d];\n", instr->num_opnds() );
|
fprintf(fp," MachOper *_opnd_array[%d];\n", instr->num_opnds() );
|
||||||
if ( instr->is_ideal_jump() ) {
|
if ( instr->is_ideal_jump() ) {
|
||||||
|
@ -1566,7 +1566,7 @@ void ArchDesc::declareClasses(FILE *fp) {
|
||||||
// Use MachNode::ideal_Opcode() for nodes based on MachNode class
|
// Use MachNode::ideal_Opcode() for nodes based on MachNode class
|
||||||
// if the ideal_Opcode == Op_Node.
|
// if the ideal_Opcode == Op_Node.
|
||||||
if ( strcmp("Node", instr->ideal_Opcode(_globalNames)) != 0 ||
|
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",
|
fprintf(fp," virtual int ideal_Opcode() const { return Op_%s; }\n",
|
||||||
instr->ideal_Opcode(_globalNames) );
|
instr->ideal_Opcode(_globalNames) );
|
||||||
}
|
}
|
||||||
|
@ -1631,7 +1631,7 @@ void ArchDesc::declareClasses(FILE *fp) {
|
||||||
// Use MachNode::oper_input_base() for nodes based on MachNode class
|
// Use MachNode::oper_input_base() for nodes based on MachNode class
|
||||||
// if the base == 1.
|
// if the base == 1.
|
||||||
if ( instr->oper_input_base(_globalNames) != 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",
|
fprintf(fp," virtual uint oper_input_base() const { return %d; }\n",
|
||||||
instr->oper_input_base(_globalNames));
|
instr->oper_input_base(_globalNames));
|
||||||
}
|
}
|
||||||
|
@ -1906,11 +1906,6 @@ void ArchDesc::declareClasses(FILE *fp) {
|
||||||
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",
|
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);
|
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()) {
|
else if (instr->is_tls_instruction()) {
|
||||||
// Special hack for tlsLoadP
|
// Special hack for tlsLoadP
|
||||||
fprintf(fp," const Type *bottom_type() const { return TypeRawPtr::BOTTOM; } // tlsLoadP\n");
|
fprintf(fp," const Type *bottom_type() const { return TypeRawPtr::BOTTOM; } // tlsLoadP\n");
|
||||||
|
|
|
@ -714,71 +714,6 @@ uint AddPNode::match_edge(uint idx) const {
|
||||||
return idx > Base;
|
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---------------------------------------
|
//------------------------------Identity---------------------------------------
|
||||||
Node *OrINode::Identity( PhaseTransform *phase ) {
|
Node *OrINode::Identity( PhaseTransform *phase ) {
|
||||||
|
|
|
@ -151,7 +151,6 @@ public:
|
||||||
|
|
||||||
// Do not match base-ptr edge
|
// Do not match base-ptr edge
|
||||||
virtual uint match_edge(uint idx) const;
|
virtual uint match_edge(uint idx) const;
|
||||||
static const Type *mach_bottom_type(const MachNode* n); // used by ad_<arch>.hpp
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------OrINode----------------------------------------
|
//------------------------------OrINode----------------------------------------
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue