7090968: Allow adlc register class to depend on runtime conditions
authorroland
Tue, 22 Nov 2011 09:45:57 +0100
changeset 11197 158eecd6b330
parent 11196 a310a659c580
child 11198 34c860ff41e3
7090968: Allow adlc register class to depend on runtime conditions Summary: allow reg_class definition as a function. Reviewed-by: kvn, never
hotspot/src/cpu/sparc/vm/sparc.ad
hotspot/src/cpu/x86/vm/x86_32.ad
hotspot/src/cpu/x86/vm/x86_64.ad
hotspot/src/share/vm/adlc/adlparse.cpp
hotspot/src/share/vm/adlc/archDesc.cpp
hotspot/src/share/vm/adlc/formsopt.cpp
hotspot/src/share/vm/adlc/formsopt.hpp
hotspot/src/share/vm/adlc/output_c.cpp
hotspot/src/share/vm/opto/matcher.hpp
--- a/hotspot/src/cpu/sparc/vm/sparc.ad	Wed Sep 14 09:22:51 2011 +0200
+++ b/hotspot/src/cpu/sparc/vm/sparc.ad	Tue Nov 22 09:45:57 2011 +0100
@@ -1019,7 +1019,7 @@
 
 
 //=============================================================================
-const RegMask& MachConstantBaseNode::_out_RegMask = PTR_REG_mask;
+const RegMask& MachConstantBaseNode::_out_RegMask = PTR_REG_mask();
 
 int Compile::ConstantTable::calculate_table_base_offset() const {
   if (UseRDPCForConstantTableBase) {
@@ -2024,7 +2024,7 @@
 }
 
 const RegMask Matcher::method_handle_invoke_SP_save_mask() {
-  return L7_REGP_mask;
+  return L7_REGP_mask();
 }
 
 %}
--- a/hotspot/src/cpu/x86/vm/x86_32.ad	Wed Sep 14 09:22:51 2011 +0200
+++ b/hotspot/src/cpu/x86/vm/x86_32.ad	Tue Nov 22 09:45:57 2011 +0100
@@ -1524,12 +1524,12 @@
 
 // Register for DIVI projection of divmodI
 RegMask Matcher::divI_proj_mask() {
-  return EAX_REG_mask;
+  return EAX_REG_mask();
 }
 
 // Register for MODI projection of divmodI
 RegMask Matcher::modI_proj_mask() {
-  return EDX_REG_mask;
+  return EDX_REG_mask();
 }
 
 // Register for DIVL projection of divmodL
@@ -1545,7 +1545,7 @@
 }
 
 const RegMask Matcher::method_handle_invoke_SP_save_mask() {
-  return EBP_REG_mask;
+  return EBP_REG_mask();
 }
 
 // Returns true if the high 32 bits of the value is known to be zero.
