6953576: bottom_type for matched AddPNodes doesn't always agree with ideal
Reviewed-by: kvn
This commit is contained in:
parent
b03699b985
commit
00d1e12daf
@ -735,7 +735,7 @@ int InstructForm::memory_operand(FormDict &globals) const {
|
||||
|
||||
// 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 @@ bool InstructForm::captures_bottom_type() const {
|
||||
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 @@ const char *InstructForm::reduce_left(FormDict &globals) const {
|
||||
|
||||
|
||||
// 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 @@ const char *InstructForm::mach_base_class() const {
|
||||
else if (is_ideal_nop()) {
|
||||
return "MachNopNode";
|
||||
}
|
||||
else if (captures_bottom_type()) {
|
||||
else if (captures_bottom_type(globals)) {
|
||||
return "MachTypeNode";
|
||||
} else {
|
||||
return "MachNode";
|
||||
|
@ -188,7 +188,7 @@ public:
|
||||
|
||||
// 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 @@ public:
|
||||
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 @@ public:
|
||||
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; }
|
||||
|
@ -1382,7 +1382,7 @@ static void generate_peepreplace( FILE *fp, FormDict &globals, PeepMatch *pmatch
|
||||
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 @@ void ArchDesc::defineClasses(FILE *fp) {
|
||||
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 @@ void ArchDesc::buildMachNode(FILE *fp_cpp, InstructForm *inst, const char *inden
|
||||
}
|
||||
|
||||
// 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 @@ bool InstructForm::define_cisc_version(ArchDesc &AD, FILE *fp_cpp) {
|
||||
// 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 @@ void InstructForm::declare_short_branch_methods(FILE *fp_hpp) {
|
||||
|
||||
//---------------------------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 @@ bool InstructForm::define_short_branch_methods(FILE *fp_cpp) {
|
||||
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");
|
||||
}
|
||||
|
||||
|
@ -1493,7 +1493,7 @@ void ArchDesc::declareClasses(FILE *fp) {
|
||||
// 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 @@ void ArchDesc::declareClasses(FILE *fp) {
|
||||
// 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 @@ void ArchDesc::declareClasses(FILE *fp) {
|
||||
// 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 @@ 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",
|
||||
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");
|
||||
|
@ -714,71 +714,6 @@ uint AddPNode::match_edge(uint idx) const {
|
||||
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 ) {
|
||||
|
@ -151,7 +151,6 @@ public:
|
||||
|
||||
// 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----------------------------------------
|
||||
|
Loading…
x
Reference in New Issue
Block a user