Mercurial > hg > truffle
annotate src/share/vm/adlc/formsopt.cpp @ 4530:6c6cb7be1324
bugfix
author | Christian Haeubl <christian.haeubl@oracle.com> |
---|---|
date | Wed, 08 Feb 2012 21:13:35 -0800 |
parents | db2e64ca2d5a |
children | 8c92982cbbc4 |
rev | line source |
---|---|
0 | 1 /* |
1972 | 2 * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. |
0 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
603
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
603
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
603
diff
changeset
|
21 * questions. |
0 | 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 RegClass *RegisterForm::addRegClass(const char *className) { | |
51 RegClass *regClass = new RegClass(className); | |
52 _rclasses.addName(className); | |
53 _regClass.Insert(className,regClass); | |
54 return regClass; | |
55 } | |
56 | |
57 // record a new register class | |
58 AllocClass *RegisterForm::addAllocClass(char *className) { | |
59 AllocClass *allocClass = new AllocClass(className); | |
60 _aclasses.addName(className); | |
61 _allocClass.Insert(className,allocClass); | |
62 return allocClass; | |
63 } | |
64 | |
65 // Called after parsing the Register block. Record the register class | |
66 // for spill-slots/regs. | |
67 void RegisterForm::addSpillRegClass() { | |
68 // Stack slots start at the next available even register number. | |
69 _reg_ctr = (_reg_ctr+1) & ~1; | |
70 const char *rc_name = "stack_slots"; | |
71 RegClass *reg_class = new RegClass(rc_name); | |
72 reg_class->_stack_or_reg = true; | |
73 _rclasses.addName(rc_name); | |
74 _regClass.Insert(rc_name,reg_class); | |
75 } | |
76 | |
77 | |
78 // Provide iteration over all register definitions | |
79 // in the order used by the register allocator | |
80 void RegisterForm::reset_RegDefs() { | |
81 _current_ac = NULL; | |
82 _aclasses.reset(); | |
83 } | |
84 | |
85 RegDef *RegisterForm::iter_RegDefs() { | |
86 // Check if we need to get the next AllocClass | |
87 if ( _current_ac == NULL ) { | |
88 const char *ac_name = _aclasses.iter(); | |
89 if( ac_name == NULL ) return NULL; // No more allocation classes | |
90 _current_ac = (AllocClass*)_allocClass[ac_name]; | |
91 _current_ac->_regDefs.reset(); | |
92 assert( _current_ac != NULL, "Name must match an allocation class"); | |
93 } | |
94 | |
95 const char *rd_name = _current_ac->_regDefs.iter(); | |
96 if( rd_name == NULL ) { | |
97 // At end of this allocation class, check the next | |
98 _current_ac = NULL; | |
99 return iter_RegDefs(); | |
100 } | |
101 RegDef *reg_def = (RegDef*)_current_ac->_regDef[rd_name]; | |
102 assert( reg_def != NULL, "Name must match a register definition"); | |
103 return reg_def; | |
104 } | |
105 | |
106 // return the register definition with name 'regName' | |
107 RegDef *RegisterForm::getRegDef(const char *regName) { | |
108 RegDef *regDef = (RegDef*)_regDef[regName]; | |
109 return regDef; | |
110 } | |
111 | |
112 // return the register class with name 'className' | |
113 RegClass *RegisterForm::getRegClass(const char *className) { | |
114 RegClass *regClass = (RegClass*)_regClass[className]; | |
115 return regClass; | |
116 } | |
117 | |
118 | |
119 // Check that register classes are compatible with chunks | |
120 bool RegisterForm::verify() { | |
121 bool valid = true; | |
122 | |
123 // Verify Register Classes | |
124 // check that each register class contains registers from one chunk | |
125 const char *rc_name = NULL; | |
126 _rclasses.reset(); | |
127 while ( (rc_name = _rclasses.iter()) != NULL ) { | |
128 // Check the chunk value for all registers in this class | |
129 RegClass *reg_class = getRegClass(rc_name); | |
130 assert( reg_class != NULL, "InternalError() no matching register class"); | |
131 } // end of RegClasses | |
132 | |
133 // Verify that every register has been placed into an allocation class | |
134 RegDef *reg_def = NULL; | |
135 reset_RegDefs(); | |
136 uint num_register_zero = 0; | |
137 while ( (reg_def = iter_RegDefs()) != NULL ) { | |
138 if( reg_def->register_num() == 0 ) ++num_register_zero; | |
139 } | |
140 if( num_register_zero > 1 ) { | |
141 fprintf(stderr, | |
142 "ERROR: More than one register has been assigned register-number 0.\n" | |
143 "Probably because a register has not been entered into an allocation class.\n"); | |
144 } | |
145 | |
146 return valid; | |
147 } | |
148 | |
149 // Compute RegMask size | |
150 int RegisterForm::RegMask_Size() { | |
151 // Need at least this many words | |
152 int words_for_regs = (_reg_ctr + 31)>>5; | |
153 // Add a few for incoming & outgoing arguments to calls. | |
154 // Round up to the next doubleword size. | |
155 return (words_for_regs + 2 + 1) & ~1; | |
156 } | |
157 | |
158 void RegisterForm::dump() { // Debug printer | |
159 output(stderr); | |
160 } | |
161 | |
162 void RegisterForm::output(FILE *fp) { // Write info to output files | |
163 const char *name; | |
164 fprintf(fp,"\n"); | |
165 fprintf(fp,"-------------------- Dump RegisterForm --------------------\n"); | |
166 for(_rdefs.reset(); (name = _rdefs.iter()) != NULL;) { | |
167 ((RegDef*)_regDef[name])->output(fp); | |
168 } | |
169 fprintf(fp,"\n"); | |
170 for (_rclasses.reset(); (name = _rclasses.iter()) != NULL;) { | |
171 ((RegClass*)_regClass[name])->output(fp); | |
172 } | |
173 fprintf(fp,"\n"); | |
174 for (_aclasses.reset(); (name = _aclasses.iter()) != NULL;) { | |
175 ((AllocClass*)_allocClass[name])->output(fp); | |
176 } | |
177 fprintf(fp,"-------------------- end RegisterForm --------------------\n"); | |
178 } | |
179 | |
180 //------------------------------RegDef----------------------------------------- | |
181 // Constructor | |
182 RegDef::RegDef(char *regname, char *callconv, char *c_conv, char * idealtype, char * encode, char * concrete) | |
183 : _regname(regname), _callconv(callconv), _c_conv(c_conv), | |
184 _idealtype(idealtype), | |
185 _register_encode(encode), | |
186 _concrete(concrete), | |
187 _register_num(0) { | |
188 | |
189 // Chunk and register mask are determined by the register number | |
190 // _register_num is set when registers are added to an allocation class | |
191 } | |
192 RegDef::~RegDef() { // Destructor | |
193 } | |
194 | |
195 void RegDef::set_register_num(uint32 register_num) { | |
196 _register_num = register_num; | |
197 } | |
198 | |
199 // Bit pattern used for generating machine code | |
200 const char* RegDef::register_encode() const { | |
201 return _register_encode; | |
202 } | |
203 | |
204 // Register number used in machine-independent code | |
205 uint32 RegDef::register_num() const { | |
206 return _register_num; | |
207 } | |
208 | |
209 void RegDef::dump() { | |
210 output(stderr); | |
211 } | |
212 | |
213 void RegDef::output(FILE *fp) { // Write info to output files | |
214 fprintf(fp,"RegDef: %s (%s) encode as %s using number %d\n", | |
215 _regname, (_callconv?_callconv:""), _register_encode, _register_num); | |
216 fprintf(fp,"\n"); | |
217 } | |
218 | |
219 | |
220 //------------------------------RegClass--------------------------------------- | |
221 // Construct a register class into which registers will be inserted | |
4121
db2e64ca2d5a
7090968: Allow adlc register class to depend on runtime conditions
roland
parents:
1972
diff
changeset
|
222 RegClass::RegClass(const char *classid) : _stack_or_reg(false), _classid(classid), _regDef(cmpstr,hashstr, Form::arena), |
db2e64ca2d5a
7090968: Allow adlc register class to depend on runtime conditions
roland
parents:
1972
diff
changeset
|
223 _user_defined(NULL) |
db2e64ca2d5a
7090968: Allow adlc register class to depend on runtime conditions
roland
parents:
1972
diff
changeset
|
224 { |
0 | 225 } |
226 | |
227 // record a register in this class | |
228 void RegClass::addReg(RegDef *regDef) { | |
229 _regDefs.addName(regDef->_regname); | |
230 _regDef.Insert((void*)regDef->_regname, regDef); | |
231 } | |
232 | |
233 // Number of registers in class | |
234 uint RegClass::size() const { | |
235 return _regDef.Size(); | |
236 } | |
237 | |
238 const RegDef *RegClass::get_RegDef(const char *rd_name) const { | |
239 return (const RegDef*)_regDef[rd_name]; | |
240 } | |
241 | |
242 void RegClass::reset() { | |
243 _regDefs.reset(); | |
244 } | |
245 | |
246 const char *RegClass::rd_name_iter() { | |
247 return _regDefs.iter(); | |
248 } | |
249 | |
250 RegDef *RegClass::RegDef_iter() { | |
251 const char *rd_name = rd_name_iter(); | |
252 RegDef *reg_def = rd_name ? (RegDef*)_regDef[rd_name] : NULL; | |
253 return reg_def; | |
254 } | |
255 | |
256 const RegDef* RegClass::find_first_elem() { | |
257 const RegDef* first = NULL; | |
258 const RegDef* def = NULL; | |
259 | |
260 reset(); | |
261 while ((def = RegDef_iter()) != NULL) { | |
262 if (first == NULL || def->register_num() < first->register_num()) { | |
263 first = def; | |
264 } | |
265 } | |
266 | |
267 assert(first != NULL, "empty mask?"); | |
268 return first;; | |
269 } | |
270 | |
271 // Collect all the registers in this register-word. One bit per register. | |
272 int RegClass::regs_in_word( int wordnum, bool stack_also ) { | |
273 int word = 0; | |
274 const char *name; | |
275 for(_regDefs.reset(); (name = _regDefs.iter()) != NULL;) { | |
276 int rnum = ((RegDef*)_regDef[name])->register_num(); | |
277 if( (rnum >> 5) == wordnum ) | |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
278 word |= (1 << (rnum & 31)); |
0 | 279 } |
280 if( stack_also ) { | |
281 // Now also collect stack bits | |
282 for( int i = 0; i < 32; i++ ) | |
283 if( wordnum*32+i >= RegisterForm::_reg_ctr ) | |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
284 word |= (1 << i); |
0 | 285 } |
286 | |
287 return word; | |
288 } | |
289 | |
290 void RegClass::dump() { | |
291 output(stderr); | |
292 } | |
293 | |
294 void RegClass::output(FILE *fp) { // Write info to output files | |
295 fprintf(fp,"RegClass: %s\n",_classid); | |
296 const char *name; | |
297 for(_regDefs.reset(); (name = _regDefs.iter()) != NULL;) { | |
298 ((RegDef*)_regDef[name])->output(fp); | |
299 } | |
300 fprintf(fp,"--- done with entries for reg_class %s\n\n",_classid); | |
301 } | |
302 | |
303 | |
304 //------------------------------AllocClass------------------------------------- | |
305 AllocClass::AllocClass(char *classid) : _classid(classid), _regDef(cmpstr,hashstr, Form::arena) { | |
306 } | |
307 | |
308 // record a register in this class | |
309 void AllocClass::addReg(RegDef *regDef) { | |
310 assert( regDef != NULL, "Can not add a NULL to an allocation class"); | |
311 regDef->set_register_num( RegisterForm::_reg_ctr++ ); | |
312 // Add regDef to this allocation class | |
313 _regDefs.addName(regDef->_regname); | |
314 _regDef.Insert((void*)regDef->_regname, regDef); | |
315 } | |
316 | |
317 void AllocClass::dump() { | |
318 output(stderr); | |
319 } | |
320 | |
321 void AllocClass::output(FILE *fp) { // Write info to output files | |
322 fprintf(fp,"AllocClass: %s \n",_classid); | |
323 const char *name; | |
324 for(_regDefs.reset(); (name = _regDefs.iter()) != NULL;) { | |
325 ((RegDef*)_regDef[name])->output(fp); | |
326 } | |
327 fprintf(fp,"--- done with entries for alloc_class %s\n\n",_classid); | |
328 } | |
329 | |
330 //==============================Frame Handling================================= | |
331 //------------------------------FrameForm-------------------------------------- | |
332 FrameForm::FrameForm() { | |
333 _frame_pointer = NULL; | |
334 _c_frame_pointer = NULL; | |
335 _alignment = NULL; | |
336 _return_addr = NULL; | |
337 _c_return_addr = NULL; | |
338 _in_preserve_slots = NULL; | |
339 _varargs_C_out_slots_killed = NULL; | |
340 _calling_convention = NULL; | |
341 _c_calling_convention = NULL; | |
342 _return_value = NULL; | |
343 _c_return_value = NULL; | |
344 _interpreter_frame_pointer_reg = NULL; | |
345 } | |
346 | |
347 FrameForm::~FrameForm() { | |
348 } | |
349 | |
350 void FrameForm::dump() { | |
351 output(stderr); | |
352 } | |
353 | |
354 void FrameForm::output(FILE *fp) { // Write info to output files | |
355 fprintf(fp,"\nFrame:\n"); | |
356 } | |
357 | |
358 //==============================Scheduling===================================== | |
359 //------------------------------PipelineForm----------------------------------- | |
360 PipelineForm::PipelineForm() | |
361 : _reslist () | |
362 , _resdict (cmpstr, hashstr, Form::arena) | |
363 , _classdict (cmpstr, hashstr, Form::arena) | |
364 , _rescount (0) | |
365 , _maxcycleused (0) | |
366 , _stages () | |
367 , _stagecnt (0) | |
368 , _classlist () | |
369 , _classcnt (0) | |
370 , _noplist () | |
371 , _nopcnt (0) | |
372 , _variableSizeInstrs (false) | |
373 , _branchHasDelaySlot (false) | |
374 , _maxInstrsPerBundle (0) | |
375 , _maxBundlesPerCycle (1) | |
376 , _instrUnitSize (0) | |
377 , _bundleUnitSize (0) | |
378 , _instrFetchUnitSize (0) | |
379 , _instrFetchUnits (0) { | |
380 } | |
381 PipelineForm::~PipelineForm() { | |
382 } | |
383 | |
384 void PipelineForm::dump() { | |
385 output(stderr); | |
386 } | |
387 | |
388 void PipelineForm::output(FILE *fp) { // Write info to output files | |
389 const char *res; | |
390 const char *stage; | |
391 const char *cls; | |
392 const char *nop; | |
393 int count = 0; | |
394 | |
395 fprintf(fp,"\nPipeline:"); | |
396 if (_variableSizeInstrs) | |
397 if (_instrUnitSize > 0) | |
398 fprintf(fp," variable-sized instructions in %d byte units", _instrUnitSize); | |
399 else | |
400 fprintf(fp," variable-sized instructions"); | |
401 else | |
402 if (_instrUnitSize > 0) | |
403 fprintf(fp," fixed-sized instructions of %d bytes", _instrUnitSize); | |
404 else if (_bundleUnitSize > 0) | |
405 fprintf(fp," fixed-sized bundles of %d bytes", _bundleUnitSize); | |
406 else | |
407 fprintf(fp," fixed-sized instructions"); | |
408 if (_branchHasDelaySlot) | |
409 fprintf(fp,", branch has delay slot"); | |
410 if (_maxInstrsPerBundle > 0) | |
411 fprintf(fp,", max of %d instruction%s in parallel", | |
412 _maxInstrsPerBundle, _maxInstrsPerBundle > 1 ? "s" : ""); | |
413 if (_maxBundlesPerCycle > 0) | |
414 fprintf(fp,", max of %d bundle%s in parallel", | |
415 _maxBundlesPerCycle, _maxBundlesPerCycle > 1 ? "s" : ""); | |
416 if (_instrFetchUnitSize > 0 && _instrFetchUnits) | |
417 fprintf(fp, ", fetch %d x % d bytes per cycle", _instrFetchUnits, _instrFetchUnitSize); | |
418 | |
419 fprintf(fp,"\nResource:"); | |
420 for ( _reslist.reset(); (res = _reslist.iter()) != NULL; ) | |
421 fprintf(fp," %s(0x%08x)", res, _resdict[res]->is_resource()->mask()); | |
422 fprintf(fp,"\n"); | |
423 | |
424 fprintf(fp,"\nDescription:\n"); | |
425 for ( _stages.reset(); (stage = _stages.iter()) != NULL; ) | |
426 fprintf(fp," %s(%d)", stage, count++); | |
427 fprintf(fp,"\n"); | |
428 | |
429 fprintf(fp,"\nClasses:\n"); | |
430 for ( _classlist.reset(); (cls = _classlist.iter()) != NULL; ) | |
431 _classdict[cls]->is_pipeclass()->output(fp); | |
432 | |
433 fprintf(fp,"\nNop Instructions:"); | |
434 for ( _noplist.reset(); (nop = _noplist.iter()) != NULL; ) | |
435 fprintf(fp, " \"%s\"", nop); | |
436 fprintf(fp,"\n"); | |
437 } | |
438 | |
439 | |
440 //------------------------------ResourceForm----------------------------------- | |
441 ResourceForm::ResourceForm(unsigned resmask) | |
442 : _resmask(resmask) { | |
443 } | |
444 ResourceForm::~ResourceForm() { | |
445 } | |
446 | |
447 ResourceForm *ResourceForm::is_resource() const { | |
448 return (ResourceForm *)(this); | |
449 } | |
450 | |
451 void ResourceForm::dump() { | |
452 output(stderr); | |
453 } | |
454 | |
455 void ResourceForm::output(FILE *fp) { // Write info to output files | |
456 fprintf(fp, "resource: 0x%08x;\n", mask()); | |
457 } | |
458 | |
459 | |
460 //------------------------------PipeClassOperandForm---------------------------------- | |
461 | |
462 void PipeClassOperandForm::dump() { | |
463 output(stderr); | |
464 } | |
465 | |
466 void PipeClassOperandForm::output(FILE *fp) { // Write info to output files | |
467 fprintf(stderr,"PipeClassOperandForm: %s", _stage); | |
468 fflush(stderr); | |
469 if (_more_instrs > 0) | |
470 fprintf(stderr,"+%d", _more_instrs); | |
471 fprintf(stderr," (%s)\n", _iswrite ? "write" : "read"); | |
472 fflush(stderr); | |
473 fprintf(fp,"PipeClassOperandForm: %s", _stage); | |
474 if (_more_instrs > 0) | |
475 fprintf(fp,"+%d", _more_instrs); | |
476 fprintf(fp," (%s)\n", _iswrite ? "write" : "read"); | |
477 } | |
478 | |
479 | |
480 //------------------------------PipeClassResourceForm---------------------------------- | |
481 | |
482 void PipeClassResourceForm::dump() { | |
483 output(stderr); | |
484 } | |
485 | |
486 void PipeClassResourceForm::output(FILE *fp) { // Write info to output files | |
487 fprintf(fp,"PipeClassResourceForm: %s at stage %s for %d cycles\n", | |
488 _resource, _stage, _cycles); | |
489 } | |
490 | |
491 | |
492 //------------------------------PipeClassForm---------------------------------- | |
493 PipeClassForm::PipeClassForm(const char *id, int num) | |
494 : _ident(id) | |
495 , _num(num) | |
496 , _localNames(cmpstr, hashstr, Form::arena) | |
497 , _localUsage(cmpstr, hashstr, Form::arena) | |
498 , _has_fixed_latency(0) | |
499 , _fixed_latency(0) | |
500 , _instruction_count(0) | |
501 , _has_multiple_bundles(false) | |
502 , _has_branch_delay_slot(false) | |
503 , _force_serialization(false) | |
504 , _may_have_no_code(false) { | |
505 } | |
506 | |
507 PipeClassForm::~PipeClassForm() { | |
508 } | |
509 | |
510 PipeClassForm *PipeClassForm::is_pipeclass() const { | |
511 return (PipeClassForm *)(this); | |
512 } | |
513 | |
514 void PipeClassForm::dump() { | |
515 output(stderr); | |
516 } | |
517 | |
518 void PipeClassForm::output(FILE *fp) { // Write info to output files | |
519 fprintf(fp,"PipeClassForm: #%03d", _num); | |
520 if (_ident) | |
521 fprintf(fp," \"%s\":", _ident); | |
522 if (_has_fixed_latency) | |
523 fprintf(fp," latency %d", _fixed_latency); | |
524 if (_force_serialization) | |
525 fprintf(fp, ", force serialization"); | |
526 if (_may_have_no_code) | |
527 fprintf(fp, ", may have no code"); | |
528 fprintf(fp, ", %d instruction%s\n", InstructionCount(), InstructionCount() != 1 ? "s" : ""); | |
529 } | |
530 | |
531 | |
532 //==============================Peephole Optimization========================== | |
533 int Peephole::_peephole_counter = 0; | |
534 //------------------------------Peephole--------------------------------------- | |
535 Peephole::Peephole() : _match(NULL), _constraint(NULL), _replace(NULL), _next(NULL) { | |
536 _peephole_number = _peephole_counter++; | |
537 } | |
538 Peephole::~Peephole() { | |
539 } | |
540 | |
541 // Append a peephole rule with the same root instruction | |
542 void Peephole::append_peephole(Peephole *next_peephole) { | |
543 if( _next == NULL ) { | |
544 _next = next_peephole; | |
545 } else { | |
546 _next->append_peephole( next_peephole ); | |
547 } | |
548 } | |
549 | |
550 // Store the components of this peephole rule | |
551 void Peephole::add_match(PeepMatch *match) { | |
552 assert( _match == NULL, "fatal()" ); | |
553 _match = match; | |
554 } | |
555 | |
556 void Peephole::append_constraint(PeepConstraint *next_constraint) { | |
557 if( _constraint == NULL ) { | |
558 _constraint = next_constraint; | |
559 } else { | |
560 _constraint->append( next_constraint ); | |
561 } | |
562 } | |
563 | |
564 void Peephole::add_replace(PeepReplace *replace) { | |
565 assert( _replace == NULL, "fatal()" ); | |
566 _replace = replace; | |
567 } | |
568 | |
569 // class Peephole accessor methods are in the declaration. | |
570 | |
571 | |
572 void Peephole::dump() { | |
573 output(stderr); | |
574 } | |
575 | |
576 void Peephole::output(FILE *fp) { // Write info to output files | |
577 fprintf(fp,"Peephole:\n"); | |
578 if( _match != NULL ) _match->output(fp); | |
579 if( _constraint != NULL ) _constraint->output(fp); | |
580 if( _replace != NULL ) _replace->output(fp); | |
581 // Output the next entry | |
582 if( _next ) _next->output(fp); | |
583 } | |
584 | |
585 //------------------------------PeepMatch-------------------------------------- | |
586 PeepMatch::PeepMatch(char *rule) : _max_position(0), _rule(rule) { | |
587 } | |
588 PeepMatch::~PeepMatch() { | |
589 } | |
590 | |
591 | |
592 // Insert info into the match-rule | |
593 void PeepMatch::add_instruction(int parent, int position, const char *name, | |
594 int input) { | |
595 if( position > _max_position ) _max_position = position; | |
596 | |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
597 _parent.addName((char*) (intptr_t) parent); |
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
598 _position.addName((char*) (intptr_t) position); |
0 | 599 _instrs.addName(name); |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
600 _input.addName((char*) (intptr_t) input); |
0 | 601 } |
602 | |
603 // Access info about instructions in the peep-match rule | |
604 int PeepMatch::max_position() { | |
605 return _max_position; | |
606 } | |
607 | |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
608 const char *PeepMatch::instruction_name(int position) { |
0 | 609 return _instrs.name(position); |
610 } | |
611 | |
612 // Iterate through all info on matched instructions | |
613 void PeepMatch::reset() { | |
614 _parent.reset(); | |
615 _position.reset(); | |
616 _instrs.reset(); | |
617 _input.reset(); | |
618 } | |
619 | |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
620 void PeepMatch::next_instruction(int &parent, int &position, const char* &name, int &input) { |
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
621 parent = (int) (intptr_t) _parent.iter(); |
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
622 position = (int) (intptr_t) _position.iter(); |
0 | 623 name = _instrs.iter(); |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
624 input = (int) (intptr_t) _input.iter(); |
0 | 625 } |
626 | |
627 // 'true' if current position in iteration is a placeholder, not matched. | |
628 bool PeepMatch::is_placeholder() { | |
629 return _instrs.current_is_signal(); | |
630 } | |
631 | |
632 | |
633 void PeepMatch::dump() { | |
634 output(stderr); | |
635 } | |
636 | |
637 void PeepMatch::output(FILE *fp) { // Write info to output files | |
638 fprintf(fp,"PeepMatch:\n"); | |
639 } | |
640 | |
641 //------------------------------PeepConstraint--------------------------------- | |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
642 PeepConstraint::PeepConstraint(int left_inst, char* left_op, char* relation, |
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
643 int right_inst, char* right_op) |
0 | 644 : _left_inst(left_inst), _left_op(left_op), _relation(relation), |
645 _right_inst(right_inst), _right_op(right_op), _next(NULL) {} | |
646 PeepConstraint::~PeepConstraint() { | |
647 } | |
648 | |
649 // Check if constraints use instruction at position | |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
650 bool PeepConstraint::constrains_instruction(int position) { |
0 | 651 // Check local instruction constraints |
652 if( _left_inst == position ) return true; | |
653 if( _right_inst == position ) return true; | |
654 | |
655 // Check remaining constraints in list | |
656 if( _next == NULL ) return false; | |
657 else return _next->constrains_instruction(position); | |
658 } | |
659 | |
660 // Add another constraint | |
661 void PeepConstraint::append(PeepConstraint *next_constraint) { | |
662 if( _next == NULL ) { | |
663 _next = next_constraint; | |
664 } else { | |
665 _next->append( next_constraint ); | |
666 } | |
667 } | |
668 | |
669 // Access the next constraint in the list | |
670 PeepConstraint *PeepConstraint::next() { | |
671 return _next; | |
672 } | |
673 | |
674 | |
675 void PeepConstraint::dump() { | |
676 output(stderr); | |
677 } | |
678 | |
679 void PeepConstraint::output(FILE *fp) { // Write info to output files | |
680 fprintf(fp,"PeepConstraint:\n"); | |
681 } | |
682 | |
683 //------------------------------PeepReplace------------------------------------ | |
684 PeepReplace::PeepReplace(char *rule) : _rule(rule) { | |
685 } | |
686 PeepReplace::~PeepReplace() { | |
687 } | |
688 | |
689 // Add contents of peepreplace | |
690 void PeepReplace::add_instruction(char *root) { | |
691 _instruction.addName(root); | |
692 _operand_inst_num.add_signal(); | |
693 _operand_op_name.add_signal(); | |
694 } | |
695 void PeepReplace::add_operand( int inst_num, char *inst_operand ) { | |
696 _instruction.add_signal(); | |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
697 _operand_inst_num.addName((char*) (intptr_t) inst_num); |
0 | 698 _operand_op_name.addName(inst_operand); |
699 } | |
700 | |
701 // Access contents of peepreplace | |
702 void PeepReplace::reset() { | |
703 _instruction.reset(); | |
704 _operand_inst_num.reset(); | |
705 _operand_op_name.reset(); | |
706 } | |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
707 void PeepReplace::next_instruction(const char* &inst){ |
0 | 708 inst = _instruction.iter(); |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
709 int inst_num = (int) (intptr_t) _operand_inst_num.iter(); |
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
710 const char* inst_operand = _operand_op_name.iter(); |
0 | 711 } |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
712 void PeepReplace::next_operand(int &inst_num, const char* &inst_operand) { |
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
713 const char* inst = _instruction.iter(); |
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
714 inst_num = (int) (intptr_t) _operand_inst_num.iter(); |
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
715 inst_operand = _operand_op_name.iter(); |
0 | 716 } |
717 | |
718 | |
719 | |
720 void PeepReplace::dump() { | |
721 output(stderr); | |
722 } | |
723 | |
724 void PeepReplace::output(FILE *fp) { // Write info to output files | |
725 fprintf(fp,"PeepReplace:\n"); | |
726 } |