Mercurial > hg > graal-jvmci-8
comparison src/share/vm/opto/buildOopMap.cpp @ 12071:adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
Summary: public methods that don't need to be public should be private.
Reviewed-by: kvn, twisti
author | adlertz |
---|---|
date | Fri, 16 Aug 2013 10:23:55 +0200 |
parents | d1034bd8cefc |
children | 650868c062a9 |
comparison
equal
deleted
inserted
replaced
12070:afbe18ae0905 | 12071:adb9a7d94cb5 |
---|---|
85 // practice. One array will map to a reaching def Node (or NULL for | 85 // practice. One array will map to a reaching def Node (or NULL for |
86 // conflict/dead). The other array will map to a callee-saved register or | 86 // conflict/dead). The other array will map to a callee-saved register or |
87 // OptoReg::Bad for not-callee-saved. | 87 // OptoReg::Bad for not-callee-saved. |
88 | 88 |
89 | 89 |
90 //------------------------------OopFlow---------------------------------------- | |
91 // Structure to pass around | 90 // Structure to pass around |
92 struct OopFlow : public ResourceObj { | 91 struct OopFlow : public ResourceObj { |
93 short *_callees; // Array mapping register to callee-saved | 92 short *_callees; // Array mapping register to callee-saved |
94 Node **_defs; // array mapping register to reaching def | 93 Node **_defs; // array mapping register to reaching def |
95 // or NULL if dead/conflict | 94 // or NULL if dead/conflict |
117 | 116 |
118 // Build an oopmap from the current flow info | 117 // Build an oopmap from the current flow info |
119 OopMap *build_oop_map( Node *n, int max_reg, PhaseRegAlloc *regalloc, int* live ); | 118 OopMap *build_oop_map( Node *n, int max_reg, PhaseRegAlloc *regalloc, int* live ); |
120 }; | 119 }; |
121 | 120 |
122 //------------------------------compute_reach---------------------------------- | |
123 // Given reaching-defs for this block start, compute it for this block end | 121 // Given reaching-defs for this block start, compute it for this block end |
124 void OopFlow::compute_reach( PhaseRegAlloc *regalloc, int max_reg, Dict *safehash ) { | 122 void OopFlow::compute_reach( PhaseRegAlloc *regalloc, int max_reg, Dict *safehash ) { |
125 | 123 |
126 for( uint i=0; i<_b->_nodes.size(); i++ ) { | 124 for( uint i=0; i<_b->_nodes.size(); i++ ) { |
127 Node *n = _b->_nodes[i]; | 125 Node *n = _b->_nodes[i]; |
175 } | 173 } |
176 } | 174 } |
177 } | 175 } |
178 } | 176 } |
179 | 177 |
180 //------------------------------merge------------------------------------------ | |
181 // Merge the given flow into the 'this' flow | 178 // Merge the given flow into the 'this' flow |
182 void OopFlow::merge( OopFlow *flow, int max_reg ) { | 179 void OopFlow::merge( OopFlow *flow, int max_reg ) { |
183 assert( _b == NULL, "merging into a happy flow" ); | 180 assert( _b == NULL, "merging into a happy flow" ); |
184 assert( flow->_b, "this flow is still alive" ); | 181 assert( flow->_b, "this flow is still alive" ); |
185 assert( flow != this, "no self flow" ); | 182 assert( flow != this, "no self flow" ); |
195 _defs[i] = NULL; | 192 _defs[i] = NULL; |
196 } | 193 } |
197 | 194 |
198 } | 195 } |
199 | 196 |
200 //------------------------------clone------------------------------------------ | |
201 void OopFlow::clone( OopFlow *flow, int max_size ) { | 197 void OopFlow::clone( OopFlow *flow, int max_size ) { |
202 _b = flow->_b; | 198 _b = flow->_b; |
203 memcpy( _callees, flow->_callees, sizeof(short)*max_size); | 199 memcpy( _callees, flow->_callees, sizeof(short)*max_size); |
204 memcpy( _defs , flow->_defs , sizeof(Node*)*max_size); | 200 memcpy( _defs , flow->_defs , sizeof(Node*)*max_size); |
205 } | 201 } |
206 | 202 |
207 //------------------------------make------------------------------------------- | |
208 OopFlow *OopFlow::make( Arena *A, int max_size, Compile* C ) { | 203 OopFlow *OopFlow::make( Arena *A, int max_size, Compile* C ) { |
209 short *callees = NEW_ARENA_ARRAY(A,short,max_size+1); | 204 short *callees = NEW_ARENA_ARRAY(A,short,max_size+1); |
210 Node **defs = NEW_ARENA_ARRAY(A,Node*,max_size+1); | 205 Node **defs = NEW_ARENA_ARRAY(A,Node*,max_size+1); |
211 debug_only( memset(defs,0,(max_size+1)*sizeof(Node*)) ); | 206 debug_only( memset(defs,0,(max_size+1)*sizeof(Node*)) ); |
212 OopFlow *flow = new (A) OopFlow(callees+1, defs+1, C); | 207 OopFlow *flow = new (A) OopFlow(callees+1, defs+1, C); |
213 assert( &flow->_callees[OptoReg::Bad] == callees, "Ok to index at OptoReg::Bad" ); | 208 assert( &flow->_callees[OptoReg::Bad] == callees, "Ok to index at OptoReg::Bad" ); |
214 assert( &flow->_defs [OptoReg::Bad] == defs , "Ok to index at OptoReg::Bad" ); | 209 assert( &flow->_defs [OptoReg::Bad] == defs , "Ok to index at OptoReg::Bad" ); |
215 return flow; | 210 return flow; |
216 } | 211 } |
217 | 212 |
218 //------------------------------bit twiddlers---------------------------------- | |
219 static int get_live_bit( int *live, int reg ) { | 213 static int get_live_bit( int *live, int reg ) { |
220 return live[reg>>LogBitsPerInt] & (1<<(reg&(BitsPerInt-1))); } | 214 return live[reg>>LogBitsPerInt] & (1<<(reg&(BitsPerInt-1))); } |
221 static void set_live_bit( int *live, int reg ) { | 215 static void set_live_bit( int *live, int reg ) { |
222 live[reg>>LogBitsPerInt] |= (1<<(reg&(BitsPerInt-1))); } | 216 live[reg>>LogBitsPerInt] |= (1<<(reg&(BitsPerInt-1))); } |
223 static void clr_live_bit( int *live, int reg ) { | 217 static void clr_live_bit( int *live, int reg ) { |
224 live[reg>>LogBitsPerInt] &= ~(1<<(reg&(BitsPerInt-1))); } | 218 live[reg>>LogBitsPerInt] &= ~(1<<(reg&(BitsPerInt-1))); } |
225 | 219 |
226 //------------------------------build_oop_map---------------------------------- | |
227 // Build an oopmap from the current flow info | 220 // Build an oopmap from the current flow info |
228 OopMap *OopFlow::build_oop_map( Node *n, int max_reg, PhaseRegAlloc *regalloc, int* live ) { | 221 OopMap *OopFlow::build_oop_map( Node *n, int max_reg, PhaseRegAlloc *regalloc, int* live ) { |
229 int framesize = regalloc->_framesize; | 222 int framesize = regalloc->_framesize; |
230 int max_inarg_slot = OptoReg::reg2stack(regalloc->_matcher._new_SP); | 223 int max_inarg_slot = OptoReg::reg2stack(regalloc->_matcher._new_SP); |
231 debug_only( char *dup_check = NEW_RESOURCE_ARRAY(char,OptoReg::stack0()); | 224 debug_only( char *dup_check = NEW_RESOURCE_ARRAY(char,OptoReg::stack0()); |
410 #endif | 403 #endif |
411 | 404 |
412 return omap; | 405 return omap; |
413 } | 406 } |
414 | 407 |
415 //------------------------------do_liveness------------------------------------ | |
416 // Compute backwards liveness on registers | 408 // Compute backwards liveness on registers |
417 static void do_liveness( PhaseRegAlloc *regalloc, PhaseCFG *cfg, Block_List *worklist, int max_reg_ints, Arena *A, Dict *safehash ) { | 409 static void do_liveness(PhaseRegAlloc* regalloc, PhaseCFG* cfg, Block_List* worklist, int max_reg_ints, Arena* A, Dict* safehash) { |
418 int *live = NEW_ARENA_ARRAY(A, int, (cfg->_num_blocks+1) * max_reg_ints); | 410 int* live = NEW_ARENA_ARRAY(A, int, (cfg->number_of_blocks() + 1) * max_reg_ints); |
419 int *tmp_live = &live[cfg->_num_blocks * max_reg_ints]; | 411 int* tmp_live = &live[cfg->number_of_blocks() * max_reg_ints]; |
420 Node *root = cfg->C->root(); | 412 Node* root = cfg->get_root_node(); |
421 // On CISC platforms, get the node representing the stack pointer that regalloc | 413 // On CISC platforms, get the node representing the stack pointer that regalloc |
422 // used for spills | 414 // used for spills |
423 Node *fp = NodeSentinel; | 415 Node *fp = NodeSentinel; |
424 if (UseCISCSpill && root->req() > 1) { | 416 if (UseCISCSpill && root->req() > 1) { |
425 fp = root->in(1)->in(TypeFunc::FramePtr); | 417 fp = root->in(1)->in(TypeFunc::FramePtr); |
426 } | 418 } |
427 memset( live, 0, cfg->_num_blocks * (max_reg_ints<<LogBytesPerInt) ); | 419 memset(live, 0, cfg->number_of_blocks() * (max_reg_ints << LogBytesPerInt)); |
428 // Push preds onto worklist | 420 // Push preds onto worklist |
429 for (uint i = 1; i < root->req(); i++) { | 421 for (uint i = 1; i < root->req(); i++) { |
430 Block* block = cfg->get_block_for_node(root->in(i)); | 422 Block* block = cfg->get_block_for_node(root->in(i)); |
431 worklist->push(block); | 423 worklist->push(block); |
432 } | 424 } |
547 } | 539 } |
548 | 540 |
549 // Scan for any missing safepoints. Happens to infinite loops | 541 // Scan for any missing safepoints. Happens to infinite loops |
550 // ala ZKM.jar | 542 // ala ZKM.jar |
551 uint i; | 543 uint i; |
552 for( i=1; i<cfg->_num_blocks; i++ ) { | 544 for (i = 1; i < cfg->number_of_blocks(); i++) { |
553 Block *b = cfg->_blocks[i]; | 545 Block* block = cfg->get_block(i); |
554 uint j; | 546 uint j; |
555 for( j=1; j<b->_nodes.size(); j++ ) | 547 for (j = 1; j < block->_nodes.size(); j++) { |
556 if( b->_nodes[j]->jvms() && | 548 if (block->_nodes[j]->jvms() && (*safehash)[block->_nodes[j]] == NULL) { |
557 (*safehash)[b->_nodes[j]] == NULL ) | |
558 break; | 549 break; |
559 if( j<b->_nodes.size() ) break; | 550 } |
560 } | 551 } |
561 if( i == cfg->_num_blocks ) | 552 if (j < block->_nodes.size()) { |
553 break; | |
554 } | |
555 } | |
556 if (i == cfg->number_of_blocks()) { | |
562 break; // Got 'em all | 557 break; // Got 'em all |
558 } | |
563 #ifndef PRODUCT | 559 #ifndef PRODUCT |
564 if( PrintOpto && Verbose ) | 560 if( PrintOpto && Verbose ) |
565 tty->print_cr("retripping live calc"); | 561 tty->print_cr("retripping live calc"); |
566 #endif | 562 #endif |
567 // Force the issue (expensively): recheck everybody | 563 // Force the issue (expensively): recheck everybody |
568 for( i=1; i<cfg->_num_blocks; i++ ) | 564 for (i = 1; i < cfg->number_of_blocks(); i++) { |
569 worklist->push(cfg->_blocks[i]); | 565 worklist->push(cfg->get_block(i)); |
570 } | 566 } |
571 | 567 } |
572 } | 568 } |
573 | 569 |
574 //------------------------------BuildOopMaps----------------------------------- | |
575 // Collect GC mask info - where are all the OOPs? | 570 // Collect GC mask info - where are all the OOPs? |
576 void Compile::BuildOopMaps() { | 571 void Compile::BuildOopMaps() { |
577 NOT_PRODUCT( TracePhase t3("bldOopMaps", &_t_buildOopMaps, TimeCompiler); ) | 572 NOT_PRODUCT( TracePhase t3("bldOopMaps", &_t_buildOopMaps, TimeCompiler); ) |
578 // Can't resource-mark because I need to leave all those OopMaps around, | 573 // Can't resource-mark because I need to leave all those OopMaps around, |
579 // or else I need to resource-mark some arena other than the default. | 574 // or else I need to resource-mark some arena other than the default. |
590 safehash = new Dict(cmpkey,hashkey,A); | 585 safehash = new Dict(cmpkey,hashkey,A); |
591 do_liveness( _regalloc, _cfg, &worklist, max_reg_ints, A, safehash ); | 586 do_liveness( _regalloc, _cfg, &worklist, max_reg_ints, A, safehash ); |
592 OopFlow *free_list = NULL; // Free, unused | 587 OopFlow *free_list = NULL; // Free, unused |
593 | 588 |
594 // Array mapping blocks to completed oopflows | 589 // Array mapping blocks to completed oopflows |
595 OopFlow **flows = NEW_ARENA_ARRAY(A, OopFlow*, _cfg->_num_blocks); | 590 OopFlow **flows = NEW_ARENA_ARRAY(A, OopFlow*, _cfg->number_of_blocks()); |
596 memset( flows, 0, _cfg->_num_blocks*sizeof(OopFlow*) ); | 591 memset( flows, 0, _cfg->number_of_blocks() * sizeof(OopFlow*) ); |
597 | 592 |
598 | 593 |
599 // Do the first block 'by hand' to prime the worklist | 594 // Do the first block 'by hand' to prime the worklist |
600 Block *entry = _cfg->_blocks[1]; | 595 Block *entry = _cfg->get_block(1); |
601 OopFlow *rootflow = OopFlow::make(A,max_reg,this); | 596 OopFlow *rootflow = OopFlow::make(A,max_reg,this); |
602 // Initialize to 'bottom' (not 'top') | 597 // Initialize to 'bottom' (not 'top') |
603 memset( rootflow->_callees, OptoReg::Bad, max_reg*sizeof(short) ); | 598 memset( rootflow->_callees, OptoReg::Bad, max_reg*sizeof(short) ); |
604 memset( rootflow->_defs , 0, max_reg*sizeof(Node*) ); | 599 memset( rootflow->_defs , 0, max_reg*sizeof(Node*) ); |
605 flows[entry->_pre_order] = rootflow; | 600 flows[entry->_pre_order] = rootflow; |
621 // SAME reaching def for the block, so any reaching def is OK. | 616 // SAME reaching def for the block, so any reaching def is OK. |
622 uint i; | 617 uint i; |
623 | 618 |
624 Block *b = worklist.pop(); | 619 Block *b = worklist.pop(); |
625 // Ignore root block | 620 // Ignore root block |
626 if( b == _cfg->_broot ) continue; | 621 if (b == _cfg->get_root_block()) { |
622 continue; | |
623 } | |
627 // Block is already done? Happens if block has several predecessors, | 624 // Block is already done? Happens if block has several predecessors, |
628 // he can get on the worklist more than once. | 625 // he can get on the worklist more than once. |
629 if( flows[b->_pre_order] ) continue; | 626 if( flows[b->_pre_order] ) continue; |
630 | 627 |
631 // If this block has a visited predecessor AND that predecessor has this | 628 // If this block has a visited predecessor AND that predecessor has this |