Mercurial > hg > truffle
annotate src/share/vm/adlc/formsopt.cpp @ 17716:cdb71841f4bc
6498581: ThreadInterruptTest3 produces wrong output on Windows
Summary: There is race condition between os::interrupt and os::is_interrupted on Windows. In JVM_Sleep(Thread.sleep), check if thread gets interrupted, it may see interrupted but not really interrupted so cause spurious waking up (early return from sleep). Fix by checking if interrupt event really gets set thus prevent false return. For intrinsic of _isInterrupted, on Windows, go fastpath only on bit not set.
Reviewed-by: acorn, kvn
Contributed-by: david.holmes@oracle.com, yumin.qi@oracle.com
author | minqi |
---|---|
date | Wed, 26 Feb 2014 15:20:41 -0800 |
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 } |