src/share/vm/opto/postaloc.cpp

Print this page




 386 //------------------------------post_allocate_copy_removal---------------------
 387 // Post-Allocation peephole copy removal.  We do this in 1 pass over the
 388 // basic blocks.  We maintain a mapping of registers to Nodes (an  array of
 389 // Nodes indexed by machine register or stack slot number).  NULL means that a
 390 // register is not mapped to any Node.  We can (want to have!) have several
 391 // registers map to the same Node.  We walk forward over the instructions
 392 // updating the mapping as we go.  At merge points we force a NULL if we have
 393 // to merge 2 different Nodes into the same register.  Phi functions will give
 394 // us a new Node if there is a proper value merging.  Since the blocks are
 395 // arranged in some RPO, we will visit all parent blocks before visiting any
 396 // successor blocks (except at loops).
 397 //
 398 // If we find a Copy we look to see if the Copy's source register is a stack
 399 // slot and that value has already been loaded into some machine register; if
 400 // so we use machine register directly.  This turns a Load into a reg-reg
 401 // Move.  We also look for reloads of identical constants.
 402 //
 403 // When we see a use from a reg-reg Copy, we will attempt to use the copy's
 404 // source directly and make the copy go dead.
 405 void PhaseChaitin::post_allocate_copy_removal() {
 406   NOT_PRODUCT( Compile::TracePhase t3("postAllocCopyRemoval", &_t_postAllocCopyRemoval, TimeCompiler); )
 407   ResourceMark rm;
 408 
 409   // Need a mapping from basic block Node_Lists.  We need a Node_List to
 410   // map from register number to value-producing Node.
 411   Node_List **blk2value = NEW_RESOURCE_ARRAY( Node_List *, _cfg.number_of_blocks() + 1);
 412   memset(blk2value, 0, sizeof(Node_List*) * (_cfg.number_of_blocks() + 1));
 413   // Need a mapping from basic block Node_Lists.  We need a Node_List to
 414   // map from register number to register-defining Node.
 415   Node_List **blk2regnd = NEW_RESOURCE_ARRAY( Node_List *, _cfg.number_of_blocks() + 1);
 416   memset(blk2regnd, 0, sizeof(Node_List*) * (_cfg.number_of_blocks() + 1));
 417 
 418   // We keep unused Node_Lists on a free_list to avoid wasting
 419   // memory.
 420   GrowableArray<Node_List*> free_list = GrowableArray<Node_List*>(16);
 421 
 422   // For all blocks
 423   for (uint i = 0; i < _cfg.number_of_blocks(); i++) {
 424     uint j;
 425     Block* block = _cfg.get_block(i);
 426 




 386 //------------------------------post_allocate_copy_removal---------------------
 387 // Post-Allocation peephole copy removal.  We do this in 1 pass over the
 388 // basic blocks.  We maintain a mapping of registers to Nodes (an  array of
 389 // Nodes indexed by machine register or stack slot number).  NULL means that a
 390 // register is not mapped to any Node.  We can (want to have!) have several
 391 // registers map to the same Node.  We walk forward over the instructions
 392 // updating the mapping as we go.  At merge points we force a NULL if we have
 393 // to merge 2 different Nodes into the same register.  Phi functions will give
 394 // us a new Node if there is a proper value merging.  Since the blocks are
 395 // arranged in some RPO, we will visit all parent blocks before visiting any
 396 // successor blocks (except at loops).
 397 //
 398 // If we find a Copy we look to see if the Copy's source register is a stack
 399 // slot and that value has already been loaded into some machine register; if
 400 // so we use machine register directly.  This turns a Load into a reg-reg
 401 // Move.  We also look for reloads of identical constants.
 402 //
 403 // When we see a use from a reg-reg Copy, we will attempt to use the copy's
 404 // source directly and make the copy go dead.
 405 void PhaseChaitin::post_allocate_copy_removal() {
 406   Compile::TracePhase t3("postAllocCopyRemoval", &timers[_t_postAllocCopyRemoval]);
 407   ResourceMark rm;
 408 
 409   // Need a mapping from basic block Node_Lists.  We need a Node_List to
 410   // map from register number to value-producing Node.
 411   Node_List **blk2value = NEW_RESOURCE_ARRAY( Node_List *, _cfg.number_of_blocks() + 1);
 412   memset(blk2value, 0, sizeof(Node_List*) * (_cfg.number_of_blocks() + 1));
 413   // Need a mapping from basic block Node_Lists.  We need a Node_List to
 414   // map from register number to register-defining Node.
 415   Node_List **blk2regnd = NEW_RESOURCE_ARRAY( Node_List *, _cfg.number_of_blocks() + 1);
 416   memset(blk2regnd, 0, sizeof(Node_List*) * (_cfg.number_of_blocks() + 1));
 417 
 418   // We keep unused Node_Lists on a free_list to avoid wasting
 419   // memory.
 420   GrowableArray<Node_List*> free_list = GrowableArray<Node_List*>(16);
 421 
 422   // For all blocks
 423   for (uint i = 0; i < _cfg.number_of_blocks(); i++) {
 424     uint j;
 425     Block* block = _cfg.get_block(i);
 426