Mercurial > hg > graal-compiler
annotate src/share/vm/adlc/formsopt.cpp @ 1751:2528b5bd749c
6980262: Memory leak when exception is thrown in static initializer
Summary: Use resource memory instead of c-heap for the exception message
Reviewed-by: phh, jmasa
author | kamg |
---|---|
date | Fri, 27 Aug 2010 15:05:28 -0400 |
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 } |