Mon, 12 Aug 2019 18:30:40 +0300
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 | } |