Mercurial > hg > truffle
annotate src/share/vm/adlc/formsopt.cpp @ 21936:49dad3e40b57
Convert addresses in ArrayCopyCallNode to word size
author | Stefan Anzinger <stefan.anzinger@oracle.com> |
---|---|
date | Fri, 12 Jun 2015 14:52:08 +0200 |
parents | 8c92982cbbc4 |
children |
rev | line source |
---|---|
0 | 1 /* |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
4121
diff
changeset
|
2 * Copyright (c) 1998, 2012, 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. | |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
4121
diff
changeset
|
69 _reg_ctr = (_reg_ctr+7) & ~7; |
0 | 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; | |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
4121
diff
changeset
|
153 // The array of Register Mask bits should be large enough to cover |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
4121
diff
changeset
|
154 // all the machine registers and all parameters that need to be passed |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
4121
diff
changeset
|
155 // on the stack (stack registers) up to some interesting limit. Methods |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
4121
diff
changeset
|
156 // that need more parameters will NOT be compiled. On Intel, the limit |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
4121
diff
changeset
|
157 // is something like 90+ parameters. |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
4121
diff
changeset
|
158 // Add a few (3 words == 96 bits) for incoming & outgoing arguments to calls. |
0 | 159 // Round up to the next doubleword size. |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
4121
diff
changeset
|
160 return (words_for_regs + 3 + 1) & ~1; |
0 | 161 } |
162 | |
163 void RegisterForm::dump() { // Debug printer | |
164 output(stderr); | |
165 } | |
166 | |
167 void RegisterForm::output(FILE *fp) { // Write info to output files | |
168 const char *name; | |
169 fprintf(fp,"\n"); | |
170 fprintf(fp,"-------------------- Dump RegisterForm --------------------\n"); | |
171 for(_rdefs.reset(); (name = _rdefs.iter()) != NULL;) { | |
172 ((RegDef*)_regDef[name])->output(fp); | |
173 } | |
174 fprintf(fp,"\n"); | |
175 for (_rclasses.reset(); (name = _rclasses.iter()) != NULL;) { | |
176 ((RegClass*)_regClass[name])->output(fp); | |
177 } | |
178 fprintf(fp,"\n"); | |
179 for (_aclasses.reset(); (name = _aclasses.iter()) != NULL;) { | |
180 ((AllocClass*)_allocClass[name])->output(fp); | |
181 } | |
182 fprintf(fp,"-------------------- end RegisterForm --------------------\n"); | |
183 } | |
184 | |
185 //------------------------------RegDef----------------------------------------- | |
186 // Constructor | |
187 RegDef::RegDef(char *regname, char *callconv, char *c_conv, char * idealtype, char * encode, char * concrete) | |
188 : _regname(regname), _callconv(callconv), _c_conv(c_conv), | |
189 _idealtype(idealtype), | |
190 _register_encode(encode), | |
191 _concrete(concrete), | |
192 _register_num(0) { | |
193 | |
194 // Chunk and register mask are determined by the register number | |
195 // _register_num is set when registers are added to an allocation class | |
196 } | |
197 RegDef::~RegDef() { // Destructor | |
198 } | |
199 | |
200 void RegDef::set_register_num(uint32 register_num) { | |
201 _register_num = register_num; | |
202 } | |
203 | |
204 // Bit pattern used for generating machine code | |
205 const char* RegDef::register_encode() const { | |
206 return _register_encode; | |
207 } | |
208 | |
209 // Register number used in machine-independent code | |
210 uint32 RegDef::register_num() const { | |
211 return _register_num; | |
212 } | |
213 | |
214 void RegDef::dump() { | |
215 output(stderr); | |
216 } | |
217 | |
218 void RegDef::output(FILE *fp) { // Write info to output files | |
219 fprintf(fp,"RegDef: %s (%s) encode as %s using number %d\n", | |
220 _regname, (_callconv?_callconv:""), _register_encode, _register_num); | |
221 fprintf(fp,"\n"); | |
222 } | |
223 | |
224 | |
225 //------------------------------RegClass--------------------------------------- | |
226 // 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
|
227 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
|
228 _user_defined(NULL) |
db2e64ca2d5a
7090968: Allow adlc register class to depend on runtime conditions
roland
parents:
1972
diff
changeset
|
229 { |
0 | 230 } |
231 | |
232 // record a register in this class | |
233 void RegClass::addReg(RegDef *regDef) { | |
234 _regDefs.addName(regDef->_regname); | |
235 _regDef.Insert((void*)regDef->_regname, regDef); | |
236 } | |
237 | |
238 // Number of registers in class | |
239 uint RegClass::size() const { | |
240 return _regDef.Size(); | |
241 } | |
242 | |
243 const RegDef *RegClass::get_RegDef(const char *rd_name) const { | |
244 return (const RegDef*)_regDef[rd_name]; | |
245 } | |
246 | |
247 void RegClass::reset() { | |
248 _regDefs.reset(); | |
249 } | |
250 | |
251 const char *RegClass::rd_name_iter() { | |
252 return _regDefs.iter(); | |
253 } | |
254 | |
255 RegDef *RegClass::RegDef_iter() { | |
256 const char *rd_name = rd_name_iter(); | |
257 RegDef *reg_def = rd_name ? (RegDef*)_regDef[rd_name] : NULL; | |
258 return reg_def; | |
259 } | |
260 | |
261 const RegDef* RegClass::find_first_elem() { | |
262 const RegDef* first = NULL; | |
263 const RegDef* def = NULL; | |
264 | |
265 reset(); | |
266 while ((def = RegDef_iter()) != NULL) { | |
267 if (first == NULL || def->register_num() < first->register_num()) { | |
268 first = def; | |
269 } | |
270 } | |
271 | |
272 assert(first != NULL, "empty mask?"); | |
273 return first;; | |
274 } | |
275 | |
276 // Collect all the registers in this register-word. One bit per register. | |
277 int RegClass::regs_in_word( int wordnum, bool stack_also ) { | |
278 int word = 0; | |
279 const char *name; | |
280 for(_regDefs.reset(); (name = _regDefs.iter()) != NULL;) { | |
281 int rnum = ((RegDef*)_regDef[name])->register_num(); | |
282 if( (rnum >> 5) == wordnum ) | |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
283 word |= (1 << (rnum & 31)); |
0 | 284 } |
285 if( stack_also ) { | |
286 // Now also collect stack bits | |
287 for( int i = 0; i < 32; i++ ) | |
288 if( wordnum*32+i >= RegisterForm::_reg_ctr ) | |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
289 word |= (1 << i); |
0 | 290 } |
291 | |
292 return word; | |
293 } | |
294 | |
295 void RegClass::dump() { | |
296 output(stderr); | |
297 } | |
298 | |
299 void RegClass::output(FILE *fp) { // Write info to output files | |
300 fprintf(fp,"RegClass: %s\n",_classid); | |
301 const char *name; | |
302 for(_regDefs.reset(); (name = _regDefs.iter()) != NULL;) { | |
303 ((RegDef*)_regDef[name])->output(fp); | |
304 } | |
305 fprintf(fp,"--- done with entries for reg_class %s\n\n",_classid); | |
306 } | |
307 | |
308 | |
309 //------------------------------AllocClass------------------------------------- | |
310 AllocClass::AllocClass(char *classid) : _classid(classid), _regDef(cmpstr,hashstr, Form::arena) { | |
311 } | |
312 | |
313 // record a register in this class | |
314 void AllocClass::addReg(RegDef *regDef) { | |
315 assert( regDef != NULL, "Can not add a NULL to an allocation class"); | |
316 regDef->set_register_num( RegisterForm::_reg_ctr++ ); | |
317 // Add regDef to this allocation class | |
318 _regDefs.addName(regDef->_regname); | |
319 _regDef.Insert((void*)regDef->_regname, regDef); | |
320 } | |
321 | |
322 void AllocClass::dump() { | |
323 output(stderr); | |
324 } | |
325 | |
326 void AllocClass::output(FILE *fp) { // Write info to output files | |
327 fprintf(fp,"AllocClass: %s \n",_classid); | |
328 const char *name; | |
329 for(_regDefs.reset(); (name = _regDefs.iter()) != NULL;) { | |
330 ((RegDef*)_regDef[name])->output(fp); | |
331 } | |
332 fprintf(fp,"--- done with entries for alloc_class %s\n\n",_classid); | |
333 } | |
334 | |
335 //==============================Frame Handling================================= | |
336 //------------------------------FrameForm-------------------------------------- | |
337 FrameForm::FrameForm() { | |
338 _frame_pointer = NULL; | |
339 _c_frame_pointer = NULL; | |
340 _alignment = NULL; | |
341 _return_addr = NULL; | |
342 _c_return_addr = NULL; | |
343 _in_preserve_slots = NULL; | |
344 _varargs_C_out_slots_killed = NULL; | |
345 _calling_convention = NULL; | |
346 _c_calling_convention = NULL; | |
347 _return_value = NULL; | |
348 _c_return_value = NULL; | |
349 _interpreter_frame_pointer_reg = NULL; | |
350 } | |
351 | |
352 FrameForm::~FrameForm() { | |
353 } | |
354 | |
355 void FrameForm::dump() { | |
356 output(stderr); | |
357 } | |
358 | |
359 void FrameForm::output(FILE *fp) { // Write info to output files | |
360 fprintf(fp,"\nFrame:\n"); | |
361 } | |
362 | |
363 //==============================Scheduling===================================== | |
364 //------------------------------PipelineForm----------------------------------- | |
365 PipelineForm::PipelineForm() | |
366 : _reslist () | |
367 , _resdict (cmpstr, hashstr, Form::arena) | |
368 , _classdict (cmpstr, hashstr, Form::arena) | |
369 , _rescount (0) | |
370 , _maxcycleused (0) | |
371 , _stages () | |
372 , _stagecnt (0) | |
373 , _classlist () | |
374 , _classcnt (0) | |
375 , _noplist () | |
376 , _nopcnt (0) | |
377 , _variableSizeInstrs (false) | |
378 , _branchHasDelaySlot (false) | |
379 , _maxInstrsPerBundle (0) | |
380 , _maxBundlesPerCycle (1) | |
381 , _instrUnitSize (0) | |
382 , _bundleUnitSize (0) | |
383 , _instrFetchUnitSize (0) | |
384 , _instrFetchUnits (0) { | |
385 } | |
386 PipelineForm::~PipelineForm() { | |
387 } | |
388 | |
389 void PipelineForm::dump() { | |
390 output(stderr); | |
391 } | |
392 | |
393 void PipelineForm::output(FILE *fp) { // Write info to output files | |
394 const char *res; | |
395 const char *stage; | |
396 const char *cls; | |
397 const char *nop; | |
398 int count = 0; | |
399 | |
400 fprintf(fp,"\nPipeline:"); | |
401 if (_variableSizeInstrs) | |
402 if (_instrUnitSize > 0) | |
403 fprintf(fp," variable-sized instructions in %d byte units", _instrUnitSize); | |
404 else | |
405 fprintf(fp," variable-sized instructions"); | |
406 else | |
407 if (_instrUnitSize > 0) | |
408 fprintf(fp," fixed-sized instructions of %d bytes", _instrUnitSize); | |
409 else if (_bundleUnitSize > 0) | |
410 fprintf(fp," fixed-sized bundles of %d bytes", _bundleUnitSize); | |
411 else | |
412 fprintf(fp," fixed-sized instructions"); | |
413 if (_branchHasDelaySlot) | |
414 fprintf(fp,", branch has delay slot"); | |
415 if (_maxInstrsPerBundle > 0) | |
416 fprintf(fp,", max of %d instruction%s in parallel", | |
417 _maxInstrsPerBundle, _maxInstrsPerBundle > 1 ? "s" : ""); | |
418 if (_maxBundlesPerCycle > 0) | |
419 fprintf(fp,", max of %d bundle%s in parallel", | |
420 _maxBundlesPerCycle, _maxBundlesPerCycle > 1 ? "s" : ""); | |
421 if (_instrFetchUnitSize > 0 && _instrFetchUnits) | |
422 fprintf(fp, ", fetch %d x % d bytes per cycle", _instrFetchUnits, _instrFetchUnitSize); | |
423 | |
424 fprintf(fp,"\nResource:"); | |
425 for ( _reslist.reset(); (res = _reslist.iter()) != NULL; ) | |
426 fprintf(fp," %s(0x%08x)", res, _resdict[res]->is_resource()->mask()); | |
427 fprintf(fp,"\n"); | |
428 | |
429 fprintf(fp,"\nDescription:\n"); | |
430 for ( _stages.reset(); (stage = _stages.iter()) != NULL; ) | |
431 fprintf(fp," %s(%d)", stage, count++); | |
432 fprintf(fp,"\n"); | |
433 | |
434 fprintf(fp,"\nClasses:\n"); | |
435 for ( _classlist.reset(); (cls = _classlist.iter()) != NULL; ) | |
436 _classdict[cls]->is_pipeclass()->output(fp); | |
437 | |
438 fprintf(fp,"\nNop Instructions:"); | |
439 for ( _noplist.reset(); (nop = _noplist.iter()) != NULL; ) | |
440 fprintf(fp, " \"%s\"", nop); | |
441 fprintf(fp,"\n"); | |
442 } | |
443 | |
444 | |
445 //------------------------------ResourceForm----------------------------------- | |
446 ResourceForm::ResourceForm(unsigned resmask) | |
447 : _resmask(resmask) { | |
448 } | |
449 ResourceForm::~ResourceForm() { | |
450 } | |
451 | |
452 ResourceForm *ResourceForm::is_resource() const { | |
453 return (ResourceForm *)(this); | |
454 } | |
455 | |
456 void ResourceForm::dump() { | |
457 output(stderr); | |
458 } | |
459 | |
460 void ResourceForm::output(FILE *fp) { // Write info to output files | |
461 fprintf(fp, "resource: 0x%08x;\n", mask()); | |
462 } | |
463 | |
464 | |
465 //------------------------------PipeClassOperandForm---------------------------------- | |
466 | |
467 void PipeClassOperandForm::dump() { | |
468 output(stderr); | |
469 } | |
470 | |
471 void PipeClassOperandForm::output(FILE *fp) { // Write info to output files | |
472 fprintf(stderr,"PipeClassOperandForm: %s", _stage); | |
473 fflush(stderr); | |
474 if (_more_instrs > 0) | |
475 fprintf(stderr,"+%d", _more_instrs); | |
476 fprintf(stderr," (%s)\n", _iswrite ? "write" : "read"); | |
477 fflush(stderr); | |
478 fprintf(fp,"PipeClassOperandForm: %s", _stage); | |
479 if (_more_instrs > 0) | |
480 fprintf(fp,"+%d", _more_instrs); | |
481 fprintf(fp," (%s)\n", _iswrite ? "write" : "read"); | |
482 } | |
483 | |
484 | |
485 //------------------------------PipeClassResourceForm---------------------------------- | |
486 | |
487 void PipeClassResourceForm::dump() { | |
488 output(stderr); | |
489 } | |
490 | |
491 void PipeClassResourceForm::output(FILE *fp) { // Write info to output files | |
492 fprintf(fp,"PipeClassResourceForm: %s at stage %s for %d cycles\n", | |
493 _resource, _stage, _cycles); | |
494 } | |
495 | |
496 | |
497 //------------------------------PipeClassForm---------------------------------- | |
498 PipeClassForm::PipeClassForm(const char *id, int num) | |
499 : _ident(id) | |
500 , _num(num) | |
501 , _localNames(cmpstr, hashstr, Form::arena) | |
502 , _localUsage(cmpstr, hashstr, Form::arena) | |
503 , _has_fixed_latency(0) | |
504 , _fixed_latency(0) | |
505 , _instruction_count(0) | |
506 , _has_multiple_bundles(false) | |
507 , _has_branch_delay_slot(false) | |
508 , _force_serialization(false) | |
509 , _may_have_no_code(false) { | |
510 } | |
511 | |
512 PipeClassForm::~PipeClassForm() { | |
513 } | |
514 | |
515 PipeClassForm *PipeClassForm::is_pipeclass() const { | |
516 return (PipeClassForm *)(this); | |
517 } | |
518 | |
519 void PipeClassForm::dump() { | |
520 output(stderr); | |
521 } | |
522 | |
523 void PipeClassForm::output(FILE *fp) { // Write info to output files | |
524 fprintf(fp,"PipeClassForm: #%03d", _num); | |
525 if (_ident) | |
526 fprintf(fp," \"%s\":", _ident); | |
527 if (_has_fixed_latency) | |
528 fprintf(fp," latency %d", _fixed_latency); | |
529 if (_force_serialization) | |
530 fprintf(fp, ", force serialization"); | |
531 if (_may_have_no_code) | |
532 fprintf(fp, ", may have no code"); | |
533 fprintf(fp, ", %d instruction%s\n", InstructionCount(), InstructionCount() != 1 ? "s" : ""); | |
534 } | |
535 | |
536 | |
537 //==============================Peephole Optimization========================== | |
538 int Peephole::_peephole_counter = 0; | |
539 //------------------------------Peephole--------------------------------------- | |
540 Peephole::Peephole() : _match(NULL), _constraint(NULL), _replace(NULL), _next(NULL) { | |
541 _peephole_number = _peephole_counter++; | |
542 } | |
543 Peephole::~Peephole() { | |
544 } | |
545 | |
546 // Append a peephole rule with the same root instruction | |
547 void Peephole::append_peephole(Peephole *next_peephole) { | |
548 if( _next == NULL ) { | |
549 _next = next_peephole; | |
550 } else { | |
551 _next->append_peephole( next_peephole ); | |
552 } | |
553 } | |
554 | |
555 // Store the components of this peephole rule | |
556 void Peephole::add_match(PeepMatch *match) { | |
557 assert( _match == NULL, "fatal()" ); | |
558 _match = match; | |
559 } | |
560 | |
561 void Peephole::append_constraint(PeepConstraint *next_constraint) { | |
562 if( _constraint == NULL ) { | |
563 _constraint = next_constraint; | |
564 } else { | |
565 _constraint->append( next_constraint ); | |
566 } | |
567 } | |
568 | |
569 void Peephole::add_replace(PeepReplace *replace) { | |
570 assert( _replace == NULL, "fatal()" ); | |
571 _replace = replace; | |
572 } | |
573 | |
574 // class Peephole accessor methods are in the declaration. | |
575 | |
576 | |
577 void Peephole::dump() { | |
578 output(stderr); | |
579 } | |
580 | |
581 void Peephole::output(FILE *fp) { // Write info to output files | |
582 fprintf(fp,"Peephole:\n"); | |
583 if( _match != NULL ) _match->output(fp); | |
584 if( _constraint != NULL ) _constraint->output(fp); | |
585 if( _replace != NULL ) _replace->output(fp); | |
586 // Output the next entry | |
587 if( _next ) _next->output(fp); | |
588 } | |
589 | |
590 //------------------------------PeepMatch-------------------------------------- | |
591 PeepMatch::PeepMatch(char *rule) : _max_position(0), _rule(rule) { | |
592 } | |
593 PeepMatch::~PeepMatch() { | |
594 } | |
595 | |
596 | |
597 // Insert info into the match-rule | |
598 void PeepMatch::add_instruction(int parent, int position, const char *name, | |
599 int input) { | |
600 if( position > _max_position ) _max_position = position; | |
601 | |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
602 _parent.addName((char*) (intptr_t) parent); |
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
603 _position.addName((char*) (intptr_t) position); |
0 | 604 _instrs.addName(name); |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
605 _input.addName((char*) (intptr_t) input); |
0 | 606 } |
607 | |
608 // Access info about instructions in the peep-match rule | |
609 int PeepMatch::max_position() { | |
610 return _max_position; | |
611 } | |
612 | |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
613 const char *PeepMatch::instruction_name(int position) { |
0 | 614 return _instrs.name(position); |
615 } | |
616 | |
617 // Iterate through all info on matched instructions | |
618 void PeepMatch::reset() { | |
619 _parent.reset(); | |
620 _position.reset(); | |
621 _instrs.reset(); | |
622 _input.reset(); | |
623 } | |
624 | |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
625 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
|
626 parent = (int) (intptr_t) _parent.iter(); |
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
627 position = (int) (intptr_t) _position.iter(); |
0 | 628 name = _instrs.iter(); |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
629 input = (int) (intptr_t) _input.iter(); |
0 | 630 } |
631 | |
632 // 'true' if current position in iteration is a placeholder, not matched. | |
633 bool PeepMatch::is_placeholder() { | |
634 return _instrs.current_is_signal(); | |
635 } | |
636 | |
637 | |
638 void PeepMatch::dump() { | |
639 output(stderr); | |
640 } | |
641 | |
642 void PeepMatch::output(FILE *fp) { // Write info to output files | |
643 fprintf(fp,"PeepMatch:\n"); | |
644 } | |
645 | |
646 //------------------------------PeepConstraint--------------------------------- | |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
647 PeepConstraint::PeepConstraint(int left_inst, char* left_op, char* relation, |
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
648 int right_inst, char* right_op) |
0 | 649 : _left_inst(left_inst), _left_op(left_op), _relation(relation), |
650 _right_inst(right_inst), _right_op(right_op), _next(NULL) {} | |
651 PeepConstraint::~PeepConstraint() { | |
652 } | |
653 | |
654 // Check if constraints use instruction at position | |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
655 bool PeepConstraint::constrains_instruction(int position) { |
0 | 656 // Check local instruction constraints |
657 if( _left_inst == position ) return true; | |
658 if( _right_inst == position ) return true; | |
659 | |
660 // Check remaining constraints in list | |
661 if( _next == NULL ) return false; | |
662 else return _next->constrains_instruction(position); | |
663 } | |
664 | |
665 // Add another constraint | |
666 void PeepConstraint::append(PeepConstraint *next_constraint) { | |
667 if( _next == NULL ) { | |
668 _next = next_constraint; | |
669 } else { | |
670 _next->append( next_constraint ); | |
671 } | |
672 } | |
673 | |
674 // Access the next constraint in the list | |
675 PeepConstraint *PeepConstraint::next() { | |
676 return _next; | |
677 } | |
678 | |
679 | |
680 void PeepConstraint::dump() { | |
681 output(stderr); | |
682 } | |
683 | |
684 void PeepConstraint::output(FILE *fp) { // Write info to output files | |
685 fprintf(fp,"PeepConstraint:\n"); | |
686 } | |
687 | |
688 //------------------------------PeepReplace------------------------------------ | |
689 PeepReplace::PeepReplace(char *rule) : _rule(rule) { | |
690 } | |
691 PeepReplace::~PeepReplace() { | |
692 } | |
693 | |
694 // Add contents of peepreplace | |
695 void PeepReplace::add_instruction(char *root) { | |
696 _instruction.addName(root); | |
697 _operand_inst_num.add_signal(); | |
698 _operand_op_name.add_signal(); | |
699 } | |
700 void PeepReplace::add_operand( int inst_num, char *inst_operand ) { | |
701 _instruction.add_signal(); | |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
702 _operand_inst_num.addName((char*) (intptr_t) inst_num); |
0 | 703 _operand_op_name.addName(inst_operand); |
704 } | |
705 | |
706 // Access contents of peepreplace | |
707 void PeepReplace::reset() { | |
708 _instruction.reset(); | |
709 _operand_inst_num.reset(); | |
710 _operand_op_name.reset(); | |
711 } | |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
712 void PeepReplace::next_instruction(const char* &inst){ |
0 | 713 inst = _instruction.iter(); |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
714 int inst_num = (int) (intptr_t) _operand_inst_num.iter(); |
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
715 const char* inst_operand = _operand_op_name.iter(); |
0 | 716 } |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
717 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
|
718 const char* inst = _instruction.iter(); |
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
719 inst_num = (int) (intptr_t) _operand_inst_num.iter(); |
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
0
diff
changeset
|
720 inst_operand = _operand_op_name.iter(); |
0 | 721 } |
722 | |
723 | |
724 | |
725 void PeepReplace::dump() { | |
726 output(stderr); | |
727 } | |
728 | |
729 void PeepReplace::output(FILE *fp) { // Write info to output files | |
730 fprintf(fp,"PeepReplace:\n"); | |
731 } |