< prev index next >

src/hotspot/share/opto/lcm.cpp

Print this page
*** 282,13 ***
          } else {
            // only regular oops are expected here
            tptr = base->bottom_type()->is_ptr();
          }
          // Give up if offset is not a compile-time constant.
!         if (offset == Type::OffsetBot || tptr->_offset == Type::OffsetBot)
            continue;
!         offset += tptr->_offset; // correct if base is offsetted
          // Give up if reference is beyond page size.
          if (MacroAssembler::needs_explicit_null_check(offset))
            continue;
          // Give up if base is a decode node and the heap base is not protected.
          if (base->is_Mach() && base->as_Mach()->ideal_Opcode() == Op_DecodeN &&
--- 282,13 ---
          } else {
            // only regular oops are expected here
            tptr = base->bottom_type()->is_ptr();
          }
          // Give up if offset is not a compile-time constant.
!         if (offset == Type::OffsetBot || tptr->offset() == Type::OffsetBot)
            continue;
!         offset += tptr->offset(); // correct if base is offsetted
          // Give up if reference is beyond page size.
          if (MacroAssembler::needs_explicit_null_check(offset))
            continue;
          // Give up if base is a decode node and the heap base is not protected.
          if (base->is_Mach() && base->as_Mach()->ideal_Opcode() == Op_DecodeN &&

*** 321,11 ***
          vidx = j;
          // Ignore DecodeN val which could be hoisted to where needed.
          if( is_decoden ) continue;
        }
        // Block of memory-op input
!       Block *inb = get_block_for_node(mach->in(j));
        Block *b = block;          // Start from nul check
        while( b != inb && b->_dom_depth > inb->_dom_depth )
          b = b->_idom;           // search upwards for input
        // See if input dominates null check
        if( b != inb )
--- 321,15 ---
          vidx = j;
          // Ignore DecodeN val which could be hoisted to where needed.
          if( is_decoden ) continue;
        }
        // Block of memory-op input
!       Block* inb = get_block_for_node(mach->in(j));
+       if (mach->in(j)->is_Con() && mach->in(j)->req() == 1 && inb == get_block_for_node(mach)) {
+         // Ignore constant loads scheduled in the same block (we can simply hoist them as well)
+         continue;
+       }
        Block *b = block;          // Start from nul check
        while( b != inb && b->_dom_depth > inb->_dom_depth )
          b = b->_idom;           // search upwards for input
        // See if input dominates null check
        if( b != inb )

*** 414,10 ***
--- 418,31 ---
            map_node_to_block(n, block);
          }
        }
      }
    }
+ 
+   // Hoist constant load inputs as well.
+   for (uint i = 1; i < best->req(); ++i) {
+     Node* n = best->in(i);
+     if (n->is_Con() && get_block_for_node(n) == get_block_for_node(best)) {
+       get_block_for_node(n)->find_remove(n);
+       block->add_inst(n);
+       map_node_to_block(n, block);
+       // Constant loads may kill flags (for example, when XORing a register).
+       // Check for flag-killing projections that also need to be hoisted.
+       for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) {
+         Node* proj = n->fast_out(j);
+         if (proj->is_MachProj()) {
+           get_block_for_node(proj)->find_remove(proj);
+           block->add_inst(proj);
+           map_node_to_block(proj, block);
+         }
+       }
+     }
+   }
+ 
    // Hoist the memory candidate up to the end of the test block.
    Block *old_block = get_block_for_node(best);
    old_block->find_remove(best);
    block->add_inst(best);
    map_node_to_block(best, block);

*** 884,11 ***
    // Act as if the call defines the Frame Pointer.
    // Certainly the FP is alive and well after the call.
    regs.Insert(_matcher.c_frame_pointer());
  
    // Set all registers killed and not already defined by the call.
!   uint r_cnt = mcall->tf()->range()->cnt();
    int op = mcall->ideal_Opcode();
    MachProjNode *proj = new MachProjNode( mcall, r_cnt+1, RegMask::Empty, MachProjNode::fat_proj );
    map_node_to_block(proj, block);
    block->insert_node(proj, node_cnt++);
  
--- 909,11 ---
    // Act as if the call defines the Frame Pointer.
    // Certainly the FP is alive and well after the call.
    regs.Insert(_matcher.c_frame_pointer());
  
    // Set all registers killed and not already defined by the call.
!   uint r_cnt = mcall->tf()->range_cc()->cnt();
    int op = mcall->ideal_Opcode();
    MachProjNode *proj = new MachProjNode( mcall, r_cnt+1, RegMask::Empty, MachProjNode::fat_proj );
    map_node_to_block(proj, block);
    block->insert_node(proj, node_cnt++);
  
< prev index next >