hotspot/src/share/vm/adlc/formsopt.hpp
changeset 1 489c9b5090e2
child 2129 e810a33b5c67
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/adlc/formsopt.hpp	Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,548 @@
+/*
+ * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+// FORMSOPT.HPP - ADL Parser Target Specific Optimization Forms Classes
+
+// Class List
+class Form;
+class InstructForm;
+class OperandForm;
+class OpClassForm;
+class AttributeForm;
+class RegisterForm;
+class PipelineForm;
+class SourceForm;
+class EncodeForm;
+class Component;
+class Constraint;
+class Predicate;
+class MatchRule;
+class Attribute;
+class Effect;
+class ExpandRule;
+class RewriteRule;
+class ConstructRule;
+class FormatRule;
+class Peephole;
+class PeepMatch;
+class PeepConstraint;
+class EncClass;
+class Interface;
+class RegInterface;
+class ConstInterface;
+class MemInterface;
+class CondInterface;
+class Opcode;
+class InsEncode;
+class RegDef;
+class RegClass;
+class AllocClass;
+class ResourceForm;
+class PipeClassForm;
+class PipeClassOperandForm;
+class PipeClassResourceForm;
+class PeepMatch;
+class PeepConstraint;
+class PeepReplace;
+class MatchList;
+
+class ArchDesc;
+
+//==============================Register Allocation============================
+//------------------------------RegisterForm-----------------------------------
+class RegisterForm : public Form {
+private:
+  AllocClass *_current_ac;         // State used by iter_RegDefs()
+
+public:
+  // Public Data
+  NameList    _rdefs;              // List of register definition names
+  Dict        _regDef;             // map register name to RegDef*
+
+  NameList    _rclasses;           // List of register class names
+  Dict        _regClass;           // map register class name to RegClass*
+
+  NameList    _aclasses;           // List of allocation class names
+  Dict        _allocClass;         // Dictionary of allocation classes
+
+  static int  _reg_ctr;         // Register counter
+  static int  RegMask_Size();   // Compute RegMask size
+
+  // Public Methods
+  RegisterForm();
+  ~RegisterForm();
+
+  void        addRegDef(char *regName, char *callingConv, char *c_conv,
+                        char * idealtype, char *encoding, char* concreteName);
+  RegClass   *addRegClass(const char *className);
+  AllocClass *addAllocClass(char *allocName);
+  void        addSpillRegClass();
+
+  // Provide iteration over all register definitions
+  // in the order used by the register allocator
+  void        reset_RegDefs();
+  RegDef     *iter_RegDefs();
+  RegDef     *getRegDef  (const char *regName);
+
+  RegClass   *getRegClass(const char *className);
+
+  // Return register mask, compressed chunk and register #
+  uint       reg_mask(char *register_class);
+
+  // Check that register classes are compatible with chunks
+  bool       verify();
+
+  void dump();                     // Debug printer
+  void output(FILE *fp);           // Write info to output files
+};
+
+//------------------------------RegDef-----------------------------------------
+class RegDef : public Form {
+public:
+  // Public Data
+  const char *_regname;            // ADLC (Opto) Register name
+  const char *_callconv;           // Calling convention
+  const char *_c_conv;             // Native calling convention, 'C'
+  const char *_idealtype;          // Ideal Type for register save/restore
+  const char *_concrete;           // concrete register name
+
+private:
+  const char *_register_encode;   // The register encoding
+  // The chunk and register mask bits define info for register allocation
+  uint32      _register_num;      // Which register am I
+
+public:
+  // Public Methods
+  RegDef(char  *regname, char *callconv, char *c_conv,
+         char *idealtype, char *encoding, char *concrete);
+  ~RegDef();                       // Destructor
+
+  // Interface to define/redefine the register number
+  void     set_register_num(uint32 new_register_num);
+
+  // Bit pattern used for generating machine code
+  const char *register_encode()   const;
+  // Register number used in machine-independent code
+  uint32   register_num()      const;
+
+  void dump();                     // Debug printer
+  void output(FILE *fp);           // Write info to output files
+};
+
+//------------------------------RegClass---------------------------------------
+class RegClass : public Form {
+public:
+  // Public Data
+  const char *_classid;         // Name of class
+  NameList    _regDefs;         // List of registers in class
+  Dict        _regDef;          // Dictionary of registers in class
+  bool        _stack_or_reg;    // Allowed on any stack slot
+
+  // Public Methods
+  RegClass(const char *classid);// Constructor
+
+  void addReg(RegDef *regDef);  // Add a register to this class
+
+  uint size() const;            // Number of registers in class
+  int regs_in_word( int wordnum, bool stack_also );
+
+  const RegDef *get_RegDef(const char *regDef_name) const;
+
+  // Returns the lowest numbered register in the mask.
+  const RegDef* find_first_elem();
+
+  // Iteration support
+  void          reset();        // Reset the following two iterators
+  RegDef       *RegDef_iter();  // which move jointly,
+  const char   *rd_name_iter(); // invoking either advances both.
+
+  void dump();                  // Debug printer
+  void output(FILE *fp);        // Write info to output files
+};
+
+//------------------------------AllocClass-------------------------------------
+class AllocClass : public Form {
+private:
+
+public:
+  // Public Data
+  char    *_classid;            // Name of class
+  NameList _regDefs;            // List of registers in class
+  Dict     _regDef;             // Dictionary of registers in class
+
+  // Public Methods
+  AllocClass(char *classid);    // Constructor
+
+  void addReg(RegDef *regDef);  // Add a register to this class
+  uint size() {return _regDef.Size();} // Number of registers in class
+
+  void dump();                  // Debug printer
+  void output(FILE *fp);        // Write info to output files
+};
+
+
+//==============================Frame Handling================================
+//------------------------------FrameForm-------------------------------------
+class FrameForm : public Form {
+private:
+
+public:
+  // Public Data
+  bool  _direction;                // Direction of stack growth
+  char *_sync_stack_slots;
+  char *_inline_cache_reg;
+  char *_interpreter_method_oop_reg;
+  char *_interpreter_frame_pointer_reg;
+  char *_cisc_spilling_operand_name;
+  char *_frame_pointer;
+  char *_c_frame_pointer;
+  char *_alignment;
+  bool  _return_addr_loc;
+  bool  _c_return_addr_loc;
+  char *_return_addr;
+  char *_c_return_addr;
+  char *_in_preserve_slots;
+  char *_varargs_C_out_slots_killed;
+  char *_calling_convention;
+  char *_c_calling_convention;
+  char *_return_value;
+  char *_c_return_value;
+
+  // Public Methods
+  FrameForm();
+  ~FrameForm();
+
+  void dump();                     // Debug printer
+  void output(FILE *fp);           // Write info to output files
+};
+
+
+//==============================Scheduling=====================================
+//------------------------------PipelineForm-----------------------------------
+class PipelineForm : public Form {
+private:
+
+public:
+  // Public Data
+  NameList   _reslist;            // List of pipeline resources
+  FormDict   _resdict;            // Resource Name -> ResourceForm mapping
+  int        _rescount;           // Number of resources (ignores OR cases)
+  int        _maxcycleused;       // Largest cycle used relative to beginning of instruction
+
+  NameList   _stages;             // List of pipeline stages on architecture
+  int        _stagecnt;           // Number of stages listed
+
+  NameList   _classlist;          // List of pipeline classes
+  FormDict   _classdict;          // Class Name -> PipeClassForm mapping
+  int        _classcnt;           // Number of classes
+
+  NameList   _noplist;            // List of NOP instructions
+  int        _nopcnt;             // Number of nop instructions
+
+  bool       _variableSizeInstrs; // Indicates if this architecture has variable sized instructions
+  bool       _branchHasDelaySlot; // Indicates that branches have delay slot instructions
+  int        _maxInstrsPerBundle; // Indicates the maximum number of instructions for ILP
+  int        _maxBundlesPerCycle; // Indicates the maximum number of bundles for ILP
+  int        _instrUnitSize;      // The minimum instruction unit size, in bytes
+  int        _bundleUnitSize;     // The bundle unit size, in bytes
+  int        _instrFetchUnitSize; // The size of the I-fetch unit, in bytes [must be power of 2]
+  int        _instrFetchUnits;    // The number of I-fetch units processed per cycle
+
+  // Public Methods
+  PipelineForm();
+  ~PipelineForm();
+
+  void dump();                    // Debug printer
+  void output(FILE *fp);          // Write info to output files
+};
+
+//------------------------------ResourceForm-----------------------------------
+class ResourceForm : public Form {
+public:
+  unsigned mask() const { return _resmask; };
+
+private:
+  // Public Data
+  unsigned _resmask;         // Resource Mask (OR of resource specifier bits)
+
+public:
+
+  // Virtual Methods
+  virtual ResourceForm  *is_resource()    const;
+
+  // Public Methods
+  ResourceForm(unsigned resmask); // Constructor
+  ~ResourceForm();                // Destructor
+
+  void dump();                    // Debug printer
+  void output(FILE *fp);          // Write info to output files
+};
+
+//------------------------------PipeClassOperandForm-----------------------------
+class PipeClassOperandForm : public Form {
+private:
+
+public:
+  // Public Data
+  const char *_stage;             // Name of Stage
+  unsigned _iswrite;              // Read or Write
+  unsigned _more_instrs;          // Additional Instructions
+
+  // Public Methods
+  PipeClassOperandForm(const char *stage, unsigned iswrite, unsigned more_instrs)
+  : _stage(stage)
+  , _iswrite(iswrite)
+  , _more_instrs(more_instrs)
+ {};
+
+  ~PipeClassOperandForm() {};     // Destructor
+
+  bool isWrite() const { return _iswrite != 0; }
+
+  void dump();                    // Debug printer
+  void output(FILE *fp);          // Write info to output files
+};
+
+//------------------------------PipeClassResourceForm--------------------------
+class PipeClassResourceForm : public Form {
+private:
+
+public:
+  // Public Data
+  const char *_resource;          // Resource
+  const char *_stage;             // Stage the resource is used in
+  int         _cycles;            // Number of cycles the resource is used
+
+  // Public Methods
+  PipeClassResourceForm(const char *resource, const char *stage, int cycles)
+                                  // Constructor
+    : _resource(resource)
+    , _stage(stage)
+    , _cycles(cycles)
+    {};
+
+  ~PipeClassResourceForm() {};    // Destructor
+
+  void dump();                    // Debug printer
+  void output(FILE *fp);          // Write info to output files
+};
+
+//------------------------------PipeClassForm----------------------------------
+class PipeClassForm : public Form {
+private:
+
+public:
+
+  // Public Data
+  const char       *_ident;             // Name of class
+  int               _num;               // Used in name of MachNode subclass
+  NameList          _parameters;        // Locally defined names
+  FormDict          _localNames;        // Table of operands & their types
+  FormDict          _localUsage;        // Table of operand usage
+  FormList          _resUsage;          // List of resource usage
+  NameList          _instructs;         // List of instructions and machine nodes that use this pipeline class
+  bool              _has_fixed_latency; // Always takes this number of cycles
+  int               _fixed_latency;     // Always takes this number of cycles
+  int               _instruction_count; // Number of instructions in first bundle
+  bool              _has_multiple_bundles;  // Indicates if 1 or multiple bundles
+  bool              _has_branch_delay_slot; // Has branch delay slot as last instruction
+  bool              _force_serialization;   // This node serializes relative to surrounding nodes
+  bool              _may_have_no_code;      // This node may generate no code based on register allocation
+
+  // Virtual Methods
+  virtual PipeClassForm  *is_pipeclass()    const;
+
+  // Public Methods
+  PipeClassForm(const char *id, int num);
+                                  // Constructor
+  ~PipeClassForm();               // Destructor
+
+  bool hasFixedLatency() { return _has_fixed_latency; }
+  int fixedLatency() { return _fixed_latency; }
+
+  void setFixedLatency(int fixed_latency) { _has_fixed_latency = 1; _fixed_latency = fixed_latency; }
+
+  void setInstructionCount(int i)    { _instruction_count = i; }
+  void setMultipleBundles(bool b)    { _has_multiple_bundles = b; }
+  void setBranchDelay(bool s)        { _has_branch_delay_slot = s; }
+  void setForceSerialization(bool s) { _force_serialization = s; }
+  void setMayHaveNoCode(bool s)      { _may_have_no_code = s; }
+
+  int  InstructionCount()   const { return _instruction_count; }
+  bool hasMultipleBundles() const { return _has_multiple_bundles; }
+  bool hasBranchDelay()     const { return _has_branch_delay_slot; }
+  bool forceSerialization() const { return _force_serialization; }
+  bool mayHaveNoCode()      const { return _may_have_no_code; }
+
+  void dump();                    // Debug printer
+  void output(FILE *fp);          // Write info to output files
+};
+
+
+//==============================Peephole Optimization==========================
+//------------------------------Peephole---------------------------------------
+class Peephole : public Form {
+private:
+  static int      _peephole_counter;// Incremented by each peephole rule parsed
+  int             _peephole_number;// Remember my order in architecture description
+  PeepMatch      *_match;          // Instruction pattern to match
+  PeepConstraint *_constraint;     // List of additional constraints
+  PeepReplace    *_replace;        // Instruction pattern to substitute in
+
+  Peephole *_next;
+
+public:
+  // Public Methods
+  Peephole();
+  ~Peephole();
+
+  // Append a peephole rule with the same root instruction
+  void append_peephole(Peephole *next_peephole);
+
+  // Store the components of this peephole rule
+  void add_match(PeepMatch *only_one_match);
+  void append_constraint(PeepConstraint *next_constraint);
+  void add_replace(PeepReplace *only_one_replacement);
+
+  // Access the components of this peephole rule
+  int             peephole_number() { return _peephole_number; }
+  PeepMatch      *match()       { return _match; }
+  PeepConstraint *constraints() { return _constraint; }
+  PeepReplace    *replacement() { return _replace; }
+  Peephole       *next()        { return _next; }
+
+  void dump();                     // Debug printer
+  void output(FILE *fp);           // Write info to output files
+};
+
+
+class PeepMatch : public Form {
+private:
+  char *_rule;
+  // NameList  _depth;                // Depth of this instruction
+  NameList  _parent;
+  NameList  _position;
+  NameList  _instrs;               // List of instructions in match rule
+  NameList  _input;                // input position in parent's instruction
+  int       _max_position;
+
+public:
+  // Public Methods
+  PeepMatch(char *rule);
+  ~PeepMatch();
+
+  // Insert info into the match-rule
+  void  add_instruction(int parent, int position, const char *name, int input);
+
+  // Access info about instructions in the peep-match rule
+  int   max_position();
+  const char *instruction_name(intptr_t position);
+  // Iterate through all info on matched instructions
+  void  reset();
+  void  next_instruction( intptr_t &parent, intptr_t &position, const char * &name, intptr_t &input );
+  // 'true' if current position in iteration is a placeholder, not matched.
+  bool  is_placeholder();
+
+  void dump();
+  void output(FILE *fp);
+};
+
+
+class PeepConstraint : public Form {
+private:
+  PeepConstraint *_next;           // Additional constraints ANDed together
+
+public:
+  const intptr_t  _left_inst;
+  const char      *_left_op;
+  const char      *_relation;
+  const intptr_t  _right_inst;
+  const char      *_right_op;
+
+public:
+  // Public Methods
+  PeepConstraint(intptr_t  left_inst,  char *left_op, char *relation,
+                 intptr_t  right_inst, char *right_op);
+  ~PeepConstraint();
+
+  // Check if constraints use instruction at position
+  bool constrains_instruction(intptr_t position);
+
+  // Add another constraint
+  void append(PeepConstraint *next_peep_constraint);
+  // Access the next constraint in the list
+  PeepConstraint *next();
+
+  void dump();
+  void output(FILE *fp);
+};
+
+
+class PeepReplace : public Form {
+private:
+  char *_rule;
+  NameList _instruction;
+  NameList _operand_inst_num;
+  NameList _operand_op_name;
+
+public:
+
+  // Public Methods
+  PeepReplace(char *rule);
+  ~PeepReplace();
+
+  // Add contents of peepreplace
+  void  add_instruction(char *root);
+  void  add_operand( int inst_num, char *inst_operand );
+
+  // Access contents of peepreplace
+  void  reset();
+  void  next_instruction(const char * &root);
+  void  next_operand( intptr_t &inst_num, const char * &inst_operand );
+
+  // Utilities
+  void dump();
+  void output(FILE *fp);
+};
+
+
+class PeepChild : public Form {
+public:
+  const int   _inst_num;         // Number of instruction (-1 if only named)
+  const char *_inst_op;          // Instruction's operand, NULL if number == -1
+  const char *_inst_name;        // Name of the instruction
+
+public:
+  PeepChild(char *inst_name)
+    : _inst_num(-1), _inst_op(NULL), _inst_name(inst_name) {};
+  PeepChild(int inst_num, char *inst_op, char *inst_name)
+    : _inst_num(inst_num), _inst_op(inst_op), _inst_name(inst_name) {};
+  ~PeepChild();
+
+  bool  use_leaf_operand()        { return _inst_num != -1; };
+  bool  generate_an_instruction() { return _inst_num == -1; }
+
+  void dump();
+  void output(FILE *fp);
+};