Mercurial > hg > graal-compiler
diff src/share/vm/adlc/forms.hpp @ 0:a61af66fc99e jdk7-b24
Initial load
author | duke |
---|---|
date | Sat, 01 Dec 2007 00:00:00 +0000 |
parents | |
children | ba764ed4b6f2 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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(); +};