Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/adlc/formsopt.cpp
32285 views
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
*/
24
25
// FORMS.CPP - Definitions for ADL Parser Forms Classes
26
#include "adlc.hpp"
27
28
//==============================Register Allocation============================
29
int RegisterForm::_reg_ctr = 0;
30
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
}
40
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
}
48
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
}
57
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);
62
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
}
70
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
}
82
83
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
}
90
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
}
100
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
}
111
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
}
117
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
}
123
124
125
// Check that register classes are compatible with chunks
126
bool RegisterForm::verify() {
127
bool valid = true;
128
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
138
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
}
151
152
return valid;
153
}
154
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
}
168
169
void RegisterForm::dump() { // Debug printer
170
output(stderr);
171
}
172
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
}
190
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) {
199
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
}
205
206
void RegDef::set_register_num(uint32 register_num) {
207
_register_num = register_num;
208
}
209
210
// Bit pattern used for generating machine code
211
const char* RegDef::register_encode() const {
212
return _register_encode;
213
}
214
215
// Register number used in machine-independent code
216
uint32 RegDef::register_num() const {
217
return _register_num;
218
}
219
220
void RegDef::dump() {
221
output(stderr);
222
}
223
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
}
229
230
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
}
235
236
RegClass::~RegClass() {
237
delete _classid;
238
}
239
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
}
245
246
// Number of registers in class
247
uint RegClass::size() const {
248
return _regDef.Size();
249
}
250
251
const RegDef *RegClass::get_RegDef(const char *rd_name) const {
252
return (const RegDef*)_regDef[rd_name];
253
}
254
255
void RegClass::reset() {
256
_regDefs.reset();
257
}
258
259
const char *RegClass::rd_name_iter() {
260
return _regDefs.iter();
261
}
262
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
}
268
269
const RegDef* RegClass::find_first_elem() {
270
const RegDef* first = NULL;
271
const RegDef* def = NULL;
272
273
reset();
274
while ((def = RegDef_iter()) != NULL) {
275
if (first == NULL || def->register_num() < first->register_num()) {
276
first = def;
277
}
278
}
279
280
assert(first != NULL, "empty mask?");
281
return first;;
282
}
283
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
}
299
300
return word;
301
}
302
303
void RegClass::dump() {
304
output(stderr);
305
}
306
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
}
315
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
}
327
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);
333
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));
339
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
}
349
350
//------------------------------CodeSnippetRegClass---------------------------
351
CodeSnippetRegClass::CodeSnippetRegClass(const char* classid) : RegClass(classid), _code_snippet(NULL) {
352
}
353
354
CodeSnippetRegClass::~CodeSnippetRegClass() {
355
delete _code_snippet;
356
}
357
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
}
364
365
//------------------------------ConditionalRegClass---------------------------
366
ConditionalRegClass::ConditionalRegClass(const char *classid) : RegClass(classid), _condition_code(NULL) {
367
}
368
369
ConditionalRegClass::~ConditionalRegClass() {
370
delete _condition_code;
371
}
372
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
}
401
402
//------------------------------AllocClass-------------------------------------
403
AllocClass::AllocClass(char *classid) : _classid(classid), _regDef(cmpstr,hashstr, Form::arena) {
404
}
405
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
}
414
415
void AllocClass::dump() {
416
output(stderr);
417
}
418
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
}
427
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
}
444
445
FrameForm::~FrameForm() {
446
}
447
448
void FrameForm::dump() {
449
output(stderr);
450
}
451
452
void FrameForm::output(FILE *fp) { // Write info to output files
453
fprintf(fp,"\nFrame:\n");
454
}
455
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
}
481
482
void PipelineForm::dump() {
483
output(stderr);
484
}
485
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;
492
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);
516
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");
521
522
fprintf(fp,"\nDescription:\n");
523
for ( _stages.reset(); (stage = _stages.iter()) != NULL; )
524
fprintf(fp," %s(%d)", stage, count++);
525
fprintf(fp,"\n");
526
527
fprintf(fp,"\nClasses:\n");
528
for ( _classlist.reset(); (cls = _classlist.iter()) != NULL; )
529
_classdict[cls]->is_pipeclass()->output(fp);
530
531
fprintf(fp,"\nNop Instructions:");
532
for ( _noplist.reset(); (nop = _noplist.iter()) != NULL; )
533
fprintf(fp, " \"%s\"", nop);
534
fprintf(fp,"\n");
535
}
536
537
538
//------------------------------ResourceForm-----------------------------------
539
ResourceForm::ResourceForm(unsigned resmask)
540
: _resmask(resmask) {
541
}
542
ResourceForm::~ResourceForm() {
543
}
544
545
ResourceForm *ResourceForm::is_resource() const {
546
return (ResourceForm *)(this);
547
}
548
549
void ResourceForm::dump() {
550
output(stderr);
551
}
552
553
void ResourceForm::output(FILE *fp) { // Write info to output files
554
fprintf(fp, "resource: 0x%08x;\n", mask());
555
}
556
557
558
//------------------------------PipeClassOperandForm----------------------------------
559
560
void PipeClassOperandForm::dump() {
561
output(stderr);
562
}
563
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
}
576
577
578
//------------------------------PipeClassResourceForm----------------------------------
579
580
void PipeClassResourceForm::dump() {
581
output(stderr);
582
}
583
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
}
588
589
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
}
604
605
PipeClassForm::~PipeClassForm() {
606
}
607
608
PipeClassForm *PipeClassForm::is_pipeclass() const {
609
return (PipeClassForm *)(this);
610
}
611
612
void PipeClassForm::dump() {
613
output(stderr);
614
}
615
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
}
628
629
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
}
638
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
}
647
648
// Store the components of this peephole rule
649
void Peephole::add_match(PeepMatch *match) {
650
assert( _match == NULL, "fatal()" );
651
_match = match;
652
}
653
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
}
661
662
void Peephole::add_replace(PeepReplace *replace) {
663
assert( _replace == NULL, "fatal()" );
664
_replace = replace;
665
}
666
667
// class Peephole accessor methods are in the declaration.
668
669
670
void Peephole::dump() {
671
output(stderr);
672
}
673
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
}
682
683
//------------------------------PeepMatch--------------------------------------
684
PeepMatch::PeepMatch(char *rule) : _max_position(0), _rule(rule) {
685
}
686
PeepMatch::~PeepMatch() {
687
}
688
689
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;
694
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
}
700
701
// Access info about instructions in the peep-match rule
702
int PeepMatch::max_position() {
703
return _max_position;
704
}
705
706
const char *PeepMatch::instruction_name(int position) {
707
return _instrs.name(position);
708
}
709
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
}
717
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
}
724
725
// 'true' if current position in iteration is a placeholder, not matched.
726
bool PeepMatch::is_placeholder() {
727
return _instrs.current_is_signal();
728
}
729
730
731
void PeepMatch::dump() {
732
output(stderr);
733
}
734
735
void PeepMatch::output(FILE *fp) { // Write info to output files
736
fprintf(fp,"PeepMatch:\n");
737
}
738
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
}
746
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;
752
753
// Check remaining constraints in list
754
if( _next == NULL ) return false;
755
else return _next->constrains_instruction(position);
756
}
757
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
}
766
767
// Access the next constraint in the list
768
PeepConstraint *PeepConstraint::next() {
769
return _next;
770
}
771
772
773
void PeepConstraint::dump() {
774
output(stderr);
775
}
776
777
void PeepConstraint::output(FILE *fp) { // Write info to output files
778
fprintf(fp,"PeepConstraint:\n");
779
}
780
781
//------------------------------PeepReplace------------------------------------
782
PeepReplace::PeepReplace(char *rule) : _rule(rule) {
783
}
784
PeepReplace::~PeepReplace() {
785
}
786
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
}
798
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
}
815
816
817
818
void PeepReplace::dump() {
819
output(stderr);
820
}
821
822
void PeepReplace::output(FILE *fp) { // Write info to output files
823
fprintf(fp,"PeepReplace:\n");
824
}
825
826