--- a/hotspot/src/cpu/x86/vm/x86_64.ad	Wed Sep 14 09:22:51 2011 +0200
+++ b/hotspot/src/cpu/x86/vm/x86_64.ad	Tue Nov 22 09:45:57 2011 +0100
@@ -2089,26 +2089,26 @@
 
 // Register for DIVI projection of divmodI
 RegMask Matcher::divI_proj_mask() {
-  return INT_RAX_REG_mask;
+  return INT_RAX_REG_mask();
 }
 
 // Register for MODI projection of divmodI
 RegMask Matcher::modI_proj_mask() {
-  return INT_RDX_REG_mask;
+  return INT_RDX_REG_mask();
 }
 
 // Register for DIVL projection of divmodL
 RegMask Matcher::divL_proj_mask() {
-  return LONG_RAX_REG_mask;
+  return LONG_RAX_REG_mask();
 }
 
 // Register for MODL projection of divmodL
 RegMask Matcher::modL_proj_mask() {
-  return LONG_RDX_REG_mask;
+  return LONG_RDX_REG_mask();
 }
 
 const RegMask Matcher::method_handle_invoke_SP_save_mask() {
-  return PTR_RBP_REG_mask;
+  return PTR_RBP_REG_mask();
 }
 
 static Address build_address(int b, int i, int s, int d) {
--- a/hotspot/src/share/vm/adlc/adlparse.cpp	Wed Sep 14 09:22:51 2011 +0200
+++ b/hotspot/src/share/vm/adlc/adlparse.cpp	Tue Nov 22 09:45:57 2011 +0100
@@ -982,27 +982,9 @@
       }
       if (strcmp(token,"interpreter_frame_pointer")==0) {
         interpreter_frame_pointer_parse(frame, false);
-        // Add  reg_class interpreter_frame_pointer_reg
-        if( _AD._register != NULL ) {
-          RegClass *reg_class = _AD._register->addRegClass("interpreter_frame_pointer_reg");
-          char *interpreter_frame_pointer_reg = frame->_interpreter_frame_pointer_reg;
-          if( interpreter_frame_pointer_reg != NULL ) {
-            RegDef *regDef = _AD._register->getRegDef(interpreter_frame_pointer_reg);
-            reg_class->addReg(regDef);     // add regDef to regClass
-          }
-        }
       }
       if (strcmp(token,"inline_cache_reg")==0) {
         inline_cache_parse(frame, false);
-        // Add  reg_class inline_cache_reg
-        if( _AD._register != NULL ) {
-          RegClass *reg_class = _AD._register->addRegClass("inline_cache_reg");
-          char *inline_cache_reg = frame->_inline_cache_reg;
-          if( inline_cache_reg != NULL ) {
-            RegDef *regDef = _AD._register->getRegDef(inline_cache_reg);
-            reg_class->addReg(regDef);     // add regDef to regClass
-          }
-        }
       }
       if (strcmp(token,"compiler_method_oop_reg")==0) {
         parse_err(WARN, "Using obsolete Token, compiler_method_oop_reg");
@@ -1010,15 +992,6 @@
       }
       if (strcmp(token,"interpreter_method_oop_reg")==0) {
         interpreter_method_oop_parse(frame, false);
-        // Add  reg_class interpreter_method_oop_reg
-        if( _AD._register != NULL ) {
-          RegClass *reg_class = _AD._register->addRegClass("interpreter_method_oop_reg");
-          char *method_oop_reg = frame->_interpreter_method_oop_reg;
-          if( method_oop_reg != NULL ) {
-            RegDef *regDef = _AD._register->getRegDef(method_oop_reg);
-            reg_class->addReg(regDef);     // add regDef to regClass
-          }
-        }
       }
       if (strcmp(token,"cisc_spilling_operand_name")==0) {
         cisc_spilling_operand_name_parse(frame, false);
@@ -2363,6 +2336,14 @@
       }
     }
     next_char();                  // Skip closing ')'
+  } else if (_curchar == '%') {
+    char *code = find_cpp_block("reg class");
+    if (code == NULL) {
+      parse_err(SYNERR, "missing code declaration for reg class.\n");
+      return;
+    }
+    reg_class->_user_defined = code;
+    return;
   }
 
   // Check for terminating ';'
--- a/hotspot/src/share/vm/adlc/archDesc.cpp	Wed Sep 14 09:22:51 2011 +0200
+++ b/hotspot/src/share/vm/adlc/archDesc.cpp	Tue Nov 22 09:45:57 2011 +0100
@@ -823,9 +823,9 @@
   } else {
     char       *rc_name = toUpper(reg_class_name);
     const char *mask    = "_mask";
-    int         length  = (int)strlen(rc_name) + (int)strlen(mask) + 3;
+    int         length  = (int)strlen(rc_name) + (int)strlen(mask) + 5;
     char       *regMask = new char[length];
-    sprintf(regMask,"%s%s", rc_name, mask);
+    sprintf(regMask,"%s%s()", rc_name, mask);
     return regMask;
   }
 }
--- a/hotspot/src/share/vm/adlc/formsopt.cpp	Wed Sep 14 09:22:51 2011 +0200
+++ b/hotspot/src/share/vm/adlc/formsopt.cpp	Tue Nov 22 09:45:57 2011 +0100
@@ -219,7 +219,9 @@
 
 //------------------------------RegClass---------------------------------------
 // Construct a register class into which registers will be inserted
