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 |