6953576: bottom_type for matched AddPNodes doesn't always agree with ideal
authornever
Tue, 18 May 2010 23:58:32 -0700
changeset 5536 f23c4e2e0d5e
parent 5535 a747f18b3d7e
child 5538 535ef83faf5d
6953576: bottom_type for matched AddPNodes doesn't always agree with ideal Reviewed-by: kvn
hotspot/src/share/vm/adlc/formssel.cpp
hotspot/src/share/vm/adlc/formssel.hpp
hotspot/src/share/vm/adlc/output_c.cpp
hotspot/src/share/vm/adlc/output_h.cpp
hotspot/src/share/vm/opto/addnode.cpp
hotspot/src/share/vm/opto/addnode.hpp
--- 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----------------------------------------