Mercurial > hg > truffle
annotate src/share/vm/adlc/formsopt.cpp @ 1721:413ad0331a0c
6977924: Changes for 6975078 produce build error with certain gcc versions
Summary: The changes introduced for 6975078 assign badHeapOopVal to the _allocation field in the ResourceObj class. In 32 bit linux builds with certain versions of gcc this assignment will be flagged as an error while compiling allocation.cpp. In 32 bit builds the constant value badHeapOopVal (which is cast to an intptr_t) is negative. The _allocation field is typed as an unsigned intptr_t and gcc catches this as an error.
Reviewed-by: jcoomes, ysr, phh
author | johnc |
---|---|
date | Wed, 18 Aug 2010 10:59:06 -0700 |
parents | c18cbe5936b8 |
children | f95d63e2154a |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
603
diff
changeset
|
2 * Copyright (c) 1998, 2009, 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 | |
222 RegClass::RegClass(const char *classid) : _stack_or_reg(false), _classid(classid), _regDef(cmpstr,hashstr, Form::arena) { | |
223 } | |
224 | |
225 // record a register in this class | |
226 void RegClass::addReg(RegDef *regDef) { | |
227 _regDefs.addName(regDef->_regname); | |
228 _regDef.Insert((void*)regDef->_regname, regDef); | |
229 } | |
230 | |
231 // Number of registers in class | |
232 uint RegClass::size() const { | |
233 return _regDef.Size(); | |
234 } | |
235 | |
236 const RegDef *RegClass::get_RegDef(const char *rd_name) const { | |
237 return (const RegDef*)_regDef[rd_name]; | |
238 } | |
239 | |
240 void RegClass::reset() { | |
241 _regDefs.reset(); | |
242 } | |
243 | |
244 const char *RegClass::rd_name_iter() { | |
245 return _regDefs.iter(); | |
246 } | |
247 | |
248 RegDef *RegClass::RegDef_iter() { | |
249 const char *rd_name = rd_name_iter(); | |
250 RegDef *reg_def = rd_name ? (RegDef*)_regDef[rd_name] : NULL; | |
251 return reg_def; | |
252 } | |
253 | |
254 const RegDef* RegClass::find_first_elem() { | |
255 const RegDef* first = NULL; | |
256 const RegDef* def = NULL; | |
257 | |
258 reset(); | |
259 while ((def = RegDef_iter()) != NULL) { | |
260 if (first == NULL || def->register_num() < first->register_num()) { | |
261 first = def; | |
262 } | |
263 } | |
264 | |
265 assert(first != NULL, "empty mask?"); | |
266 return first;; | |
267 } | |
268 | |
269 // Collect all the registers in this register-word. One bit per register. | |
270 int RegClass::regs_in_word( int wordnum, bool stack_also ) { | |
271 int word = 0; | |
272 const char *name; | |
273 for(_regDefs.reset(); (name = _regDefs.iter()) != NULL;) { | |
274 int rnum = ((RegDef*)_regDef[name])->register_num(); | |
275 if( (rnum >> 5) == wordnum ) | |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
276 word |= (1 << (rnum & 31)); |
0 | 277 } |
278 if( stack_also ) { | |
279 // Now also collect stack bits | |
280 for( int i = 0; i < 32; i++ ) | |
281 if( wordnum*32+i >= RegisterForm::_reg_ctr ) | |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
282 word |= (1 << i); |
0 | 283 } |
284 | |
285 return word; | |
286 } | |
287 | |
288 void RegClass::dump() { | |
289 output(stderr); | |
290 } | |
291 | |
292 void RegClass::output(FILE *fp) { // Write info to output files | |
293 fprintf(fp,"RegClass: %s\n",_classid); | |
294 const char *name; | |
295 for(_regDefs.reset(); (name = _regDefs.iter()) != NULL;) { | |
296 ((RegDef*)_regDef[name])->output(fp); | |
297 } | |
298 fprintf(fp,"--- done with entries for reg_class %s\n\n",_classid); | |
299 } | |
300 | |
301 | |
302 //------------------------------AllocClass------------------------------------- | |
303 AllocClass::AllocClass(char *classid) : _classid(classid), _regDef(cmpstr,hashstr, Form::arena) { | |
304 } | |
305 | |
306 // record a register in this class | |
307 void AllocClass::addReg(RegDef *regDef) { | |
308 assert( regDef != NULL, "Can not add a NULL to an allocation class"); | |
309 regDef->set_register_num( RegisterForm::_reg_ctr++ ); | |
310 // Add regDef to this allocation class | |
311 _regDefs.addName(regDef->_regname); | |
312 _regDef.Insert((void*)regDef->_regname, regDef); | |
313 } | |
314 | |
315 void AllocClass::dump() { | |
316 output(stderr); | |
317 } | |
318 | |
319 void AllocClass::output(FILE *fp) { // Write info to output files | |
320 fprintf(fp,"AllocClass: %s \n",_classid); | |
321 const char *name; | |
322 for(_regDefs.reset(); (name = _regDefs.iter()) != NULL;) { | |
323 ((RegDef*)_regDef[name])->output(fp); | |
324 } | |
325 fprintf(fp,"--- done with entries for alloc_class %s\n\n",_classid); | |
326 } | |
327 | |
328 //==============================Frame Handling================================= | |
329 //------------------------------FrameForm-------------------------------------- | |
330 FrameForm::FrameForm() { | |
331 _frame_pointer = NULL; | |
332 _c_frame_pointer = NULL; | |
333 _alignment = NULL; | |
334 _return_addr = NULL; | |
335 _c_return_addr = NULL; | |
336 _in_preserve_slots = NULL; | |
337 _varargs_C_out_slots_killed = NULL; | |
338 _calling_convention = NULL; | |
339 _c_calling_convention = NULL; | |
340 _return_value = NULL; | |
341 _c_return_value = NULL; | |
342 _interpreter_frame_pointer_reg = NULL; | |
343 } | |
344 | |
345 FrameForm::~FrameForm() { | |
346 } | |
347 | |
348 void FrameForm::dump() { | |
349 output(stderr); | |
350 } | |
351 | |
352 void FrameForm::output(FILE *fp) { // Write info to output files | |
353 fprintf(fp,"\nFrame:\n"); | |
354 } | |
355 | |
356 //==============================Scheduling===================================== | |
357 //------------------------------PipelineForm----------------------------------- | |
358 PipelineForm::PipelineForm() | |
359 : _reslist () | |
360 , _resdict (cmpstr, hashstr, Form::arena) | |
361 , _classdict (cmpstr, hashstr, Form::arena) | |
362 , _rescount (0) | |
363 , _maxcycleused (0) | |
364 , _stages () | |
365 , _stagecnt (0) | |
366 , _classlist () | |
367 , _classcnt (0) | |
368 , _noplist () | |
369 , _nopcnt (0) | |
370 , _variableSizeInstrs (false) | |
371 , _branchHasDelaySlot (false) | |
372 , _maxInstrsPerBundle (0) | |
373 , _maxBundlesPerCycle (1) | |
374 , _instrUnitSize (0) | |
375 , _bundleUnitSize (0) | |
376 , _instrFetchUnitSize (0) | |
377 , _instrFetchUnits (0) { | |
378 } | |
379 PipelineForm::~PipelineForm() { | |
380 } | |
381 | |
382 void PipelineForm::dump() { | |
383 output(stderr); | |
384 } | |
385 | |
386 void PipelineForm::output(FILE *fp) { // Write info to output files | |
387 const char *res; | |
388 const char *stage; | |
389 const char *cls; | |
390 const char *nop; | |
391 int count = 0; | |
392 | |
393 fprintf(fp,"\nPipeline:"); | |
394 if (_variableSizeInstrs) | |
395 if (_instrUnitSize > 0) | |
396 fprintf(fp," variable-sized instructions in %d byte units", _instrUnitSize); | |
397 else | |
398 fprintf(fp," variable-sized instructions"); | |
399 else | |
400 if (_instrUnitSize > 0) | |
401 fprintf(fp," fixed-sized instructions of %d bytes", _instrUnitSize); | |
402 else if (_bundleUnitSize > 0) | |
403 fprintf(fp," fixed-sized bundles of %d bytes", _bundleUnitSize); | |
404 else | |
405 fprintf(fp," fixed-sized instructions"); | |
406 if (_branchHasDelaySlot) | |
407 fprintf(fp,", branch has delay slot"); | |
408 if (_maxInstrsPerBundle > 0) | |
409 fprintf(fp,", max of %d instruction%s in parallel", | |
410 _maxInstrsPerBundle, _maxInstrsPerBundle > 1 ? "s" : ""); | |
411 if (_maxBundlesPerCycle > 0) | |
412 fprintf(fp,", max of %d bundle%s in parallel", | |
413 _maxBundlesPerCycle, _maxBundlesPerCycle > 1 ? "s" : ""); | |
414 if (_instrFetchUnitSize > 0 && _instrFetchUnits) | |
415 fprintf(fp, ", fetch %d x % d bytes per cycle", _instrFetchUnits, _instrFetchUnitSize); | |
416 | |
417 fprintf(fp,"\nResource:"); | |
418 for ( _reslist.reset(); (res = _reslist.iter()) != NULL; ) | |
419 fprintf(fp," %s(0x%08x)", res, _resdict[res]->is_resource()->mask()); | |
420 fprintf(fp,"\n"); | |
421 | |
422 fprintf(fp,"\nDescription:\n"); | |
423 for ( _stages.reset(); (stage = _stages.iter()) != NULL; ) | |
424 fprintf(fp," %s(%d)", stage, count++); | |
425 fprintf(fp,"\n"); | |
426 | |
427 fprintf(fp,"\nClasses:\n"); | |
428 for ( _classlist.reset(); (cls = _classlist.iter()) != NULL; ) | |
429 _classdict[cls]->is_pipeclass()->output(fp); | |
430 | |
431 fprintf(fp,"\nNop Instructions:"); | |
432 for ( _noplist.reset(); (nop = _noplist.iter()) != NULL; ) | |
433 fprintf(fp, " \"%s\"", nop); | |
434 fprintf(fp,"\n"); | |
435 } | |
436 | |
437 | |
438 //------------------------------ResourceForm----------------------------------- | |
439 ResourceForm::ResourceForm(unsigned resmask) | |
440 : _resmask(resmask) { | |
441 } | |
442 ResourceForm::~ResourceForm() { | |
443 } | |
444 | |
445 ResourceForm *ResourceForm::is_resource() const { | |
446 return (ResourceForm *)(this); | |
447 } | |
448 | |
449 void ResourceForm::dump() { | |
450 output(stderr); | |
451 } | |
452 | |
453 void ResourceForm::output(FILE *fp) { // Write info to output files | |
454 fprintf(fp, "resource: 0x%08x;\n", mask()); | |
455 } | |
456 | |
457 | |
458 //------------------------------PipeClassOperandForm---------------------------------- | |
459 | |
460 void PipeClassOperandForm::dump() { | |
461 output(stderr); | |
462 } | |
463 | |
464 void PipeClassOperandForm::output(FILE *fp) { // Write info to output files | |
465 fprintf(stderr,"PipeClassOperandForm: %s", _stage); | |
466 fflush(stderr); | |
467 if (_more_instrs > 0) | |
468 fprintf(stderr,"+%d", _more_instrs); | |
469 fprintf(stderr," (%s)\n", _iswrite ? "write" : "read"); | |
470 fflush(stderr); | |
471 fprintf(fp,"PipeClassOperandForm: %s", _stage); | |
472 if (_more_instrs > 0) | |
473 fprintf(fp,"+%d", _more_instrs); | |
474 fprintf(fp," (%s)\n", _iswrite ? "write" : "read"); | |
475 } | |
476 | |
477 | |
478 //------------------------------PipeClassResourceForm---------------------------------- | |
479 | |
480 void PipeClassResourceForm::dump() { | |
481 output(stderr); | |
482 } | |
483 | |
484 void PipeClassResourceForm::output(FILE *fp) { // Write info to output files | |
485 fprintf(fp,"PipeClassResourceForm: %s at stage %s for %d cycles\n", | |
486 _resource, _stage, _cycles); | |
487 } | |
488 | |
489 | |
490 //------------------------------PipeClassForm---------------------------------- | |
491 PipeClassForm::PipeClassForm(const char *id, int num) | |
492 : _ident(id) | |
493 , _num(num) | |
494 , _localNames(cmpstr, hashstr, Form::arena) | |
495 , _localUsage(cmpstr, hashstr, Form::arena) | |
496 , _has_fixed_latency(0) | |
497 , _fixed_latency(0) | |
498 , _instruction_count(0) | |
499 , _has_multiple_bundles(false) | |
500 , _has_branch_delay_slot(false) | |
501 , _force_serialization(false) | |
502 , _may_have_no_code(false) { | |
503 } | |
504 | |
505 PipeClassForm::~PipeClassForm() { | |
506 } | |
507 | |
508 PipeClassForm *PipeClassForm::is_pipeclass() const { | |
509 return (PipeClassForm *)(this); | |
510 } | |
511 | |
512 void PipeClassForm::dump() { | |
513 output(stderr); | |
514 } | |
515 | |
516 void PipeClassForm::output(FILE *fp) { // Write info to output files | |
517 fprintf(fp,"PipeClassForm: #%03d", _num); | |
518 if (_ident) | |
519 fprintf(fp," \"%s\":", _ident); | |
520 if (_has_fixed_latency) | |
521 fprintf(fp," latency %d", _fixed_latency); | |
522 if (_force_serialization) | |
523 fprintf(fp, ", force serialization"); | |
524 if (_may_have_no_code) | |
525 fprintf(fp, ", may have no code"); | |
526 fprintf(fp, ", %d instruction%s\n", InstructionCount(), InstructionCount() != 1 ? "s" : ""); | |
527 } | |
528 | |
529 | |
530 //==============================Peephole Optimization========================== | |
531 int Peephole::_peephole_counter = 0; | |
532 //------------------------------Peephole--------------------------------------- | |
533 Peephole::Peephole() : _match(NULL), _constraint(NULL), _replace(NULL), _next(NULL) { | |
534 _peephole_number = _peephole_counter++; | |
535 } | |
536 Peephole::~Peephole() { | |
537 } | |
538 | |
539 // Append a peephole rule with the same root instruction | |
540 void Peephole::append_peephole(Peephole *next_peephole) { | |
541 if( _next == NULL ) { | |
542 _next = next_peephole; | |
543 } else { | |
544 _next->append_peephole( next_peephole ); | |
545 } | |
546 } | |
547 | |
548 // Store the components of this peephole rule | |
549 void Peephole::add_match(PeepMatch *match) { | |
550 assert( _match == NULL, "fatal()" ); | |
551 _match = match; | |
552 } | |
553 | |
554 void Peephole::append_constraint(PeepConstraint *next_constraint) { | |
555 if( _constraint == NULL ) { | |
556 _constraint = next_constraint; | |
557 } else { | |
558 _constraint->append( next_constraint ); | |
559 } | |
560 } | |
561 | |
562 void Peephole::add_replace(PeepReplace *replace) { | |
563 assert( _replace == NULL, "fatal()" ); | |
564 _replace = replace; | |
565 } | |
566 | |
567 // class Peephole accessor methods are in the declaration. | |
568 | |
569 | |
570 void Peephole::dump() { | |
571 output(stderr); | |
572 } | |
573 | |
574 void Peephole::output(FILE *fp) { // Write info to output files | |
575 fprintf(fp,"Peephole:\n"); | |
576 if( _match != NULL ) _match->output(fp); | |
577 if( _constraint != NULL ) _constraint->output(fp); | |
578 if( _replace != NULL ) _replace->output(fp); | |
579 // Output the next entry | |
580 if( _next ) _next->output(fp); | |
581 } | |
582 | |
583 //------------------------------PeepMatch-------------------------------------- | |
584 PeepMatch::PeepMatch(char *rule) : _max_position(0), _rule(rule) { | |
585 } | |
586 PeepMatch::~PeepMatch() { | |
587 } | |
588 | |
589 | |
590 // Insert info into the match-rule | |
591 void PeepMatch::add_instruction(int parent, int position, const char *name, | |
592 int input) { | |
593 if( position > _max_position ) _max_position = position; | |
594 | |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
595 _parent.addName((char*) (intptr_t) parent); |
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
596 _position.addName((char*) (intptr_t) position); |
0 | 597 _instrs.addName(name); |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
598 _input.addName((char*) (intptr_t) input); |
0 | 599 } |
600 | |
601 // Access info about instructions in the peep-match rule | |
602 int PeepMatch::max_position() { | |
603 return _max_position; | |
604 } | |
605 | |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
606 const char *PeepMatch::instruction_name(int position) { |
0 | 607 return _instrs.name(position); |
608 } | |
609 | |
610 // Iterate through all info on matched instructions | |
611 void PeepMatch::reset() { | |
612 _parent.reset(); | |
613 _position.reset(); | |
614 _instrs.reset(); | |
615 _input.reset(); | |
616 } | |
617 | |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
618 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
|
619 parent = (int) (intptr_t) _parent.iter(); |
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
620 position = (int) (intptr_t) _position.iter(); |
0 | 621 name = _instrs.iter(); |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
622 input = (int) (intptr_t) _input.iter(); |
0 | 623 } |
624 | |
625 // 'true' if current position in iteration is a placeholder, not matched. | |
626 bool PeepMatch::is_placeholder() { | |
627 return _instrs.current_is_signal(); | |
628 } | |
629 | |
630 | |
631 void PeepMatch::dump() { | |
632 output(stderr); | |
633 } | |
634 | |
635 void PeepMatch::output(FILE *fp) { // Write info to output files | |
636 fprintf(fp,"PeepMatch:\n"); | |
637 } | |
638 | |
639 //------------------------------PeepConstraint--------------------------------- | |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
640 PeepConstraint::PeepConstraint(int left_inst, char* left_op, char* relation, |
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
641 int right_inst, char* right_op) |
0 | 642 : _left_inst(left_inst), _left_op(left_op), _relation(relation), |
643 _right_inst(right_inst), _right_op(right_op), _next(NULL) {} | |
644 PeepConstraint::~PeepConstraint() { | |
645 } | |
646 | |
647 // Check if constraints use instruction at position | |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
648 bool PeepConstraint::constrains_instruction(int position) { |
0 | 649 // Check local instruction constraints |
650 if( _left_inst == position ) return true; | |
651 if( _right_inst == position ) return true; | |
652 | |
653 // Check remaining constraints in list | |
654 if( _next == NULL ) return false; | |
655 else return _next->constrains_instruction(position); | |
656 } | |
657 | |
658 // Add another constraint | |
659 void PeepConstraint::append(PeepConstraint *next_constraint) { | |
660 if( _next == NULL ) { | |
661 _next = next_constraint; | |
662 } else { | |
663 _next->append( next_constraint ); | |
664 } | |
665 } | |
666 | |
667 // Access the next constraint in the list | |
668 PeepConstraint *PeepConstraint::next() { | |
669 return _next; | |
670 } | |
671 | |
672 | |
673 void PeepConstraint::dump() { | |
674 output(stderr); | |
675 } | |
676 | |
677 void PeepConstraint::output(FILE *fp) { // Write info to output files | |
678 fprintf(fp,"PeepConstraint:\n"); | |
679 } | |
680 | |
681 //------------------------------PeepReplace------------------------------------ | |
682 PeepReplace::PeepReplace(char *rule) : _rule(rule) { | |
683 } | |
684 PeepReplace::~PeepReplace() { | |
685 } | |
686 | |
687 // Add contents of peepreplace | |
688 void PeepReplace::add_instruction(char *root) { | |
689 _instruction.addName(root); | |
690 _operand_inst_num.add_signal(); | |
691 _operand_op_name.add_signal(); | |
692 } | |
693 void PeepReplace::add_operand( int inst_num, char *inst_operand ) { | |
694 _instruction.add_signal(); | |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
695 _operand_inst_num.addName((char*) (intptr_t) inst_num); |
0 | 696 _operand_op_name.addName(inst_operand); |
697 } | |
698 | |
699 // Access contents of peepreplace | |
700 void PeepReplace::reset() { | |
701 _instruction.reset(); | |
702 _operand_inst_num.reset(); | |
703 _operand_op_name.reset(); | |
704 } | |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
705 void PeepReplace::next_instruction(const char* &inst){ |
0 | 706 inst = _instruction.iter(); |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
707 int inst_num = (int) (intptr_t) _operand_inst_num.iter(); |
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
708 const char* inst_operand = _operand_op_name.iter(); |
0 | 709 } |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
710 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
|
711 const char* inst = _instruction.iter(); |
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
712 inst_num = (int) (intptr_t) _operand_inst_num.iter(); |
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
713 inst_operand = _operand_op_name.iter(); |
0 | 714 } |
715 | |
716 | |
717 | |
718 void PeepReplace::dump() { | |
719 output(stderr); | |
720 } | |
721 | |
722 void PeepReplace::output(FILE *fp) { // Write info to output files | |
723 fprintf(fp,"PeepReplace:\n"); | |
724 } |