src/share/vm/adlc/formsopt.cpp

Mon, 12 Aug 2019 18:30:40 +0300

author
apetushkov
date
Mon, 12 Aug 2019 18:30:40 +0300
changeset 9858
b985cbb00e68
parent 7853
a1642365d69f
child 7994
04ff2f6cd0eb
permissions
-rw-r--r--

8223147: JFR Backport
8199712: Flight Recorder
8203346: JFR: Inconsistent signature of jfr_add_string_constant
8195817: JFR.stop should require name of recording
8195818: JFR.start should increase autogenerated name by one
8195819: Remove recording=x from jcmd JFR.check output
8203921: JFR thread sampling is missing fixes from JDK-8194552
8203929: Limit amount of data for JFR.dump
8203664: JFR start failure after AppCDS archive created with JFR StartFlightRecording
8003209: JFR events for network utilization
8207392: [PPC64] Implement JFR profiling
8202835: jfr/event/os/TestSystemProcess.java fails on missing events
Summary: Backport JFR from JDK11. Initial integration
Reviewed-by: neugens

duke@435 1 /*
kvn@3882 2 * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
duke@435 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@435 4 *
duke@435 5 * This code is free software; you can redistribute it and/or modify it
duke@435 6 * under the terms of the GNU General Public License version 2 only, as
duke@435 7 * published by the Free Software Foundation.
duke@435 8 *
duke@435 9 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@435 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@435 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@435 12 * version 2 for more details (a copy is included in the LICENSE file that
duke@435 13 * accompanied this code).
duke@435 14 *
duke@435 15 * You should have received a copy of the GNU General Public License version
duke@435 16 * 2 along with this work; if not, write to the Free Software Foundation,
duke@435 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@435 18 *
trims@1907 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@1907 20 * or visit www.oracle.com if you need additional information or have any
trims@1907 21 * questions.
duke@435 22 *
duke@435 23 */
duke@435 24
duke@435 25 // FORMS.CPP - Definitions for ADL Parser Forms Classes
duke@435 26 #include "adlc.hpp"
duke@435 27
duke@435 28 //==============================Register Allocation============================
duke@435 29 int RegisterForm::_reg_ctr = 0;
duke@435 30
duke@435 31 //------------------------------RegisterForm-----------------------------------
duke@435 32 // Constructor
duke@435 33 RegisterForm::RegisterForm()
duke@435 34 : _regDef(cmpstr,hashstr, Form::arena),
duke@435 35 _regClass(cmpstr,hashstr, Form::arena),
duke@435 36 _allocClass(cmpstr,hashstr, Form::arena) {
duke@435 37 }
duke@435 38 RegisterForm::~RegisterForm() {
duke@435 39 }
duke@435 40
duke@435 41 // record a new register definition
duke@435 42 void RegisterForm::addRegDef(char *name, char *callingConv, char *c_conv,
duke@435 43 char *idealtype, char *encoding, char* concrete) {
duke@435 44 RegDef *regDef = new RegDef(name, callingConv, c_conv, idealtype, encoding, concrete);
duke@435 45 _rdefs.addName(name);
duke@435 46 _regDef.Insert(name,regDef);
duke@435 47 }
duke@435 48
duke@435 49 // record a new register class
zmajo@7853 50 template <typename T>
zmajo@7853 51 T* RegisterForm::addRegClass(const char* className) {
zmajo@7853 52 T* regClass = new T(className);
duke@435 53 _rclasses.addName(className);
zmajo@7853 54 _regClass.Insert(className, regClass);
duke@435 55 return regClass;
duke@435 56 }
duke@435 57
zmajo@7853 58 // Explicit instantiation for all supported register classes.
zmajo@7853 59 template RegClass* RegisterForm::addRegClass<RegClass>(const char* className);
zmajo@7853 60 template CodeSnippetRegClass* RegisterForm::addRegClass<CodeSnippetRegClass>(const char* className);
zmajo@7853 61 template ConditionalRegClass* RegisterForm::addRegClass<ConditionalRegClass>(const char* className);
zmajo@7853 62
duke@435 63 // record a new register class
duke@435 64 AllocClass *RegisterForm::addAllocClass(char *className) {
duke@435 65 AllocClass *allocClass = new AllocClass(className);
duke@435 66 _aclasses.addName(className);
duke@435 67 _allocClass.Insert(className,allocClass);
duke@435 68 return allocClass;
duke@435 69 }
duke@435 70
duke@435 71 // Called after parsing the Register block. Record the register class
duke@435 72 // for spill-slots/regs.
duke@435 73 void RegisterForm::addSpillRegClass() {
duke@435 74 // Stack slots start at the next available even register number.
kvn@3882 75 _reg_ctr = (_reg_ctr+7) & ~7;
zmajo@7853 76 const char *rc_name = "stack_slots";
zmajo@7853 77 RegClass* reg_class = new RegClass(rc_name);
zmajo@7853 78 reg_class->set_stack_version(true);
duke@435 79 _rclasses.addName(rc_name);
duke@435 80 _regClass.Insert(rc_name,reg_class);
duke@435 81 }
duke@435 82
duke@435 83
duke@435 84 // Provide iteration over all register definitions
duke@435 85 // in the order used by the register allocator
duke@435 86 void RegisterForm::reset_RegDefs() {
duke@435 87 _current_ac = NULL;
duke@435 88 _aclasses.reset();
duke@435 89 }
duke@435 90
duke@435 91 RegDef *RegisterForm::iter_RegDefs() {
duke@435 92 // Check if we need to get the next AllocClass
duke@435 93 if ( _current_ac == NULL ) {
duke@435 94 const char *ac_name = _aclasses.iter();
duke@435 95 if( ac_name == NULL ) return NULL; // No more allocation classes
duke@435 96 _current_ac = (AllocClass*)_allocClass[ac_name];
duke@435 97 _current_ac->_regDefs.reset();
duke@435 98 assert( _current_ac != NULL, "Name must match an allocation class");
duke@435 99 }
duke@435 100
duke@435 101 const char *rd_name = _current_ac->_regDefs.iter();
duke@435 102 if( rd_name == NULL ) {
duke@435 103 // At end of this allocation class, check the next
duke@435 104 _current_ac = NULL;
duke@435 105 return iter_RegDefs();
duke@435 106 }
duke@435 107 RegDef *reg_def = (RegDef*)_current_ac->_regDef[rd_name];
duke@435 108 assert( reg_def != NULL, "Name must match a register definition");
duke@435 109 return reg_def;
duke@435 110 }
duke@435 111
duke@435 112 // return the register definition with name 'regName'
duke@435 113 RegDef *RegisterForm::getRegDef(const char *regName) {
duke@435 114 RegDef *regDef = (RegDef*)_regDef[regName];
duke@435 115 return regDef;
duke@435 116 }
duke@435 117
duke@435 118 // return the register class with name 'className'
duke@435 119 RegClass *RegisterForm::getRegClass(const char *className) {
duke@435 120 RegClass *regClass = (RegClass*)_regClass[className];
duke@435 121 return regClass;
duke@435 122 }
duke@435 123
duke@435 124
duke@435 125 // Check that register classes are compatible with chunks
duke@435 126 bool RegisterForm::verify() {
duke@435 127 bool valid = true;
duke@435 128
duke@435 129 // Verify Register Classes
duke@435 130 // check that each register class contains registers from one chunk
duke@435 131 const char *rc_name = NULL;
duke@435 132 _rclasses.reset();
duke@435 133 while ( (rc_name = _rclasses.iter()) != NULL ) {
duke@435 134 // Check the chunk value for all registers in this class
duke@435 135 RegClass *reg_class = getRegClass(rc_name);
duke@435 136 assert( reg_class != NULL, "InternalError() no matching register class");
duke@435 137 } // end of RegClasses
duke@435 138
duke@435 139 // Verify that every register has been placed into an allocation class
duke@435 140 RegDef *reg_def = NULL;
duke@435 141 reset_RegDefs();
duke@435 142 uint num_register_zero = 0;
duke@435 143 while ( (reg_def = iter_RegDefs()) != NULL ) {
duke@435 144 if( reg_def->register_num() == 0 ) ++num_register_zero;
duke@435 145 }
duke@435 146 if( num_register_zero > 1 ) {
duke@435 147 fprintf(stderr,
duke@435 148 "ERROR: More than one register has been assigned register-number 0.\n"
duke@435 149 "Probably because a register has not been entered into an allocation class.\n");
duke@435 150 }
duke@435 151
duke@435 152 return valid;
duke@435 153 }
duke@435 154
duke@435 155 // Compute RegMask size
duke@435 156 int RegisterForm::RegMask_Size() {
duke@435 157 // Need at least this many words
duke@435 158 int words_for_regs = (_reg_ctr + 31)>>5;
kvn@3882 159 // The array of Register Mask bits should be large enough to cover
kvn@3882 160 // all the machine registers and all parameters that need to be passed
kvn@3882 161 // on the stack (stack registers) up to some interesting limit. Methods
kvn@3882 162 // that need more parameters will NOT be compiled. On Intel, the limit
kvn@3882 163 // is something like 90+ parameters.
kvn@3882 164 // Add a few (3 words == 96 bits) for incoming & outgoing arguments to calls.
duke@435 165 // Round up to the next doubleword size.
kvn@3882 166 return (words_for_regs + 3 + 1) & ~1;
duke@435 167 }
duke@435 168
duke@435 169 void RegisterForm::dump() { // Debug printer
duke@435 170 output(stderr);
duke@435 171 }
duke@435 172
duke@435 173 void RegisterForm::output(FILE *fp) { // Write info to output files
duke@435 174 const char *name;
duke@435 175 fprintf(fp,"\n");
duke@435 176 fprintf(fp,"-------------------- Dump RegisterForm --------------------\n");
duke@435 177 for(_rdefs.reset(); (name = _rdefs.iter()) != NULL;) {
duke@435 178 ((RegDef*)_regDef[name])->output(fp);
duke@435 179 }
duke@435 180 fprintf(fp,"\n");
duke@435 181 for (_rclasses.reset(); (name = _rclasses.iter()) != NULL;) {
duke@435 182 ((RegClass*)_regClass[name])->output(fp);
duke@435 183 }
duke@435 184 fprintf(fp,"\n");
duke@435 185 for (_aclasses.reset(); (name = _aclasses.iter()) != NULL;) {
duke@435 186 ((AllocClass*)_allocClass[name])->output(fp);
duke@435 187 }
duke@435 188 fprintf(fp,"-------------------- end RegisterForm --------------------\n");
duke@435 189 }
duke@435 190
duke@435 191 //------------------------------RegDef-----------------------------------------
duke@435 192 // Constructor
duke@435 193 RegDef::RegDef(char *regname, char *callconv, char *c_conv, char * idealtype, char * encode, char * concrete)
duke@435 194 : _regname(regname), _callconv(callconv), _c_conv(c_conv),
duke@435 195 _idealtype(idealtype),
duke@435 196 _register_encode(encode),
duke@435 197 _concrete(concrete),
duke@435 198 _register_num(0) {
duke@435 199
duke@435 200 // Chunk and register mask are determined by the register number
duke@435 201 // _register_num is set when registers are added to an allocation class
duke@435 202 }
duke@435 203 RegDef::~RegDef() { // Destructor
duke@435 204 }
duke@435 205
duke@435 206 void RegDef::set_register_num(uint32 register_num) {
duke@435 207 _register_num = register_num;
duke@435 208 }
duke@435 209
duke@435 210 // Bit pattern used for generating machine code
duke@435 211 const char* RegDef::register_encode() const {
duke@435 212 return _register_encode;
duke@435 213 }
duke@435 214
duke@435 215 // Register number used in machine-independent code
duke@435 216 uint32 RegDef::register_num() const {
duke@435 217 return _register_num;
duke@435 218 }
duke@435 219
duke@435 220 void RegDef::dump() {
duke@435 221 output(stderr);
duke@435 222 }
duke@435 223
duke@435 224 void RegDef::output(FILE *fp) { // Write info to output files
duke@435 225 fprintf(fp,"RegDef: %s (%s) encode as %s using number %d\n",
duke@435 226 _regname, (_callconv?_callconv:""), _register_encode, _register_num);
duke@435 227 fprintf(fp,"\n");
duke@435 228 }
duke@435 229
duke@435 230
duke@435 231 //------------------------------RegClass---------------------------------------
duke@435 232 // Construct a register class into which registers will be inserted
zmajo@7853 233 RegClass::RegClass(const char* classid) : _stack_or_reg(false), _classid(classid), _regDef(cmpstr, hashstr, Form::arena) {
zmajo@7853 234 }
zmajo@7853 235
zmajo@7853 236 RegClass::~RegClass() {
zmajo@7853 237 delete _classid;
duke@435 238 }
duke@435 239
duke@435 240 // record a register in this class
duke@435 241 void RegClass::addReg(RegDef *regDef) {
duke@435 242 _regDefs.addName(regDef->_regname);
duke@435 243 _regDef.Insert((void*)regDef->_regname, regDef);
duke@435 244 }
duke@435 245
duke@435 246 // Number of registers in class
duke@435 247 uint RegClass::size() const {
duke@435 248 return _regDef.Size();
duke@435 249 }
duke@435 250
duke@435 251 const RegDef *RegClass::get_RegDef(const char *rd_name) const {
duke@435 252 return (const RegDef*)_regDef[rd_name];
duke@435 253 }
duke@435 254
duke@435 255 void RegClass::reset() {
duke@435 256 _regDefs.reset();
duke@435 257 }
duke@435 258
duke@435 259 const char *RegClass::rd_name_iter() {
duke@435 260 return _regDefs.iter();
duke@435 261 }
duke@435 262
duke@435 263 RegDef *RegClass::RegDef_iter() {
duke@435 264 const char *rd_name = rd_name_iter();
duke@435 265 RegDef *reg_def = rd_name ? (RegDef*)_regDef[rd_name] : NULL;
duke@435 266 return reg_def;
duke@435 267 }
duke@435 268
duke@435 269 const RegDef* RegClass::find_first_elem() {
duke@435 270 const RegDef* first = NULL;
duke@435 271 const RegDef* def = NULL;
duke@435 272
duke@435 273 reset();
duke@435 274 while ((def = RegDef_iter()) != NULL) {
duke@435 275 if (first == NULL || def->register_num() < first->register_num()) {
duke@435 276 first = def;
duke@435 277 }
duke@435 278 }
duke@435 279
duke@435 280 assert(first != NULL, "empty mask?");
duke@435 281 return first;;
duke@435 282 }
duke@435 283
duke@435 284 // Collect all the registers in this register-word. One bit per register.
duke@435 285 int RegClass::regs_in_word( int wordnum, bool stack_also ) {
duke@435 286 int word = 0;
duke@435 287 const char *name;
duke@435 288 for(_regDefs.reset(); (name = _regDefs.iter()) != NULL;) {
duke@435 289 int rnum = ((RegDef*)_regDef[name])->register_num();
duke@435 290 if( (rnum >> 5) == wordnum )
twisti@1038 291 word |= (1 << (rnum & 31));
duke@435 292 }
duke@435 293 if( stack_also ) {
duke@435 294 // Now also collect stack bits
duke@435 295 for( int i = 0; i < 32; i++ )
duke@435 296 if( wordnum*32+i >= RegisterForm::_reg_ctr )
twisti@1038 297 word |= (1 << i);
duke@435 298 }
duke@435 299
duke@435 300 return word;
duke@435 301 }
duke@435 302
duke@435 303 void RegClass::dump() {
duke@435 304 output(stderr);
duke@435 305 }
duke@435 306
duke@435 307 void RegClass::output(FILE *fp) { // Write info to output files
duke@435 308 fprintf(fp,"RegClass: %s\n",_classid);
duke@435 309 const char *name;
duke@435 310 for(_regDefs.reset(); (name = _regDefs.iter()) != NULL;) {
duke@435 311 ((RegDef*)_regDef[name])->output(fp);
duke@435 312 }
duke@435 313 fprintf(fp,"--- done with entries for reg_class %s\n\n",_classid);
duke@435 314 }
duke@435 315
zmajo@7853 316 void RegClass::declare_register_masks(FILE* fp) {
zmajo@7853 317 const char* prefix = "";
zmajo@7853 318 const char* rc_name_to_upper = toUpper(_classid);
zmajo@7853 319 fprintf(fp, "extern const RegMask _%s%s_mask;\n", prefix, rc_name_to_upper);
zmajo@7853 320 fprintf(fp, "inline const RegMask &%s%s_mask() { return _%s%s_mask; }\n", prefix, rc_name_to_upper, prefix, rc_name_to_upper);
zmajo@7853 321 if (_stack_or_reg) {
zmajo@7853 322 fprintf(fp, "extern const RegMask _%sSTACK_OR_%s_mask;\n", prefix, rc_name_to_upper);
zmajo@7853 323 fprintf(fp, "inline const RegMask &%sSTACK_OR_%s_mask() { return _%sSTACK_OR_%s_mask; }\n", prefix, rc_name_to_upper, prefix, rc_name_to_upper);
zmajo@7853 324 }
zmajo@7853 325 delete[] rc_name_to_upper;
zmajo@7853 326 }
zmajo@7853 327
zmajo@7853 328 void RegClass::build_register_masks(FILE* fp) {
zmajo@7853 329 int len = RegisterForm::RegMask_Size();
zmajo@7853 330 const char *prefix = "";
zmajo@7853 331 const char* rc_name_to_upper = toUpper(_classid);
zmajo@7853 332 fprintf(fp, "const RegMask _%s%s_mask(", prefix, rc_name_to_upper);
zmajo@7853 333
zmajo@7853 334 int i;
zmajo@7853 335 for(i = 0; i < len - 1; i++) {
zmajo@7853 336 fprintf(fp," 0x%x,", regs_in_word(i, false));
zmajo@7853 337 }
zmajo@7853 338 fprintf(fp," 0x%x );\n", regs_in_word(i, false));
zmajo@7853 339
zmajo@7853 340 if (_stack_or_reg) {
zmajo@7853 341 fprintf(fp, "const RegMask _%sSTACK_OR_%s_mask(", prefix, rc_name_to_upper);
zmajo@7853 342 for(i = 0; i < len - 1; i++) {
zmajo@7853 343 fprintf(fp," 0x%x,", regs_in_word(i, true));
zmajo@7853 344 }
zmajo@7853 345 fprintf(fp," 0x%x );\n", regs_in_word(i, true));
zmajo@7853 346 }
zmajo@7853 347 delete[] rc_name_to_upper;
zmajo@7853 348 }
zmajo@7853 349
zmajo@7853 350 //------------------------------CodeSnippetRegClass---------------------------
zmajo@7853 351 CodeSnippetRegClass::CodeSnippetRegClass(const char* classid) : RegClass(classid), _code_snippet(NULL) {
zmajo@7853 352 }
zmajo@7853 353
zmajo@7853 354 CodeSnippetRegClass::~CodeSnippetRegClass() {
zmajo@7853 355 delete _code_snippet;
zmajo@7853 356 }
zmajo@7853 357
zmajo@7853 358 void CodeSnippetRegClass::declare_register_masks(FILE* fp) {
zmajo@7853 359 const char* prefix = "";
zmajo@7853 360 const char* rc_name_to_upper = toUpper(_classid);
zmajo@7853 361 fprintf(fp, "inline const RegMask &%s%s_mask() { %s }\n", prefix, rc_name_to_upper, _code_snippet);
zmajo@7853 362 delete[] rc_name_to_upper;
zmajo@7853 363 }
zmajo@7853 364
zmajo@7853 365 //------------------------------ConditionalRegClass---------------------------
zmajo@7853 366 ConditionalRegClass::ConditionalRegClass(const char *classid) : RegClass(classid), _condition_code(NULL) {
zmajo@7853 367 }
zmajo@7853 368
zmajo@7853 369 ConditionalRegClass::~ConditionalRegClass() {
zmajo@7853 370 delete _condition_code;
zmajo@7853 371 }
zmajo@7853 372
zmajo@7853 373 void ConditionalRegClass::declare_register_masks(FILE* fp) {
zmajo@7853 374 const char* prefix = "";
zmajo@7853 375 const char* rc_name_to_upper = toUpper(_classid);
zmajo@7853 376 const char* rclass_0_to_upper = toUpper(_rclasses[0]->_classid);
zmajo@7853 377 const char* rclass_1_to_upper = toUpper(_rclasses[1]->_classid);
zmajo@7853 378 fprintf(fp, "inline const RegMask &%s%s_mask() {"
zmajo@7853 379 " return (%s) ?"
zmajo@7853 380 " %s%s_mask() :"
zmajo@7853 381 " %s%s_mask(); }\n",
zmajo@7853 382 prefix, rc_name_to_upper,
zmajo@7853 383 _condition_code,
zmajo@7853 384 prefix, rclass_0_to_upper,
zmajo@7853 385 prefix, rclass_1_to_upper);
zmajo@7853 386 if (_stack_or_reg) {
zmajo@7853 387 fprintf(fp, "inline const RegMask &%sSTACK_OR_%s_mask() {"
zmajo@7853 388 " return (%s) ?"
zmajo@7853 389 " %sSTACK_OR_%s_mask() :"
zmajo@7853 390 " %sSTACK_OR_%s_mask(); }\n",
zmajo@7853 391 prefix, rc_name_to_upper,
zmajo@7853 392 _condition_code,
zmajo@7853 393 prefix, rclass_0_to_upper,
zmajo@7853 394 prefix, rclass_1_to_upper);
zmajo@7853 395 }
zmajo@7853 396 delete[] rc_name_to_upper;
zmajo@7853 397 delete[] rclass_0_to_upper;
zmajo@7853 398 delete[] rclass_1_to_upper;
zmajo@7853 399 return;
zmajo@7853 400 }
duke@435 401
duke@435 402 //------------------------------AllocClass-------------------------------------
duke@435 403 AllocClass::AllocClass(char *classid) : _classid(classid), _regDef(cmpstr,hashstr, Form::arena) {
duke@435 404 }
duke@435 405
duke@435 406 // record a register in this class
duke@435 407 void AllocClass::addReg(RegDef *regDef) {
duke@435 408 assert( regDef != NULL, "Can not add a NULL to an allocation class");
duke@435 409 regDef->set_register_num( RegisterForm::_reg_ctr++ );
duke@435 410 // Add regDef to this allocation class
duke@435 411 _regDefs.addName(regDef->_regname);
duke@435 412 _regDef.Insert((void*)regDef->_regname, regDef);
duke@435 413 }
duke@435 414
duke@435 415 void AllocClass::dump() {
duke@435 416 output(stderr);
duke@435 417 }
duke@435 418
duke@435 419 void AllocClass::output(FILE *fp) { // Write info to output files
duke@435 420 fprintf(fp,"AllocClass: %s \n",_classid);
duke@435 421 const char *name;
duke@435 422 for(_regDefs.reset(); (name = _regDefs.iter()) != NULL;) {
duke@435 423 ((RegDef*)_regDef[name])->output(fp);
duke@435 424 }
duke@435 425 fprintf(fp,"--- done with entries for alloc_class %s\n\n",_classid);
duke@435 426 }
duke@435 427
duke@435 428 //==============================Frame Handling=================================
duke@435 429 //------------------------------FrameForm--------------------------------------
duke@435 430 FrameForm::FrameForm() {
duke@435 431 _frame_pointer = NULL;
duke@435 432 _c_frame_pointer = NULL;
duke@435 433 _alignment = NULL;
duke@435 434 _return_addr = NULL;
duke@435 435 _c_return_addr = NULL;
duke@435 436 _in_preserve_slots = NULL;
duke@435 437 _varargs_C_out_slots_killed = NULL;
duke@435 438 _calling_convention = NULL;
duke@435 439 _c_calling_convention = NULL;
duke@435 440 _return_value = NULL;
duke@435 441 _c_return_value = NULL;
duke@435 442 _interpreter_frame_pointer_reg = NULL;
duke@435 443 }
duke@435 444
duke@435 445 FrameForm::~FrameForm() {
duke@435 446 }
duke@435 447
duke@435 448 void FrameForm::dump() {
duke@435 449 output(stderr);
duke@435 450 }
duke@435 451
duke@435 452 void FrameForm::output(FILE *fp) { // Write info to output files
duke@435 453 fprintf(fp,"\nFrame:\n");
duke@435 454 }
duke@435 455
duke@435 456 //==============================Scheduling=====================================
duke@435 457 //------------------------------PipelineForm-----------------------------------
duke@435 458 PipelineForm::PipelineForm()
duke@435 459 : _reslist ()
duke@435 460 , _resdict (cmpstr, hashstr, Form::arena)
duke@435 461 , _classdict (cmpstr, hashstr, Form::arena)
duke@435 462 , _rescount (0)
duke@435 463 , _maxcycleused (0)
duke@435 464 , _stages ()
duke@435 465 , _stagecnt (0)
duke@435 466 , _classlist ()
duke@435 467 , _classcnt (0)
duke@435 468 , _noplist ()
duke@435 469 , _nopcnt (0)
duke@435 470 , _variableSizeInstrs (false)
duke@435 471 , _branchHasDelaySlot (false)
duke@435 472 , _maxInstrsPerBundle (0)
duke@435 473 , _maxBundlesPerCycle (1)
duke@435 474 , _instrUnitSize (0)
duke@435 475 , _bundleUnitSize (0)
duke@435 476 , _instrFetchUnitSize (0)
duke@435 477 , _instrFetchUnits (0) {
duke@435 478 }
duke@435 479 PipelineForm::~PipelineForm() {
duke@435 480 }
duke@435 481
duke@435 482 void PipelineForm::dump() {
duke@435 483 output(stderr);
duke@435 484 }
duke@435 485
duke@435 486 void PipelineForm::output(FILE *fp) { // Write info to output files
duke@435 487 const char *res;
duke@435 488 const char *stage;
duke@435 489 const char *cls;
duke@435 490 const char *nop;
duke@435 491 int count = 0;
duke@435 492
duke@435 493 fprintf(fp,"\nPipeline:");
duke@435 494 if (_variableSizeInstrs)
duke@435 495 if (_instrUnitSize > 0)
duke@435 496 fprintf(fp," variable-sized instructions in %d byte units", _instrUnitSize);
duke@435 497 else
duke@435 498 fprintf(fp," variable-sized instructions");
duke@435 499 else
duke@435 500 if (_instrUnitSize > 0)
duke@435 501 fprintf(fp," fixed-sized instructions of %d bytes", _instrUnitSize);
duke@435 502 else if (_bundleUnitSize > 0)
duke@435 503 fprintf(fp," fixed-sized bundles of %d bytes", _bundleUnitSize);
duke@435 504 else
duke@435 505 fprintf(fp," fixed-sized instructions");
duke@435 506 if (_branchHasDelaySlot)
duke@435 507 fprintf(fp,", branch has delay slot");
duke@435 508 if (_maxInstrsPerBundle > 0)
duke@435 509 fprintf(fp,", max of %d instruction%s in parallel",
duke@435 510 _maxInstrsPerBundle, _maxInstrsPerBundle > 1 ? "s" : "");
duke@435 511 if (_maxBundlesPerCycle > 0)
duke@435 512 fprintf(fp,", max of %d bundle%s in parallel",
duke@435 513 _maxBundlesPerCycle, _maxBundlesPerCycle > 1 ? "s" : "");
duke@435 514 if (_instrFetchUnitSize > 0 && _instrFetchUnits)
duke@435 515 fprintf(fp, ", fetch %d x % d bytes per cycle", _instrFetchUnits, _instrFetchUnitSize);
duke@435 516
duke@435 517 fprintf(fp,"\nResource:");
duke@435 518 for ( _reslist.reset(); (res = _reslist.iter()) != NULL; )
duke@435 519 fprintf(fp," %s(0x%08x)", res, _resdict[res]->is_resource()->mask());
duke@435 520 fprintf(fp,"\n");
duke@435 521
duke@435 522 fprintf(fp,"\nDescription:\n");
duke@435 523 for ( _stages.reset(); (stage = _stages.iter()) != NULL; )
duke@435 524 fprintf(fp," %s(%d)", stage, count++);
duke@435 525 fprintf(fp,"\n");
duke@435 526
duke@435 527 fprintf(fp,"\nClasses:\n");
duke@435 528 for ( _classlist.reset(); (cls = _classlist.iter()) != NULL; )
duke@435 529 _classdict[cls]->is_pipeclass()->output(fp);
duke@435 530
duke@435 531 fprintf(fp,"\nNop Instructions:");
duke@435 532 for ( _noplist.reset(); (nop = _noplist.iter()) != NULL; )
duke@435 533 fprintf(fp, " \"%s\"", nop);
duke@435 534 fprintf(fp,"\n");
duke@435 535 }
duke@435 536
duke@435 537
duke@435 538 //------------------------------ResourceForm-----------------------------------
duke@435 539 ResourceForm::ResourceForm(unsigned resmask)
duke@435 540 : _resmask(resmask) {
duke@435 541 }
duke@435 542 ResourceForm::~ResourceForm() {
duke@435 543 }
duke@435 544
duke@435 545 ResourceForm *ResourceForm::is_resource() const {
duke@435 546 return (ResourceForm *)(this);
duke@435 547 }
duke@435 548
duke@435 549 void ResourceForm::dump() {
duke@435 550 output(stderr);
duke@435 551 }
duke@435 552
duke@435 553 void ResourceForm::output(FILE *fp) { // Write info to output files
duke@435 554 fprintf(fp, "resource: 0x%08x;\n", mask());
duke@435 555 }
duke@435 556
duke@435 557
duke@435 558 //------------------------------PipeClassOperandForm----------------------------------
duke@435 559
duke@435 560 void PipeClassOperandForm::dump() {
duke@435 561 output(stderr);
duke@435 562 }
duke@435 563
duke@435 564 void PipeClassOperandForm::output(FILE *fp) { // Write info to output files
duke@435 565 fprintf(stderr,"PipeClassOperandForm: %s", _stage);
duke@435 566 fflush(stderr);
duke@435 567 if (_more_instrs > 0)
duke@435 568 fprintf(stderr,"+%d", _more_instrs);
duke@435 569 fprintf(stderr," (%s)\n", _iswrite ? "write" : "read");
duke@435 570 fflush(stderr);
duke@435 571 fprintf(fp,"PipeClassOperandForm: %s", _stage);
duke@435 572 if (_more_instrs > 0)
duke@435 573 fprintf(fp,"+%d", _more_instrs);
duke@435 574 fprintf(fp," (%s)\n", _iswrite ? "write" : "read");
duke@435 575 }
duke@435 576
duke@435 577
duke@435 578 //------------------------------PipeClassResourceForm----------------------------------
duke@435 579
duke@435 580 void PipeClassResourceForm::dump() {
duke@435 581 output(stderr);
duke@435 582 }
duke@435 583
duke@435 584 void PipeClassResourceForm::output(FILE *fp) { // Write info to output files
duke@435 585 fprintf(fp,"PipeClassResourceForm: %s at stage %s for %d cycles\n",
duke@435 586 _resource, _stage, _cycles);
duke@435 587 }
duke@435 588
duke@435 589
duke@435 590 //------------------------------PipeClassForm----------------------------------
duke@435 591 PipeClassForm::PipeClassForm(const char *id, int num)
duke@435 592 : _ident(id)
duke@435 593 , _num(num)
duke@435 594 , _localNames(cmpstr, hashstr, Form::arena)
duke@435 595 , _localUsage(cmpstr, hashstr, Form::arena)
duke@435 596 , _has_fixed_latency(0)
duke@435 597 , _fixed_latency(0)
duke@435 598 , _instruction_count(0)
duke@435 599 , _has_multiple_bundles(false)
duke@435 600 , _has_branch_delay_slot(false)
duke@435 601 , _force_serialization(false)
duke@435 602 , _may_have_no_code(false) {
duke@435 603 }
duke@435 604
duke@435 605 PipeClassForm::~PipeClassForm() {
duke@435 606 }
duke@435 607
duke@435 608 PipeClassForm *PipeClassForm::is_pipeclass() const {
duke@435 609 return (PipeClassForm *)(this);
duke@435 610 }
duke@435 611
duke@435 612 void PipeClassForm::dump() {
duke@435 613 output(stderr);
duke@435 614 }
duke@435 615
duke@435 616 void PipeClassForm::output(FILE *fp) { // Write info to output files
duke@435 617 fprintf(fp,"PipeClassForm: #%03d", _num);
duke@435 618 if (_ident)
duke@435 619 fprintf(fp," \"%s\":", _ident);
duke@435 620 if (_has_fixed_latency)
duke@435 621 fprintf(fp," latency %d", _fixed_latency);
duke@435 622 if (_force_serialization)
duke@435 623 fprintf(fp, ", force serialization");
duke@435 624 if (_may_have_no_code)
duke@435 625 fprintf(fp, ", may have no code");
duke@435 626 fprintf(fp, ", %d instruction%s\n", InstructionCount(), InstructionCount() != 1 ? "s" : "");
duke@435 627 }
duke@435 628
duke@435 629
duke@435 630 //==============================Peephole Optimization==========================
duke@435 631 int Peephole::_peephole_counter = 0;
duke@435 632 //------------------------------Peephole---------------------------------------
duke@435 633 Peephole::Peephole() : _match(NULL), _constraint(NULL), _replace(NULL), _next(NULL) {
duke@435 634 _peephole_number = _peephole_counter++;
duke@435 635 }
duke@435 636 Peephole::~Peephole() {
duke@435 637 }
duke@435 638
duke@435 639 // Append a peephole rule with the same root instruction
duke@435 640 void Peephole::append_peephole(Peephole *next_peephole) {
duke@435 641 if( _next == NULL ) {
duke@435 642 _next = next_peephole;
duke@435 643 } else {
duke@435 644 _next->append_peephole( next_peephole );
duke@435 645 }
duke@435 646 }
duke@435 647
duke@435 648 // Store the components of this peephole rule
duke@435 649 void Peephole::add_match(PeepMatch *match) {
duke@435 650 assert( _match == NULL, "fatal()" );
duke@435 651 _match = match;
duke@435 652 }
duke@435 653
duke@435 654 void Peephole::append_constraint(PeepConstraint *next_constraint) {
duke@435 655 if( _constraint == NULL ) {
duke@435 656 _constraint = next_constraint;
duke@435 657 } else {
duke@435 658 _constraint->append( next_constraint );
duke@435 659 }
duke@435 660 }
duke@435 661
duke@435 662 void Peephole::add_replace(PeepReplace *replace) {
duke@435 663 assert( _replace == NULL, "fatal()" );
duke@435 664 _replace = replace;
duke@435 665 }
duke@435 666
duke@435 667 // class Peephole accessor methods are in the declaration.
duke@435 668
duke@435 669
duke@435 670 void Peephole::dump() {
duke@435 671 output(stderr);
duke@435 672 }
duke@435 673
duke@435 674 void Peephole::output(FILE *fp) { // Write info to output files
duke@435 675 fprintf(fp,"Peephole:\n");
duke@435 676 if( _match != NULL ) _match->output(fp);
duke@435 677 if( _constraint != NULL ) _constraint->output(fp);
duke@435 678 if( _replace != NULL ) _replace->output(fp);
duke@435 679 // Output the next entry
duke@435 680 if( _next ) _next->output(fp);
duke@435 681 }
duke@435 682
duke@435 683 //------------------------------PeepMatch--------------------------------------
duke@435 684 PeepMatch::PeepMatch(char *rule) : _max_position(0), _rule(rule) {
duke@435 685 }
duke@435 686 PeepMatch::~PeepMatch() {
duke@435 687 }
duke@435 688
duke@435 689
duke@435 690 // Insert info into the match-rule
duke@435 691 void PeepMatch::add_instruction(int parent, int position, const char *name,
duke@435 692 int input) {
duke@435 693 if( position > _max_position ) _max_position = position;
duke@435 694
twisti@1038 695 _parent.addName((char*) (intptr_t) parent);
twisti@1038 696 _position.addName((char*) (intptr_t) position);
duke@435 697 _instrs.addName(name);
twisti@1038 698 _input.addName((char*) (intptr_t) input);
duke@435 699 }
duke@435 700
duke@435 701 // Access info about instructions in the peep-match rule
duke@435 702 int PeepMatch::max_position() {
duke@435 703 return _max_position;
duke@435 704 }
duke@435 705
twisti@1038 706 const char *PeepMatch::instruction_name(int position) {
duke@435 707 return _instrs.name(position);
duke@435 708 }
duke@435 709
duke@435 710 // Iterate through all info on matched instructions
duke@435 711 void PeepMatch::reset() {
duke@435 712 _parent.reset();
duke@435 713 _position.reset();
duke@435 714 _instrs.reset();
duke@435 715 _input.reset();
duke@435 716 }
duke@435 717
twisti@1038 718 void PeepMatch::next_instruction(int &parent, int &position, const char* &name, int &input) {
twisti@1038 719 parent = (int) (intptr_t) _parent.iter();
twisti@1038 720 position = (int) (intptr_t) _position.iter();
duke@435 721 name = _instrs.iter();
twisti@1038 722 input = (int) (intptr_t) _input.iter();
duke@435 723 }
duke@435 724
duke@435 725 // 'true' if current position in iteration is a placeholder, not matched.
duke@435 726 bool PeepMatch::is_placeholder() {
duke@435 727 return _instrs.current_is_signal();
duke@435 728 }
duke@435 729
duke@435 730
duke@435 731 void PeepMatch::dump() {
duke@435 732 output(stderr);
duke@435 733 }
duke@435 734
duke@435 735 void PeepMatch::output(FILE *fp) { // Write info to output files
duke@435 736 fprintf(fp,"PeepMatch:\n");
duke@435 737 }
duke@435 738
duke@435 739 //------------------------------PeepConstraint---------------------------------
twisti@1038 740 PeepConstraint::PeepConstraint(int left_inst, char* left_op, char* relation,
twisti@1038 741 int right_inst, char* right_op)
duke@435 742 : _left_inst(left_inst), _left_op(left_op), _relation(relation),
duke@435 743 _right_inst(right_inst), _right_op(right_op), _next(NULL) {}
duke@435 744 PeepConstraint::~PeepConstraint() {
duke@435 745 }
duke@435 746
duke@435 747 // Check if constraints use instruction at position
twisti@1038 748 bool PeepConstraint::constrains_instruction(int position) {
duke@435 749 // Check local instruction constraints
duke@435 750 if( _left_inst == position ) return true;
duke@435 751 if( _right_inst == position ) return true;
duke@435 752
duke@435 753 // Check remaining constraints in list
duke@435 754 if( _next == NULL ) return false;
duke@435 755 else return _next->constrains_instruction(position);
duke@435 756 }
duke@435 757
duke@435 758 // Add another constraint
duke@435 759 void PeepConstraint::append(PeepConstraint *next_constraint) {
duke@435 760 if( _next == NULL ) {
duke@435 761 _next = next_constraint;
duke@435 762 } else {
duke@435 763 _next->append( next_constraint );
duke@435 764 }
duke@435 765 }
duke@435 766
duke@435 767 // Access the next constraint in the list
duke@435 768 PeepConstraint *PeepConstraint::next() {
duke@435 769 return _next;
duke@435 770 }
duke@435 771
duke@435 772
duke@435 773 void PeepConstraint::dump() {
duke@435 774 output(stderr);
duke@435 775 }
duke@435 776
duke@435 777 void PeepConstraint::output(FILE *fp) { // Write info to output files
duke@435 778 fprintf(fp,"PeepConstraint:\n");
duke@435 779 }
duke@435 780
duke@435 781 //------------------------------PeepReplace------------------------------------
duke@435 782 PeepReplace::PeepReplace(char *rule) : _rule(rule) {
duke@435 783 }
duke@435 784 PeepReplace::~PeepReplace() {
duke@435 785 }
duke@435 786
duke@435 787 // Add contents of peepreplace
duke@435 788 void PeepReplace::add_instruction(char *root) {
duke@435 789 _instruction.addName(root);
duke@435 790 _operand_inst_num.add_signal();
duke@435 791 _operand_op_name.add_signal();
duke@435 792 }
duke@435 793 void PeepReplace::add_operand( int inst_num, char *inst_operand ) {
duke@435 794 _instruction.add_signal();
twisti@1038 795 _operand_inst_num.addName((char*) (intptr_t) inst_num);
duke@435 796 _operand_op_name.addName(inst_operand);
duke@435 797 }
duke@435 798
duke@435 799 // Access contents of peepreplace
duke@435 800 void PeepReplace::reset() {
duke@435 801 _instruction.reset();
duke@435 802 _operand_inst_num.reset();
duke@435 803 _operand_op_name.reset();
duke@435 804 }
twisti@1038 805 void PeepReplace::next_instruction(const char* &inst){
duke@435 806 inst = _instruction.iter();
twisti@1038 807 int inst_num = (int) (intptr_t) _operand_inst_num.iter();
twisti@1038 808 const char* inst_operand = _operand_op_name.iter();
duke@435 809 }
twisti@1038 810 void PeepReplace::next_operand(int &inst_num, const char* &inst_operand) {
twisti@1038 811 const char* inst = _instruction.iter();
twisti@1038 812 inst_num = (int) (intptr_t) _operand_inst_num.iter();
twisti@1038 813 inst_operand = _operand_op_name.iter();
duke@435 814 }
duke@435 815
duke@435 816
duke@435 817
duke@435 818 void PeepReplace::dump() {
duke@435 819 output(stderr);
duke@435 820 }
duke@435 821
duke@435 822 void PeepReplace::output(FILE *fp) { // Write info to output files
duke@435 823 fprintf(fp,"PeepReplace:\n");
duke@435 824 }

mercurial