-RegClass::RegClass(const char *classid) : _stack_or_reg(false), _classid(classid), _regDef(cmpstr,hashstr, Form::arena) {
+RegClass::RegClass(const char *classid) : _stack_or_reg(false), _classid(classid), _regDef(cmpstr,hashstr, Form::arena),
+                                          _user_defined(NULL)
+{
 }
 
 // record a register in this class
--- a/hotspot/src/share/vm/adlc/formsopt.hpp	Wed Sep 14 09:22:51 2011 +0200
+++ b/hotspot/src/share/vm/adlc/formsopt.hpp	Tue Nov 22 09:45:57 2011 +0100
@@ -161,6 +161,7 @@
   NameList    _regDefs;         // List of registers in class
   Dict        _regDef;          // Dictionary of registers in class
   bool        _stack_or_reg;    // Allowed on any stack slot
+  char*       _user_defined;
 
   // Public Methods
   RegClass(const char *classid);// Constructor
--- a/hotspot/src/share/vm/adlc/output_c.cpp	Wed Sep 14 09:22:51 2011 +0200
+++ b/hotspot/src/share/vm/adlc/output_c.cpp	Tue Nov 22 09:45:57 2011 +0100
@@ -162,11 +162,17 @@
       RegClass   *reg_class = _register->getRegClass(rc_name);
       assert( reg_class, "Using an undefined register class");
 
-      int len = RegisterForm::RegMask_Size();
-      fprintf(fp_hpp, "extern const RegMask %s%s_mask;\n", prefix, toUpper( rc_name ) );
+      if (reg_class->_user_defined == NULL) {
+        fprintf(fp_hpp, "extern const RegMask _%s%s_mask;\n", prefix, toUpper( rc_name ) );
+        fprintf(fp_hpp, "inline const RegMask &%s%s_mask() { return _%s%s_mask; }\n", prefix, toUpper( rc_name ), prefix, toUpper( rc_name ));
+      } else {
+        fprintf(fp_hpp, "inline const RegMask &%s%s_mask() { %s }\n", prefix, toUpper( rc_name ), reg_class->_user_defined);
+      }
 
       if( reg_class->_stack_or_reg ) {
-        fprintf(fp_hpp, "extern const RegMask %sSTACK_OR_%s_mask;\n", prefix, toUpper( rc_name ) );
+        assert(reg_class->_user_defined == NULL, "no user defined reg class here");
+        fprintf(fp_hpp, "extern const RegMask _%sSTACK_OR_%s_mask;\n", prefix, toUpper( rc_name ) );
+        fprintf(fp_hpp, "inline const RegMask &%sSTACK_OR_%s_mask() { return _%sSTACK_OR_%s_mask; }\n", prefix, toUpper( rc_name ), prefix, toUpper( rc_name ) );
       }
     }
   }
@@ -188,8 +194,10 @@
       RegClass   *reg_class = _register->getRegClass(rc_name);
       assert( reg_class, "Using an undefined register class");
 
+      if (reg_class->_user_defined != NULL) continue;
+
       int len = RegisterForm::RegMask_Size();
