--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/adlc/forms.hpp Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,586 @@
+/*
+ * Copyright 1997-2007 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.
+ *
+ */
+
+// FORMS.HPP - ADL Parser Generic and Utility Forms Classes
+
+#define TRUE 1
+#define FALSE 0
+
+// DEFINITIONS OF LEGAL ATTRIBUTE TYPES
+#define INS_ATTR 0
+#define OP_ATTR 1
+
+// DEFINITIONS OF LEGAL CONSTRAINT TYPES
+
+// Class List
+class Form;
+class InstructForm;
+class MachNodeForm;
+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 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 PeepMatch;
+class PeepConstraint;
+class PeepReplace;
+class MatchList;
+
+class ArchDesc;
+
+//------------------------------FormDict---------------------------------------
+// Dictionary containing Forms, and objects derived from forms
+class FormDict {
+private:
+ Dict _form; // map names, char*, to their Form* or NULL
+
+ // Disable public use of constructor, copy-ctor, operator =, operator ==
+ FormDict( );
+ FormDict &operator =( const FormDict & );
+ // == compares two dictionaries; they must have the same keys (their keys
+ // must match using CmpKey) and they must have the same values (pointer
+ // comparison). If so 1 is returned, if not 0 is returned.
+ bool operator ==(const FormDict &d) const; // Compare dictionaries for equal
+
+public:
+ // cmp is a key comparision routine. hash is a routine to hash a key.
+ // FormDict( CmpKey cmp, Hash hash );
+ FormDict( CmpKey cmp, Hash hash, Arena *arena );
+ FormDict( const FormDict & fd ); // Deep-copy guts
+ ~FormDict();
+
+ // Return # of key-value pairs in dict
+ int Size(void) const;
+
+ // Insert inserts the given key-value pair into the dictionary. The prior
+ // value of the key is returned; NULL if the key was not previously defined.
+ const Form *Insert(const char *name, Form *form); // A new key-value
+
+ // Find finds the value of a given key; or NULL if not found.
+ // The dictionary is NOT changed.
+ const Form *operator [](const char *name) const; // Do a lookup
+
+ void dump();
+};
+
+// ***** Master Class for ADL Parser Forms *****
+//------------------------------Form-------------------------------------------
+class Form {
+public:
+ static Arena *arena; // arena used by forms
+private:
+ static Arena *generate_arena(); // allocate arena used by forms
+
+protected:
+ int _ftype; // Indicator for derived class type
+
+public:
+ // Public Data
+ Form *_next; // Next pointer for form lists
+ long _linenum; // Line number for debugging
+
+ // Dynamic type check for common forms.
+ virtual OpClassForm *is_opclass() const;
+ virtual OperandForm *is_operand() const;
+ virtual InstructForm *is_instruction() const;
+ virtual MachNodeForm *is_machnode() const;
+ virtual AttributeForm *is_attribute() const;
+ virtual Effect *is_effect() const;
+ virtual ResourceForm *is_resource() const;
+ virtual PipeClassForm *is_pipeclass() const;
+
+ // Check if this form is an operand usable for cisc-spilling
+ virtual bool is_cisc_reg(FormDict &globals) const { return false; }
+ virtual bool is_cisc_mem(FormDict &globals) const { return false; }
+
+ // Public Methods
+ Form(int formType=0, int line=0)
+ : _next(NULL), _linenum(line), _ftype(formType) { };
+ ~Form() {};
+
+ virtual bool ideal_only() const {
+ assert(0,"Check of ideal status on non-instruction/operand form.\n");
+ return FALSE;
+ }
+
+ // Check constraints after parsing
+ virtual bool verify() { return true; }
+
+ virtual void dump() { output(stderr); } // Debug printer
+ // Write info to output files
+ virtual void output(FILE *fp) { fprintf(fp,"Form Output"); }
+
+public:
+ // ADLC types, match the last character on ideal operands and instructions
+ enum DataType {
+ none = 0, // Not a simple type
+ idealI = 1, // Integer type
+ idealP = 2, // Pointer types, oop(s)
+ idealL = 3, // Long type
+ idealF = 4, // Float type
+ idealD = 5, // Double type
+ idealB = 6, // Byte type
+ idealC = 7, // Char type
+ idealS = 8 // String type
+ };
+ // Convert ideal name to a DataType, return DataType::none if not a 'ConX'
+ Form::DataType ideal_to_const_type(const char *ideal_type_name) const;
+ // Convert ideal name to a DataType, return DataType::none if not a 'sRegX
+ Form::DataType ideal_to_sReg_type(const char *name) const;
+ // Convert ideal name to a DataType, return DataType::none if not a 'RegX
+ Form::DataType ideal_to_Reg_type(const char *name) const;
+
+ // Convert ideal name to a DataType, return DataType::none if not a 'LoadX
+ Form::DataType is_load_from_memory(const char *opType) const;
+ // Convert ideal name to a DataType, return DataType::none if not a 'StoreX
+ Form::DataType is_store_to_memory(const char *opType) const;
+
+ // ADLC call types, matched with ideal world
+ enum CallType {
+ invalid_type = 0, // invalid call type
+ JAVA_STATIC = 1, // monomorphic entry
+ JAVA_DYNAMIC = 2, // possibly megamorphic, inline cache call
+ JAVA_COMPILED = 3, // callee will be compiled java
+ JAVA_INTERP = 4, // callee will be executed by interpreter
+ JAVA_NATIVE = 5, // native entrypoint
+ JAVA_RUNTIME = 6, // runtime entrypoint
+ JAVA_LEAF = 7 // calling leaf
+ };
+
+ // Interface types for operands and operand classes
+ enum InterfaceType {
+ no_interface = 0, // unknown or inconsistent interface type
+ constant_interface = 1, // interface to constants
+ register_interface = 2, // interface to registers
+ memory_interface = 3, // interface to memory
+ conditional_interface = 4 // interface for condition codes
+ };
+ virtual Form::InterfaceType interface_type(FormDict &globals) const;
+
+ enum CiscSpillInfo {
+ Not_cisc_spillable = AdlcVMDeps::Not_cisc_spillable,
+ Maybe_cisc_spillable = 0,
+ Is_cisc_spillable = 1
+ // ...
+ };
+
+ // LEGAL FORM TYPES
+ enum {
+ INS,
+ OPER,
+ OPCLASS,
+ SRC,
+ ADEF,
+ REG,
+ PIPE,
+ CNST,
+ PRED,
+ ATTR,
+ MAT,
+ ENC,
+ FOR,
+ EXP,
+ REW,
+ EFF,
+ RDEF,
+ RCL,
+ ACL,
+ RES,
+ PCL,
+ PDEF,
+ REGL,
+ RESL,
+ STAL,
+ COMP,
+ PEEP,
+ RESO
+ };
+
+};
+
+//------------------------------FormList---------------------------------------
+class FormList {
+private:
+ Form *_root;
+ Form *_tail;
+ Form *_cur;
+ int _justReset; // Set immediately after reset
+ Form *_cur2; // Nested iterator
+ int _justReset2;
+
+public:
+ void addForm(Form * entry) {
+ if (_tail==NULL) { _root = _tail = _cur = entry;}
+ else { _tail->_next = entry; _tail = entry;}
+ };
+ Form * current() { return _cur; };
+ Form * iter() { if (_justReset) _justReset = 0;
+ else if (_cur) _cur = _cur->_next;
+ return _cur;};
+ void reset() { if (_root) {_cur = _root; _justReset = 1;} };
+
+ // Second iterator, state is internal
+ Form * current2(){ return _cur2; };
+ Form * iter2() { if (_justReset2) _justReset2 = 0;
+ else if (_cur2) _cur2 = _cur2->_next;
+ return _cur2;};
+ void reset2() { if (_root) {_cur2 = _root; _justReset2 = 1;} };
+
+ int count() {
+ int count = 0; reset();
+ for( Form *cur; (cur = iter()) != NULL; ) { ++count; };
+ return count;
+ }
+
+ void dump() {
+ reset();
+ Form *cur;
+ for(; (cur = iter()) != NULL; ) {
+ cur->dump();
+ };
+ }
+
+ bool verify() {
+ bool verified = true;
+
+ reset();
+ Form *cur;
+ for(; (cur = iter()) != NULL; ) {
+ if ( ! cur->verify() ) verified = false;
+ };
+
+ return verified;
+ }
+
+ void output(FILE* fp) {
+ reset();
+ Form *cur;
+ for( ; (cur = iter()) != NULL; ) {
+ cur->output(fp);
+ };
+ }
+
+ FormList() { _justReset = 1; _justReset2 = 1; _root = NULL; _tail = NULL; _cur = NULL; _cur2 = NULL;};
+ ~FormList();
+};
+
+//------------------------------NameList---------------------------------------
+// Extendable list of pointers, <char *>
+class NameList {
+ friend class PreserveIter;
+
+private:
+ int _cur; // Insert next entry here; count of entries
+ int _max; // Number of spaces allocated
+ const char **_names; // Array of names
+
+protected:
+ int _iter; // position during iteration
+ bool _justReset; // Set immediately after reset
+
+
+public:
+ static const char *_signal; // reserved user-defined string
+ enum { Not_in_list = -1 };
+
+ void addName(const char *name);
+ void add_signal();
+ void clear(); // Remove all entries
+
+ int count() const;
+
+ void reset(); // Reset iteration
+ const char *iter(); // after reset(), first element : else next
+ const char *current(); // return current element in iteration.
+
+ bool current_is_signal(); // Return 'true' if current entry is signal
+ bool is_signal(const char *entry); // Return true if entry is a signal
+
+ bool search(const char *); // Search for a name in the list
+ int index(const char *); // Return index of name in list
+ const char *name (intptr_t index);// Return name at index in list
+
+ void dump(); // output to stderr
+ void output(FILE *fp); // Output list of names to 'fp'
+
+ NameList();
+ ~NameList();
+};
+
+
+// Convenience class to preserve iteration state since iterators are
+// internal instead of being external.
+class PreserveIter {
+ private:
+ NameList* _list;
+ int _iter;
+ bool _justReset;
+
+ public:
+ PreserveIter(NameList* nl) {
+ _list = nl;
+ _iter = _list->_iter;
+ _justReset = _list->_justReset;
+ }
+ ~PreserveIter() {
+ _list->_iter = _iter;
+ _list->_justReset = _justReset;
+ }
+
+};
+
+
+//------------------------------NameAndList------------------------------------
+// Storage for a name and an associated list of names
+class NameAndList {
+private:
+ const char *_name;
+ NameList _list;
+
+public:
+ NameAndList(char *name);
+ ~NameAndList();
+
+ // Add to entries in list
+ void add_entry(const char *entry);
+
+ // Access the name and its associated list.
+ const char *name() const;
+ void reset();
+ const char *iter();
+
+ int count() { return _list.count(); }
+
+ // Return the "index" entry in the list, zero-based
+ const char *operator[](int index);
+
+
+ void dump(); // output to stderr
+ void output(FILE *fp); // Output list of names to 'fp'
+};
+
+//------------------------------ComponentList---------------------------------
+// Component lists always have match rule operands first, followed by parameter
+// operands which do not appear in the match list (in order of declaration).
+class ComponentList : private NameList {
+private:
+ int _matchcnt; // Count of match rule operands
+
+public:
+
+ // This is a batch program. (And I have a destructor bug!)
+ void operator delete( void *ptr ) {}
+
+ void insert(Component *component, bool mflag);
+ void insert(const char *name, const char *opType, int usedef, bool mflag);
+
+ int count();
+ int match_count() { return _matchcnt; } // Get count of match rule opers
+
+ Component *iter(); // after reset(), first element : else next
+ Component *match_iter(); // after reset(), first element : else next
+ Component *post_match_iter(); // after reset(), first element : else next
+ void reset(); // Reset iteration
+ Component *current(); // return current element in iteration.
+
+ // Return element at "position", else NULL
+ Component *operator[](int position);
+ Component *at(int position) { return (*this)[position]; }
+
+ // Return first component having this name.
+ const Component *search(const char *name);
+
+ // Return number of USEs + number of DEFs
+ int num_operands();
+ // Return zero-based position in list; -1 if not in list.
+ int operand_position(const char *name, int usedef);
+ // Find position for this name, regardless of use/def information
+ int operand_position(const char *name);
+ // Find position for this name when looked up for output via "format"
+ int operand_position_format(const char *name);
+ // Find position for the Label when looked up for output via "format"
+ int label_position();
+ // Find position for the Method when looked up for output via "format"
+ int method_position();
+
+ void dump(); // output to stderr
+ void output(FILE *fp); // Output list of names to 'fp'
+
+ ComponentList();
+ ~ComponentList();
+};
+
+//------------------------------SourceForm-------------------------------------
+class SourceForm : public Form {
+private:
+
+public:
+ // Public Data
+ char *_code; // Buffer for storing code text
+
+ // Public Methods
+ SourceForm(char* code);
+ ~SourceForm();
+
+ virtual const char* classname() { return "SourceForm"; }
+
+ void dump(); // Debug printer
+ void output(FILE *fp); // Write output files
+};
+
+class HeaderForm : public SourceForm {
+public:
+ HeaderForm(char* code) : SourceForm(code) { }
+
+ virtual const char* classname() { return "HeaderForm"; }
+};
+
+class PreHeaderForm : public SourceForm {
+public:
+ PreHeaderForm(char* code) : SourceForm(code) { }
+
+ virtual const char* classname() { return "PreHeaderForm"; }
+};
+
+
+
+
+//------------------------------Expr------------------------------------------
+#define STRING_BUFFER_LENGTH 2048
+// class Expr represents integer expressions containing constants and addition
+// Value must be in range zero through maximum positive integer. 32bits.
+// Expected use: instruction and operand costs
+class Expr {
+public:
+ enum {
+ Zero = 0,
+ Max = 0x7fffffff
+ };
+ const char *_external_name; // if !NULL, then print this instead of _expr
+ const char *_expr;
+ int _min_value;
+ int _max_value;
+
+ Expr();
+ Expr(const char *cost);
+ Expr(const char *name, const char *expression, int min_value, int max_value);
+ Expr *clone() const;
+
+ bool is_unknown() const { return (this == Expr::get_unknown()); }
+ bool is_zero() const { return (_min_value == Expr::Zero && _max_value == Expr::Zero); }
+ bool less_than_or_equal(const Expr *c) const { return (_max_value <= c->_min_value); }
+
+ void add(const Expr *c);
+ void add(const char *c);
+ void add(const char *c, ArchDesc &AD); // check if 'c' is defined in <arch>.ad
+ void set_external_name(const char *name) { _external_name = name; }
+
+ const char *as_string() const { return (_external_name != NULL ? _external_name : _expr); }
+ void print() const;
+ void print_define(FILE *fp) const;
+ void print_assert(FILE *fp) const;
+
+ static Expr *get_unknown(); // Returns pointer to shared unknown cost instance
+
+ static char *buffer() { return &external_buffer[0]; }
+ static bool init_buffers(); // Fill buffers with 0
+ static bool check_buffers(); // if buffer use may have overflowed, assert
+
+private:
+ static Expr *_unknown_expr;
+ static char string_buffer[STRING_BUFFER_LENGTH];
+ static char external_buffer[STRING_BUFFER_LENGTH];
+ static bool _init_buffers;
+ const char *compute_expr(const Expr *c1, const Expr *c2); // cost as string after adding 'c1' and 'c2'
+ int compute_min (const Expr *c1, const Expr *c2); // minimum after adding 'c1' and 'c2'
+ int compute_max (const Expr *c1, const Expr *c2); // maximum after adding 'c1' and 'c2'
+ const char *compute_external(const Expr *c1, const Expr *c2); // external name after adding 'c1' and 'c2'
+};
+
+//------------------------------ExprDict---------------------------------------
+// Dictionary containing Exprs
+class ExprDict {
+private:
+ Dict _expr; // map names, char*, to their Expr* or NULL
+ NameList _defines; // record the order of definitions entered with define call
+
+ // Disable public use of constructor, copy-ctor, operator =, operator ==
+ ExprDict( );
+ ExprDict( const ExprDict & ); // Deep-copy guts
+ ExprDict &operator =( const ExprDict & );
+ // == compares two dictionaries; they must have the same keys (their keys
+ // must match using CmpKey) and they must have the same values (pointer
+ // comparison). If so 1 is returned, if not 0 is returned.
+ bool operator ==(const ExprDict &d) const; // Compare dictionaries for equal
+
+public:
+ // cmp is a key comparision routine. hash is a routine to hash a key.
+ ExprDict( CmpKey cmp, Hash hash, Arena *arena );
+ ~ExprDict();
+
+ // Return # of key-value pairs in dict
+ int Size(void) const;
+
+ // define inserts the given key-value pair into the dictionary,
+ // and records the name in order for later output, ...
+ const Expr *define(const char *name, Expr *expr);
+
+ // Insert inserts the given key-value pair into the dictionary. The prior
+ // value of the key is returned; NULL if the key was not previously defined.
+ const Expr *Insert(const char *name, Expr *expr); // A new key-value
+
+ // Find finds the value of a given key; or NULL if not found.
+ // The dictionary is NOT changed.
+ const Expr *operator [](const char *name) const; // Do a lookup
+
+ void print_defines(FILE *fp);
+ void print_asserts(FILE *fp);
+ void dump();
+};