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