提交 2e2d9814 编写于 作者: N never

6953576: bottom_type for matched AddPNodes doesn't always agree with ideal

Reviewed-by: kvn
上级 eb70938f
......@@ -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----------------------------------------
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册