1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/adlc/forms.cpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,369 @@ 1.4 +/* 1.5 + * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +// FORMS.CPP - Definitions for ADL Parser Generic & Utility Forms Classes 1.29 +#include "adlc.hpp" 1.30 + 1.31 +//------------------------------Static Initializers---------------------------- 1.32 +// allocate arena used by forms 1.33 +Arena *Form::arena = Form::generate_arena(); // = Form::generate_arena(); 1.34 +Arena *Form::generate_arena() { 1.35 + return (new Arena); 1.36 +} 1.37 + 1.38 +//------------------------------NameList--------------------------------------- 1.39 +// reserved user-defined string 1.40 +const char *NameList::_signal = "$$SIGNAL$$"; 1.41 +const char *NameList::_signal2 = "$$SIGNAL2$$"; 1.42 +const char *NameList::_signal3 = "$$SIGNAL3$$"; 1.43 + 1.44 +// Constructor and Destructor 1.45 +NameList::NameList() : _cur(0), _max(4), _iter(0), _justReset(true) { 1.46 + _names = (const char**)malloc(_max*sizeof(char*)); 1.47 +} 1.48 +NameList::~NameList() { 1.49 + // The following free is a double-free, and crashes the program: 1.50 + //free(_names); // not owner of strings 1.51 +} 1.52 + 1.53 +void NameList::addName(const char *name) { 1.54 + if (_cur == _max) _names =(const char**)realloc(_names,(_max *=2)*sizeof(char*)); 1.55 + _names[_cur++] = name; 1.56 +} 1.57 + 1.58 +void NameList::add_signal() { 1.59 + addName( _signal ); 1.60 +} 1.61 +void NameList::clear() { 1.62 + _cur = 0; 1.63 + _iter = 0; 1.64 + _justReset = true; 1.65 + // _max = 4; Already allocated 1.66 +} 1.67 + 1.68 +int NameList::count() const { return _cur; } 1.69 + 1.70 +void NameList::reset() { _iter = 0; _justReset = true;} 1.71 +const char *NameList::iter() { 1.72 + if (_justReset) {_justReset=false; return (_iter < _cur ? _names[_iter] : NULL);} 1.73 + else return (_iter <_cur-1 ? _names[++_iter] : NULL); 1.74 +} 1.75 +const char *NameList::current() { return (_iter < _cur ? _names[_iter] : NULL); } 1.76 +const char *NameList::peek(int skip) { return (_iter + skip < _cur ? _names[_iter + skip] : NULL); } 1.77 + 1.78 +// Return 'true' if current entry is signal 1.79 +bool NameList::current_is_signal() { 1.80 + const char *entry = current(); 1.81 + return is_signal(entry); 1.82 +} 1.83 + 1.84 +// Return true if entry is a signal 1.85 +bool NameList::is_signal(const char *entry) { 1.86 + return ( (strcmp(entry,NameList::_signal) == 0) ? true : false); 1.87 +} 1.88 + 1.89 +// Search for a name in the list 1.90 +bool NameList::search(const char *name) { 1.91 + const char *entry; 1.92 + for(reset(); (entry = iter()) != NULL; ) { 1.93 + if(!strcmp(entry,name)) return true; 1.94 + } 1.95 + return false; 1.96 +} 1.97 + 1.98 +// Return index of name in list 1.99 +int NameList::index(const char *name) { 1.100 + int cnt = 0; 1.101 + const char *entry; 1.102 + for(reset(); (entry = iter()) != NULL; ) { 1.103 + if(!strcmp(entry,name)) return cnt; 1.104 + cnt++; 1.105 + } 1.106 + return Not_in_list; 1.107 +} 1.108 + 1.109 +// Return name at index in list 1.110 +const char *NameList::name(intptr_t index) { 1.111 + return ( index < _cur ? _names[index] : NULL); 1.112 +} 1.113 + 1.114 +void NameList::dump() { output(stderr); } 1.115 + 1.116 +void NameList::output(FILE *fp) { 1.117 + fprintf(fp, "\n"); 1.118 + 1.119 + // Run iteration over all entries, independent of position of iterator. 1.120 + const char *name = NULL; 1.121 + int iter = 0; 1.122 + bool justReset = true; 1.123 + 1.124 + while( ( name = (justReset ? 1.125 + (justReset=false, (iter < _cur ? _names[iter] : NULL)) : 1.126 + (iter < _cur-1 ? _names[++iter] : NULL)) ) 1.127 + != NULL ) { 1.128 + fprintf( fp, " %s,\n", name); 1.129 + } 1.130 + fprintf(fp, "\n"); 1.131 +} 1.132 + 1.133 +//------------------------------NameAndList------------------------------------ 1.134 +// Storage for a name and an associated list of names 1.135 +NameAndList::NameAndList(char *name) : _name(name) { 1.136 +} 1.137 +NameAndList::~NameAndList() { 1.138 +} 1.139 + 1.140 +// Add to entries in list 1.141 +void NameAndList::add_entry(const char *entry) { 1.142 + _list.addName(entry); 1.143 +} 1.144 + 1.145 +// Access the name and its associated list. 1.146 +const char *NameAndList::name() const { return _name; } 1.147 +void NameAndList::reset() { _list.reset(); } 1.148 +const char *NameAndList::iter() { return _list.iter(); } 1.149 + 1.150 +// Return the "index" entry in the list, zero-based 1.151 +const char *NameAndList::operator[](int index) { 1.152 + assert( index >= 0, "Internal Error(): index less than 0."); 1.153 + 1.154 + _list.reset(); 1.155 + const char *entry = _list.iter(); 1.156 + // Iterate further if it isn't at index 0. 1.157 + for ( int position = 0; position != index; ++position ) { 1.158 + entry = _list.iter(); 1.159 + } 1.160 + 1.161 + return entry; 1.162 +} 1.163 + 1.164 + 1.165 +void NameAndList::dump() { output(stderr); } 1.166 +void NameAndList::output(FILE *fp) { 1.167 + fprintf(fp, "\n"); 1.168 + 1.169 + // Output the Name 1.170 + fprintf(fp, "Name == %s", (_name ? _name : "") ); 1.171 + 1.172 + // Output the associated list of names 1.173 + const char *name; 1.174 + fprintf(fp, " ("); 1.175 + for (reset(); (name = iter()) != NULL;) { 1.176 + fprintf(fp, " %s,\n", name); 1.177 + } 1.178 + fprintf(fp, ")"); 1.179 + fprintf(fp, "\n"); 1.180 +} 1.181 + 1.182 +//------------------------------Form------------------------------------------- 1.183 +OpClassForm *Form::is_opclass() const { 1.184 + return NULL; 1.185 +} 1.186 + 1.187 +OperandForm *Form::is_operand() const { 1.188 + return NULL; 1.189 +} 1.190 + 1.191 +InstructForm *Form::is_instruction() const { 1.192 + return NULL; 1.193 +} 1.194 + 1.195 +MachNodeForm *Form::is_machnode() const { 1.196 + return NULL; 1.197 +} 1.198 + 1.199 +AttributeForm *Form::is_attribute() const { 1.200 + return NULL; 1.201 +} 1.202 + 1.203 +Effect *Form::is_effect() const { 1.204 + return NULL; 1.205 +} 1.206 + 1.207 +ResourceForm *Form::is_resource() const { 1.208 + return NULL; 1.209 +} 1.210 + 1.211 +PipeClassForm *Form::is_pipeclass() const { 1.212 + return NULL; 1.213 +} 1.214 + 1.215 +Form::DataType Form::ideal_to_const_type(const char *name) const { 1.216 + if( name == NULL ) { return Form::none; } 1.217 + 1.218 + if (strcmp(name,"ConI")==0) return Form::idealI; 1.219 + if (strcmp(name,"ConP")==0) return Form::idealP; 1.220 + if (strcmp(name,"ConN")==0) return Form::idealN; 1.221 + if (strcmp(name,"ConNKlass")==0) return Form::idealNKlass; 1.222 + if (strcmp(name,"ConL")==0) return Form::idealL; 1.223 + if (strcmp(name,"ConF")==0) return Form::idealF; 1.224 + if (strcmp(name,"ConD")==0) return Form::idealD; 1.225 + if (strcmp(name,"Bool")==0) return Form::idealI; 1.226 + 1.227 + return Form::none; 1.228 +} 1.229 + 1.230 +Form::DataType Form::ideal_to_sReg_type(const char *name) const { 1.231 + if( name == NULL ) { return Form::none; } 1.232 + 1.233 + if (strcmp(name,"sRegI")==0) return Form::idealI; 1.234 + if (strcmp(name,"sRegP")==0) return Form::idealP; 1.235 + if (strcmp(name,"sRegF")==0) return Form::idealF; 1.236 + if (strcmp(name,"sRegD")==0) return Form::idealD; 1.237 + if (strcmp(name,"sRegL")==0) return Form::idealL; 1.238 + return Form::none; 1.239 +} 1.240 + 1.241 +Form::DataType Form::ideal_to_Reg_type(const char *name) const { 1.242 + if( name == NULL ) { return Form::none; } 1.243 + 1.244 + if (strcmp(name,"RegI")==0) return Form::idealI; 1.245 + if (strcmp(name,"RegP")==0) return Form::idealP; 1.246 + if (strcmp(name,"RegF")==0) return Form::idealF; 1.247 + if (strcmp(name,"RegD")==0) return Form::idealD; 1.248 + if (strcmp(name,"RegL")==0) return Form::idealL; 1.249 + 1.250 + return Form::none; 1.251 +} 1.252 + 1.253 +// True if 'opType', an ideal name, loads or stores. 1.254 +Form::DataType Form::is_load_from_memory(const char *opType) const { 1.255 + if( strcmp(opType,"LoadB")==0 ) return Form::idealB; 1.256 + if( strcmp(opType,"LoadUB")==0 ) return Form::idealB; 1.257 + if( strcmp(opType,"LoadUS")==0 ) return Form::idealC; 1.258 + if( strcmp(opType,"LoadD")==0 ) return Form::idealD; 1.259 + if( strcmp(opType,"LoadD_unaligned")==0 ) return Form::idealD; 1.260 + if( strcmp(opType,"LoadF")==0 ) return Form::idealF; 1.261 + if( strcmp(opType,"LoadI")==0 ) return Form::idealI; 1.262 + if( strcmp(opType,"LoadKlass")==0 ) return Form::idealP; 1.263 + if( strcmp(opType,"LoadNKlass")==0 ) return Form::idealNKlass; 1.264 + if( strcmp(opType,"LoadL")==0 ) return Form::idealL; 1.265 + if( strcmp(opType,"LoadL_unaligned")==0 ) return Form::idealL; 1.266 + if( strcmp(opType,"LoadPLocked")==0 ) return Form::idealP; 1.267 + if( strcmp(opType,"LoadP")==0 ) return Form::idealP; 1.268 + if( strcmp(opType,"LoadN")==0 ) return Form::idealN; 1.269 + if( strcmp(opType,"LoadRange")==0 ) return Form::idealI; 1.270 + if( strcmp(opType,"LoadS")==0 ) return Form::idealS; 1.271 + if( strcmp(opType,"LoadVector")==0 ) return Form::idealV; 1.272 + assert( strcmp(opType,"Load") != 0, "Must type Loads" ); 1.273 + return Form::none; 1.274 +} 1.275 + 1.276 +Form::DataType Form::is_store_to_memory(const char *opType) const { 1.277 + if( strcmp(opType,"StoreB")==0) return Form::idealB; 1.278 + if( strcmp(opType,"StoreCM")==0) return Form::idealB; 1.279 + if( strcmp(opType,"StoreC")==0) return Form::idealC; 1.280 + if( strcmp(opType,"StoreD")==0) return Form::idealD; 1.281 + if( strcmp(opType,"StoreF")==0) return Form::idealF; 1.282 + if( strcmp(opType,"StoreI")==0) return Form::idealI; 1.283 + if( strcmp(opType,"StoreL")==0) return Form::idealL; 1.284 + if( strcmp(opType,"StoreP")==0) return Form::idealP; 1.285 + if( strcmp(opType,"StoreN")==0) return Form::idealN; 1.286 + if( strcmp(opType,"StoreNKlass")==0) return Form::idealNKlass; 1.287 + if( strcmp(opType,"StoreVector")==0 ) return Form::idealV; 1.288 + assert( strcmp(opType,"Store") != 0, "Must type Stores" ); 1.289 + return Form::none; 1.290 +} 1.291 + 1.292 +Form::InterfaceType Form::interface_type(FormDict &globals) const { 1.293 + return Form::no_interface; 1.294 +} 1.295 + 1.296 +//------------------------------FormList--------------------------------------- 1.297 +// Destructor 1.298 +FormList::~FormList() { 1.299 + // // This list may not own its elements 1.300 + // Form *cur = _root; 1.301 + // Form *next = NULL; 1.302 + // for( ; (cur = next) != NULL; ) { 1.303 + // next = (Form *)cur->_next; 1.304 + // delete cur; 1.305 + // } 1.306 +}; 1.307 + 1.308 +//------------------------------FormDict--------------------------------------- 1.309 +// Constructor 1.310 +FormDict::FormDict( CmpKey cmp, Hash hash, Arena *arena ) 1.311 + : _form(cmp, hash, arena) { 1.312 +} 1.313 +FormDict::~FormDict() { 1.314 +} 1.315 + 1.316 +// Return # of name-Form pairs in dict 1.317 +int FormDict::Size(void) const { 1.318 + return _form.Size(); 1.319 +} 1.320 + 1.321 +// Insert inserts the given key-value pair into the dictionary. The prior 1.322 +// value of the key is returned; NULL if the key was not previously defined. 1.323 +const Form *FormDict::Insert(const char *name, Form *form) { 1.324 + return (Form*)_form.Insert((void*)name, (void*)form); 1.325 +} 1.326 + 1.327 +// Finds the value of a given key; or NULL if not found. 1.328 +// The dictionary is NOT changed. 1.329 +const Form *FormDict::operator [](const char *name) const { 1.330 + return (Form*)_form[name]; 1.331 +} 1.332 + 1.333 +//------------------------------FormDict::private------------------------------ 1.334 +// Disable public use of constructor, copy-ctor, operator =, operator == 1.335 +FormDict::FormDict( ) : _form(cmpkey,hashkey) { 1.336 + assert( false, "NotImplemented"); 1.337 +} 1.338 +FormDict::FormDict( const FormDict & fd) : _form(fd._form) { 1.339 +} 1.340 +FormDict &FormDict::operator =( const FormDict &rhs) { 1.341 + assert( false, "NotImplemented"); 1.342 + _form = rhs._form; 1.343 + return *this; 1.344 +} 1.345 +// == compares two dictionaries; they must have the same keys (their keys 1.346 +// must match using CmpKey) and they must have the same values (pointer 1.347 +// comparison). If so 1 is returned, if not 0 is returned. 1.348 +bool FormDict::operator ==(const FormDict &d) const { 1.349 + assert( false, "NotImplemented"); 1.350 + return false; 1.351 +} 1.352 + 1.353 +// Print out the dictionary contents as key-value pairs 1.354 +static void dumpkey (const void* key) { fprintf(stdout, "%s", (char*) key); } 1.355 +static void dumpform(const void* form) { fflush(stdout); ((Form*)form)->dump(); } 1.356 + 1.357 +void FormDict::dump() { 1.358 + _form.print(dumpkey, dumpform); 1.359 +} 1.360 + 1.361 +//------------------------------SourceForm------------------------------------- 1.362 +SourceForm::SourceForm(char* code) : _code(code) { }; // Constructor 1.363 +SourceForm::~SourceForm() { 1.364 +} 1.365 + 1.366 +void SourceForm::dump() { // Debug printer 1.367 + output(stderr); 1.368 +} 1.369 + 1.370 +void SourceForm::output(FILE *fp) { 1.371 + fprintf(fp,"\n//%s\n%s\n",classname(),(_code?_code:"")); 1.372 +}