-      fprintf(fp_cpp, "const RegMask %s%s_mask(", prefix, toUpper( rc_name ) );
+      fprintf(fp_cpp, "const RegMask _%s%s_mask(", prefix, toUpper( rc_name ) );
       { int i;
         for( i = 0; i < len-1; i++ )
           fprintf(fp_cpp," 0x%x,",reg_class->regs_in_word(i,false));
@@ -198,7 +206,7 @@
 
       if( reg_class->_stack_or_reg ) {
         int i;
-        fprintf(fp_cpp, "const RegMask %sSTACK_OR_%s_mask(", prefix, toUpper( rc_name ) );
+        fprintf(fp_cpp, "const RegMask _%sSTACK_OR_%s_mask(", prefix, toUpper( rc_name ) );
         for( i = 0; i < len-1; i++ )
           fprintf(fp_cpp," 0x%x,",reg_class->regs_in_word(i,true));
         fprintf(fp_cpp," 0x%x );\n",reg_class->regs_in_word(i,true));
@@ -2690,7 +2698,7 @@
       if (strcmp(first_reg_class, "stack_slots") == 0) {
         fprintf(fp,"  return &(Compile::current()->FIRST_STACK_mask());\n");
       } else {
-        fprintf(fp,"  return &%s_mask;\n", toUpper(first_reg_class));
+        fprintf(fp,"  return &%s_mask();\n", toUpper(first_reg_class));
       }
     } else {
       // Build a switch statement to return the desired mask.
@@ -2702,7 +2710,7 @@
         if( !strcmp(reg_class, "stack_slots") ) {
           fprintf(fp, "  case %d: return &(Compile::current()->FIRST_STACK_mask());\n", index);
         } else {
-          fprintf(fp, "  case %d: return &%s_mask;\n", index, toUpper(reg_class));
+          fprintf(fp, "  case %d: return &%s_mask();\n", index, toUpper(reg_class));
         }
       }
       fprintf(fp,"  }\n");
@@ -4080,8 +4088,6 @@
   fprintf(fp_cpp,"OptoReg::Name Matcher::inline_cache_reg() {");
   fprintf(fp_cpp," return OptoReg::Name(%s_num); }\n\n",
           _frame->_inline_cache_reg);
-  fprintf(fp_cpp,"const RegMask &Matcher::inline_cache_reg_mask() {");
-  fprintf(fp_cpp," return INLINE_CACHE_REG_mask; }\n\n");
   fprintf(fp_cpp,"int Matcher::inline_cache_reg_encode() {");
   fprintf(fp_cpp," return _regEncode[inline_cache_reg()]; }\n\n");
 
@@ -4089,8 +4095,6 @@
   fprintf(fp_cpp,"OptoReg::Name Matcher::interpreter_method_oop_reg() {");
   fprintf(fp_cpp," return OptoReg::Name(%s_num); }\n\n",
           _frame->_interpreter_method_oop_reg);
-  fprintf(fp_cpp,"const RegMask &Matcher::interpreter_method_oop_reg_mask() {");
-  fprintf(fp_cpp," return INTERPRETER_METHOD_OOP_REG_mask; }\n\n");
   fprintf(fp_cpp,"int Matcher::interpreter_method_oop_reg_encode() {");
   fprintf(fp_cpp," return _regEncode[interpreter_method_oop_reg()]; }\n\n");
 
@@ -4101,11 +4105,6 @@
   else
     fprintf(fp_cpp," return OptoReg::Name(%s_num); }\n\n",
             _frame->_interpreter_frame_pointer_reg);
-  fprintf(fp_cpp,"const RegMask &Matcher::interpreter_frame_pointer_reg_mask() {");
-  if (_frame->_interpreter_frame_pointer_reg == NULL)
-    fprintf(fp_cpp," static RegMask dummy; return dummy; }\n\n");
-  else
-    fprintf(fp_cpp," return INTERPRETER_FRAME_POINTER_REG_mask; }\n\n");
 
   // Frame Pointer definition
   /* CNC - I can not contemplate having a different frame pointer between
--- a/hotspot/src/share/vm/opto/matcher.hpp	Wed Sep 14 09:22:51 2011 +0200
+++ b/hotspot/src/share/vm/opto/matcher.hpp	Tue Nov 22 09:45:57 2011 +0100
@@ -294,7 +294,6 @@
   RegMask                     _return_value_mask;
   // Inline Cache Register
   static OptoReg::Name  inline_cache_reg();
-  static const RegMask &inline_cache_reg_mask();
   static int            inline_cache_reg_encode();
 
   // Register for DIVI projection of divmodI
@@ -324,7 +323,6 @@
   // and then expanded into the inline_cache_reg and a method_oop register
 
   static OptoReg::Name  interpreter_method_oop_reg();
-  static const RegMask &interpreter_method_oop_reg_mask();
   static int            interpreter_method_oop_reg_encode();
 
   static OptoReg::Name  compiler_method_oop_reg();
@@ -333,7 +331,6 @@
 
   // Interpreter's Frame Pointer Register
   static OptoReg::Name  interpreter_frame_pointer_reg();
-  static const RegMask &interpreter_frame_pointer_reg_mask();
 
   // Java-Native calling convention
   // (what you use when intercalling between Java and C++ code)