src/share/vm/adlc/formsopt.hpp

Wed, 31 Jan 2018 19:24:57 -0500

author
dbuck
date
Wed, 31 Jan 2018 19:24:57 -0500
changeset 9289
427b2fb1944f
parent 7853
a1642365d69f
child 7994
04ff2f6cd0eb
permissions
-rw-r--r--

8189170: Add option to disable stack overflow checking in primordial thread for use with JNI_CreateJavaJVM
Reviewed-by: dcubed

     1 /*
     2  * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    22  *
    23  */
    25 #ifndef SHARE_VM_ADLC_FORMSOPT_HPP
    26 #define SHARE_VM_ADLC_FORMSOPT_HPP
    28 // FORMSOPT.HPP - ADL Parser Target Specific Optimization Forms Classes
    30 // Class List
    31 class Form;
    32 class InstructForm;
    33 class OperandForm;
    34 class OpClassForm;
    35 class AttributeForm;
    36 class RegisterForm;
    37 class PipelineForm;
    38 class SourceForm;
    39 class EncodeForm;
    40 class Component;
    41 class Constraint;
    42 class Predicate;
    43 class MatchRule;
    44 class Attribute;
    45 class Effect;
    46 class ExpandRule;
    47 class RewriteRule;
    48 class ConstructRule;
    49 class FormatRule;
    50 class Peephole;
    51 class PeepMatch;
    52 class PeepConstraint;
    53 class EncClass;
    54 class Interface;
    55 class RegInterface;
    56 class ConstInterface;
    57 class MemInterface;
    58 class CondInterface;
    59 class Opcode;
    60 class InsEncode;
    61 class RegDef;
    62 class RegClass;
    63 class CodeSnippetRegClass;
    64 class ConditionalRegClass;
    65 class AllocClass;
    66 class ResourceForm;
    67 class PipeClassForm;
    68 class PipeClassOperandForm;
    69 class PipeClassResourceForm;
    70 class PeepMatch;
    71 class PeepConstraint;
    72 class PeepReplace;
    73 class MatchList;
    75 class ArchDesc;
    77 //==============================Register Allocation============================
    78 //------------------------------RegisterForm-----------------------------------
    79 class RegisterForm : public Form {
    80 private:
    81   AllocClass *_current_ac;         // State used by iter_RegDefs()
    83 public:
    84   // Public Data
    85   NameList    _rdefs;              // List of register definition names
    86   Dict        _regDef;             // map register name to RegDef*
    88   NameList    _rclasses;           // List of register class names
    89   Dict        _regClass;           // map register class name to RegClass*
    91   NameList    _aclasses;           // List of allocation class names
    92   Dict        _allocClass;         // Dictionary of allocation classes
    94   static int  _reg_ctr;         // Register counter
    95   static int  RegMask_Size();   // Compute RegMask size
    97   // Public Methods
    98   RegisterForm();
    99   ~RegisterForm();
   101   void        addRegDef(char *regName, char *callingConv, char *c_conv,
   102                         char * idealtype, char *encoding, char* concreteName);
   103   template<typename T> T* addRegClass(const char* className);
   105   AllocClass *addAllocClass(char *allocName);
   106   void        addSpillRegClass();
   108   // Provide iteration over all register definitions
   109   // in the order used by the register allocator
   110   void        reset_RegDefs();
   111   RegDef     *iter_RegDefs();
   112   RegDef     *getRegDef  (const char *regName);
   114   RegClass   *getRegClass(const char *className);
   116   // Return register mask, compressed chunk and register #
   117   uint       reg_mask(char *register_class);
   119   // Check that register classes are compatible with chunks
   120   bool       verify();
   122   void dump();                     // Debug printer
   123   void output(FILE *fp);           // Write info to output files
   124 };
   126 //------------------------------RegDef-----------------------------------------
   127 class RegDef : public Form {
   128 public:
   129   // Public Data
   130   const char *_regname;            // ADLC (Opto) Register name
   131   const char *_callconv;           // Calling convention
   132   const char *_c_conv;             // Native calling convention, 'C'
   133   const char *_idealtype;          // Ideal Type for register save/restore
   134   const char *_concrete;           // concrete register name
   136 private:
   137   const char *_register_encode;   // The register encoding
   138   // The chunk and register mask bits define info for register allocation
   139   uint32      _register_num;      // Which register am I
   141 public:
   142   // Public Methods
   143   RegDef(char  *regname, char *callconv, char *c_conv,
   144          char *idealtype, char *encoding, char *concrete);
   145   ~RegDef();                       // Destructor
   147   // Interface to define/redefine the register number
   148   void     set_register_num(uint32 new_register_num);
   150   // Bit pattern used for generating machine code
   151   const char *register_encode()   const;
   152   // Register number used in machine-independent code
   153   uint32   register_num()      const;
   155   void dump();                     // Debug printer
   156   void output(FILE *fp);           // Write info to output files
   157 };
   159 //------------------------------RegClass---------------------------------------
   160 // Generic register class. This register class is the internal representation
   161 // for the following .ad file format:
   162 //
   163 //  reg_class ptr(RAX, RBX, ...);
   164 //
   165 // where ptr is the name of the register class, RAX and RBX are registers.
   166 //
   167 // This register class allows registers to be spilled onto the stack. Spilling
   168 // is allowed is field _stack_or_reg is true.
   169 class RegClass : public Form {
   170 public:
   171   // Public Data
   172   const char *_classid;         // Name of class
   173   NameList    _regDefs;         // List of registers in class
   174   Dict        _regDef;          // Dictionary of registers in class
   175 protected:
   176   bool        _stack_or_reg;    // Allowed on any stack slot
   178 public:
   179   // Public Methods
   180   RegClass(const char *classid);// Constructor
   181   virtual ~RegClass();
   183   void addReg(RegDef *regDef);  // Add a register to this class
   185   uint size() const;            // Number of registers in class
   186   int regs_in_word( int wordnum, bool stack_also );
   188   const RegDef *get_RegDef(const char *regDef_name) const;
   190   // Returns the lowest numbered register in the mask.
   191   const RegDef* find_first_elem();
   193   // Iteration support
   194   void          reset();        // Reset the following two iterators
   195   RegDef       *RegDef_iter();  // which move jointly,
   196   const char   *rd_name_iter(); // invoking either advances both.
   198   void dump();                  // Debug printer
   199   void output(FILE *fp);        // Write info to output files
   201   virtual bool has_stack_version() {
   202     return _stack_or_reg;
   203   }
   204   virtual void set_stack_version(bool flag) {
   205     _stack_or_reg = flag;
   206   }
   208   virtual void declare_register_masks(FILE* fp);
   209   virtual void build_register_masks(FILE* fp);
   210 };
   212 //------------------------------CodeSnippetRegClass----------------------------
   213 // Register class that has an user-defined C++ code snippet attached to it
   214 // to determine at runtime which register class to use. This register class is
   215 // the internal representation for the following .ad file format:
   216 //
   217 //  reg_class actual_dflt_reg %{
   218 //      if (VM_Version::has_vfp3_32()) {
   219 //          return DFLT_REG_mask();
   220 //      } else {
   221 //          return DFLT_LOW_REG_mask();
   222 //      }
   223 //  %}
   224 //
   225 // where DFLT_REG_mask() and DFLT_LOW_REG_mask() are the internal names of the
   226 // masks of register classes dflt_reg and dflt_low_reg.
   227 //
   228 // The attached code snippet can select also between more than two register classes.
   229 // This register class can be, however, used only if the register class is not
   230 // cisc-spillable (i.e., the registers of this class are not allowed on the stack,
   231 // which is equivalent with _stack_or_reg being false).
   232 class CodeSnippetRegClass : public RegClass {
   233 protected:
   234   char* _code_snippet;
   235 public:
   236   CodeSnippetRegClass(const char* classid);// Constructor
   237   ~CodeSnippetRegClass();
   239   void set_code_snippet(char* code) {
   240     _code_snippet = code;
   241   }
   242   char* code_snippet() {
   243     return _code_snippet;
   244   }
   245   void set_stack_version(bool flag) {
   246     assert(false, "User defined register classes are not allowed to spill to the stack.");
   247   }
   248   void declare_register_masks(FILE* fp);
   249   void build_register_masks(FILE* fp) {
   250     // We do not need to generate register masks because we select at runtime
   251     // between register masks generated for other register classes.
   252     return;
   253   }
   254 };
   256 //------------------------------ConditionalRegClass----------------------------
   257 // Register class that has two register classes and a runtime condition attached
   258 // to it. The condition is evaluated at runtime and either one of the register
   259 // attached register classes is selected. This register class is the internal
   260 // representation for the following .ad format:
   261 //
   262 //  reg_class_dynamic actual_dflt_reg(dflt_reg, low_reg,
   263 //                                    %{ VM_Version::has_vfp3_32() }%
   264 //                                    );
   265 //
   266 // This example is equivalent to the example used with the CodeSnippetRegClass
   267 // register class. A ConditionalRegClass works also if a register class is cisc-spillable
   268 // (i.e., _stack_or_reg is true), but if can select only between two register classes.
   269 class ConditionalRegClass : public RegClass {
   270 protected:
   271   // reference to condition code
   272   char* _condition_code;  // C++ condition code to dynamically determine which register class to use.
   274                           // Example syntax (equivalent to previous example):
   275                           //
   276                           //  reg_class actual_dflt_reg(dflt_reg, low_reg,
   277                           //                            %{ VM_Version::has_vfp3_32() }%
   278                           //                            );
   279   // reference to conditional register classes
   280   RegClass* _rclasses[2]; // 0 is the register class selected if the condition code returns true
   281                           // 1 is the register class selected if the condition code returns false
   282 public:
   283   ConditionalRegClass(const char* classid);// Constructor
   284   ~ConditionalRegClass();
   286   virtual void set_stack_version(bool flag) {
   287     RegClass::set_stack_version(flag);
   288     assert((_rclasses[0] != NULL), "Register class NULL for condition code == true");
   289     assert((_rclasses[1] != NULL), "Register class NULL for condition code == false");
   290     _rclasses[0]->set_stack_version(flag);
   291     _rclasses[1]->set_stack_version(flag);
   292   }
   293   void declare_register_masks(FILE* fp);
   294   void build_register_masks(FILE* fp) {
   295     // We do not need to generate register masks because we select at runtime
   296     // between register masks generated for other register classes.
   297     return;
   298   }
   299   void set_rclass_at_index(int index, RegClass* rclass) {
   300     assert((0 <= index && index < 2), "Condition code can select only between two register classes");
   301     _rclasses[index] = rclass;
   302   }
   303   void set_condition_code(char* code) {
   304     _condition_code = code;
   305   }
   306   char* condition_code() {
   307     return _condition_code;
   308   }
   309 };
   311 //------------------------------AllocClass-------------------------------------
   312 class AllocClass : public Form {
   313 private:
   315 public:
   316   // Public Data
   317   char    *_classid;            // Name of class
   318   NameList _regDefs;            // List of registers in class
   319   Dict     _regDef;             // Dictionary of registers in class
   321   // Public Methods
   322   AllocClass(char *classid);    // Constructor
   324   void addReg(RegDef *regDef);  // Add a register to this class
   325   uint size() {return _regDef.Size();} // Number of registers in class
   327   void dump();                  // Debug printer
   328   void output(FILE *fp);        // Write info to output files
   329 };
   332 //==============================Frame Handling================================
   333 //------------------------------FrameForm-------------------------------------
   334 class FrameForm : public Form {
   335 private:
   337 public:
   338   // Public Data
   339   bool  _direction;                // Direction of stack growth
   340   char *_sync_stack_slots;
   341   char *_inline_cache_reg;
   342   char *_interpreter_method_oop_reg;
   343   char *_interpreter_frame_pointer_reg;
   344   char *_cisc_spilling_operand_name;
   345   char *_frame_pointer;
   346   char *_c_frame_pointer;
   347   char *_alignment;
   348   bool  _return_addr_loc;
   349   bool  _c_return_addr_loc;
   350   char *_return_addr;
   351   char *_c_return_addr;
   352   char *_in_preserve_slots;
   353   char *_varargs_C_out_slots_killed;
   354   char *_calling_convention;
   355   char *_c_calling_convention;
   356   char *_return_value;
   357   char *_c_return_value;
   359   // Public Methods
   360   FrameForm();
   361   ~FrameForm();
   363   void dump();                     // Debug printer
   364   void output(FILE *fp);           // Write info to output files
   365 };
   368 //==============================Scheduling=====================================
   369 //------------------------------PipelineForm-----------------------------------
   370 class PipelineForm : public Form {
   371 private:
   373 public:
   374   // Public Data
   375   NameList   _reslist;            // List of pipeline resources
   376   FormDict   _resdict;            // Resource Name -> ResourceForm mapping
   377   int        _rescount;           // Number of resources (ignores OR cases)
   378   int        _maxcycleused;       // Largest cycle used relative to beginning of instruction
   380   NameList   _stages;             // List of pipeline stages on architecture
   381   int        _stagecnt;           // Number of stages listed
   383   NameList   _classlist;          // List of pipeline classes
   384   FormDict   _classdict;          // Class Name -> PipeClassForm mapping
   385   int        _classcnt;           // Number of classes
   387   NameList   _noplist;            // List of NOP instructions
   388   int        _nopcnt;             // Number of nop instructions
   390   bool       _variableSizeInstrs; // Indicates if this architecture has variable sized instructions
   391   bool       _branchHasDelaySlot; // Indicates that branches have delay slot instructions
   392   int        _maxInstrsPerBundle; // Indicates the maximum number of instructions for ILP
   393   int        _maxBundlesPerCycle; // Indicates the maximum number of bundles for ILP
   394   int        _instrUnitSize;      // The minimum instruction unit size, in bytes
   395   int        _bundleUnitSize;     // The bundle unit size, in bytes
   396   int        _instrFetchUnitSize; // The size of the I-fetch unit, in bytes [must be power of 2]
   397   int        _instrFetchUnits;    // The number of I-fetch units processed per cycle
   399   // Public Methods
   400   PipelineForm();
   401   ~PipelineForm();
   403   void dump();                    // Debug printer
   404   void output(FILE *fp);          // Write info to output files
   405 };
   407 //------------------------------ResourceForm-----------------------------------
   408 class ResourceForm : public Form {
   409 public:
   410   unsigned mask() const { return _resmask; };
   412 private:
   413   // Public Data
   414   unsigned _resmask;         // Resource Mask (OR of resource specifier bits)
   416 public:
   418   // Virtual Methods
   419   virtual ResourceForm  *is_resource()    const;
   421   // Public Methods
   422   ResourceForm(unsigned resmask); // Constructor
   423   ~ResourceForm();                // Destructor
   425   void dump();                    // Debug printer
   426   void output(FILE *fp);          // Write info to output files
   427 };
   429 //------------------------------PipeClassOperandForm-----------------------------
   430 class PipeClassOperandForm : public Form {
   431 private:
   433 public:
   434   // Public Data
   435   const char *_stage;             // Name of Stage
   436   unsigned _iswrite;              // Read or Write
   437   unsigned _more_instrs;          // Additional Instructions
   439   // Public Methods
   440   PipeClassOperandForm(const char *stage, unsigned iswrite, unsigned more_instrs)
   441   : _stage(stage)
   442   , _iswrite(iswrite)
   443   , _more_instrs(more_instrs)
   444  {};
   446   ~PipeClassOperandForm() {};     // Destructor
   448   bool isWrite() const { return _iswrite != 0; }
   450   void dump();                    // Debug printer
   451   void output(FILE *fp);          // Write info to output files
   452 };
   454 //------------------------------PipeClassResourceForm--------------------------
   455 class PipeClassResourceForm : public Form {
   456 private:
   458 public:
   459   // Public Data
   460   const char *_resource;          // Resource
   461   const char *_stage;             // Stage the resource is used in
   462   int         _cycles;            // Number of cycles the resource is used
   464   // Public Methods
   465   PipeClassResourceForm(const char *resource, const char *stage, int cycles)
   466                                   // Constructor
   467     : _resource(resource)
   468     , _stage(stage)
   469     , _cycles(cycles)
   470     {};
   472   ~PipeClassResourceForm() {};    // Destructor
   474   void dump();                    // Debug printer
   475   void output(FILE *fp);          // Write info to output files
   476 };
   478 //------------------------------PipeClassForm----------------------------------
   479 class PipeClassForm : public Form {
   480 private:
   482 public:
   484   // Public Data
   485   const char       *_ident;             // Name of class
   486   int               _num;               // Used in name of MachNode subclass
   487   NameList          _parameters;        // Locally defined names
   488   FormDict          _localNames;        // Table of operands & their types
   489   FormDict          _localUsage;        // Table of operand usage
   490   FormList          _resUsage;          // List of resource usage
   491   NameList          _instructs;         // List of instructions and machine nodes that use this pipeline class
   492   bool              _has_fixed_latency; // Always takes this number of cycles
   493   int               _fixed_latency;     // Always takes this number of cycles
   494   int               _instruction_count; // Number of instructions in first bundle
   495   bool              _has_multiple_bundles;  // Indicates if 1 or multiple bundles
   496   bool              _has_branch_delay_slot; // Has branch delay slot as last instruction
   497   bool              _force_serialization;   // This node serializes relative to surrounding nodes
   498   bool              _may_have_no_code;      // This node may generate no code based on register allocation
   500   // Virtual Methods
   501   virtual PipeClassForm  *is_pipeclass()    const;
   503   // Public Methods
   504   PipeClassForm(const char *id, int num);
   505                                   // Constructor
   506   ~PipeClassForm();               // Destructor
   508   bool hasFixedLatency() { return _has_fixed_latency; }
   509   int fixedLatency() { return _fixed_latency; }
   511   void setFixedLatency(int fixed_latency) { _has_fixed_latency = 1; _fixed_latency = fixed_latency; }
   513   void setInstructionCount(int i)    { _instruction_count = i; }
   514   void setMultipleBundles(bool b)    { _has_multiple_bundles = b; }
   515   void setBranchDelay(bool s)        { _has_branch_delay_slot = s; }
   516   void setForceSerialization(bool s) { _force_serialization = s; }
   517   void setMayHaveNoCode(bool s)      { _may_have_no_code = s; }
   519   int  InstructionCount()   const { return _instruction_count; }
   520   bool hasMultipleBundles() const { return _has_multiple_bundles; }
   521   bool hasBranchDelay()     const { return _has_branch_delay_slot; }
   522   bool forceSerialization() const { return _force_serialization; }
   523   bool mayHaveNoCode()      const { return _may_have_no_code; }
   525   void dump();                    // Debug printer
   526   void output(FILE *fp);          // Write info to output files
   527 };
   530 //==============================Peephole Optimization==========================
   531 //------------------------------Peephole---------------------------------------
   532 class Peephole : public Form {
   533 private:
   534   static int      _peephole_counter;// Incremented by each peephole rule parsed
   535   int             _peephole_number;// Remember my order in architecture description
   536   PeepMatch      *_match;          // Instruction pattern to match
   537   PeepConstraint *_constraint;     // List of additional constraints
   538   PeepReplace    *_replace;        // Instruction pattern to substitute in
   540   Peephole *_next;
   542 public:
   543   // Public Methods
   544   Peephole();
   545   ~Peephole();
   547   // Append a peephole rule with the same root instruction
   548   void append_peephole(Peephole *next_peephole);
   550   // Store the components of this peephole rule
   551   void add_match(PeepMatch *only_one_match);
   552   void append_constraint(PeepConstraint *next_constraint);
   553   void add_replace(PeepReplace *only_one_replacement);
   555   // Access the components of this peephole rule
   556   int             peephole_number() { return _peephole_number; }
   557   PeepMatch      *match()       { return _match; }
   558   PeepConstraint *constraints() { return _constraint; }
   559   PeepReplace    *replacement() { return _replace; }
   560   Peephole       *next()        { return _next; }
   562   void dump();                     // Debug printer
   563   void output(FILE *fp);           // Write info to output files
   564 };
   567 class PeepMatch : public Form {
   568 private:
   569   char *_rule;
   570   // NameList  _depth;                // Depth of this instruction
   571   NameList  _parent;
   572   NameList  _position;
   573   NameList  _instrs;               // List of instructions in match rule
   574   NameList  _input;                // input position in parent's instruction
   575   int       _max_position;
   577 public:
   578   // Public Methods
   579   PeepMatch(char *rule);
   580   ~PeepMatch();
   582   // Insert info into the match-rule
   583   void  add_instruction(int parent, int position, const char *name, int input);
   585   // Access info about instructions in the peep-match rule
   586   int   max_position();
   587   const char *instruction_name(int position);
   588   // Iterate through all info on matched instructions
   589   void  reset();
   590   void  next_instruction(int &parent, int &position, const char* &name, int &input);
   591   // 'true' if current position in iteration is a placeholder, not matched.
   592   bool  is_placeholder();
   594   void dump();
   595   void output(FILE *fp);
   596 };
   599 class PeepConstraint : public Form {
   600 private:
   601   PeepConstraint *_next;           // Additional constraints ANDed together
   603 public:
   604   const int   _left_inst;
   605   const char* _left_op;
   606   const char* _relation;
   607   const int   _right_inst;
   608   const char* _right_op;
   610 public:
   611   // Public Methods
   612   PeepConstraint(int left_inst,  char* left_op, char* relation,
   613                  int right_inst, char* right_op);
   614   ~PeepConstraint();
   616   // Check if constraints use instruction at position
   617   bool constrains_instruction(int position);
   619   // Add another constraint
   620   void append(PeepConstraint *next_peep_constraint);
   621   // Access the next constraint in the list
   622   PeepConstraint *next();
   624   void dump();
   625   void output(FILE *fp);
   626 };
   629 class PeepReplace : public Form {
   630 private:
   631   char *_rule;
   632   NameList _instruction;
   633   NameList _operand_inst_num;
   634   NameList _operand_op_name;
   636 public:
   638   // Public Methods
   639   PeepReplace(char *rule);
   640   ~PeepReplace();
   642   // Add contents of peepreplace
   643   void  add_instruction(char *root);
   644   void  add_operand( int inst_num, char *inst_operand );
   646   // Access contents of peepreplace
   647   void  reset();
   648   void  next_instruction(const char * &root);
   649   void  next_operand(int &inst_num, const char * &inst_operand );
   651   // Utilities
   652   void dump();
   653   void output(FILE *fp);
   654 };
   657 class PeepChild : public Form {
   658 public:
   659   const int   _inst_num;         // Number of instruction (-1 if only named)
   660   const char *_inst_op;          // Instruction's operand, NULL if number == -1
   661   const char *_inst_name;        // Name of the instruction
   663 public:
   664   PeepChild(char *inst_name)
   665     : _inst_num(-1), _inst_op(NULL), _inst_name(inst_name) {};
   666   PeepChild(int inst_num, char *inst_op, char *inst_name)
   667     : _inst_num(inst_num), _inst_op(inst_op), _inst_name(inst_name) {};
   668   ~PeepChild();
   670   bool  use_leaf_operand()        { return _inst_num != -1; };
   671   bool  generate_an_instruction() { return _inst_num == -1; }
   673   void dump();
   674   void output(FILE *fp);
   675 };
   677 #endif // SHARE_VM_ADLC_FORMSOPT_HPP

mercurial