< prev index next >

src/hotspot/share/opto/macro.cpp

Print this page
rev 49911 : imported patch removeAllGCs


  30 #include "opto/arraycopynode.hpp"
  31 #include "opto/callnode.hpp"
  32 #include "opto/castnode.hpp"
  33 #include "opto/cfgnode.hpp"
  34 #include "opto/compile.hpp"
  35 #include "opto/convertnode.hpp"
  36 #include "opto/graphKit.hpp"
  37 #include "opto/locknode.hpp"
  38 #include "opto/loopnode.hpp"
  39 #include "opto/macro.hpp"
  40 #include "opto/memnode.hpp"
  41 #include "opto/narrowptrnode.hpp"
  42 #include "opto/node.hpp"
  43 #include "opto/opaquenode.hpp"
  44 #include "opto/phaseX.hpp"
  45 #include "opto/rootnode.hpp"
  46 #include "opto/runtime.hpp"
  47 #include "opto/subnode.hpp"
  48 #include "opto/type.hpp"
  49 #include "runtime/sharedRuntime.hpp"
  50 #if INCLUDE_ALL_GCS
  51 #include "gc/g1/g1ThreadLocalData.hpp"
  52 #endif // INCLUDE_ALL_GCS
  53 
  54 
  55 //
  56 // Replace any references to "oldref" in inputs to "use" with "newref".
  57 // Returns the number of replacements made.
  58 //
  59 int PhaseMacroExpand::replace_input(Node *use, Node *oldref, Node *newref) {
  60   int nreplacements = 0;
  61   uint req = use->req();
  62   for (uint j = 0; j < use->len(); j++) {
  63     Node *uin = use->in(j);
  64     if (uin == oldref) {
  65       if (j < req)
  66         use->set_req(j, newref);
  67       else
  68         use->set_prec(j, newref);
  69       nreplacements++;
  70     } else if (j >= req && uin == NULL) {
  71       break;
  72     }


 229 
 230 // Eliminate a card mark sequence.  p2x is a ConvP2XNode
 231 void PhaseMacroExpand::eliminate_card_mark(Node* p2x) {
 232   assert(p2x->Opcode() == Op_CastP2X, "ConvP2XNode required");
 233   if (!UseG1GC) {
 234     // vanilla/CMS post barrier
 235     Node *shift = p2x->unique_out();
 236     Node *addp = shift->unique_out();
 237     for (DUIterator_Last jmin, j = addp->last_outs(jmin); j >= jmin; --j) {
 238       Node *mem = addp->last_out(j);
 239       if (UseCondCardMark && mem->is_Load()) {
 240         assert(mem->Opcode() == Op_LoadB, "unexpected code shape");
 241         // The load is checking if the card has been written so
 242         // replace it with zero to fold the test.
 243         _igvn.replace_node(mem, intcon(0));
 244         continue;
 245       }
 246       assert(mem->is_Store(), "store required");
 247       _igvn.replace_node(mem, mem->in(MemNode::Memory));
 248     }
 249   } else {


 250     // G1 pre/post barriers
 251     assert(p2x->outcnt() <= 2, "expects 1 or 2 users: Xor and URShift nodes");
 252     // It could be only one user, URShift node, in Object.clone() intrinsic
 253     // but the new allocation is passed to arraycopy stub and it could not
 254     // be scalar replaced. So we don't check the case.
 255 
 256     // An other case of only one user (Xor) is when the value check for NULL
 257     // in G1 post barrier is folded after CCP so the code which used URShift
 258     // is removed.
 259 
 260     // Take Region node before eliminating post barrier since it also
 261     // eliminates CastP2X node when it has only one user.
 262     Node* this_region = p2x->in(0);
 263     assert(this_region != NULL, "");
 264 
 265     // Remove G1 post barrier.
 266 
 267     // Search for CastP2X->Xor->URShift->Cmp path which
 268     // checks if the store done to a different from the value's region.
 269     // And replace Cmp with #0 (false) to collapse G1 post barrier.


 309       // This is a G1 post barrier emitted by the Object.clone() intrinsic.
 310       // Search for the CastP2X->URShiftX->AddP->LoadB->Cmp path which checks if the card
 311       // is marked as young_gen and replace the Cmp with 0 (false) to collapse the barrier.
 312       Node* shift = p2x->find_out_with(Op_URShiftX);
 313       assert(shift != NULL, "missing G1 post barrier");
 314       Node* addp = shift->unique_out();
 315       Node* load = addp->find_out_with(Op_LoadB);
 316       assert(load != NULL, "missing G1 post barrier");
 317       Node* cmpx = load->unique_out();
 318       assert(cmpx->is_Cmp() && cmpx->unique_out()->is_Bool() &&
 319              cmpx->unique_out()->as_Bool()->_test._test == BoolTest::ne,
 320              "missing card value check in G1 post barrier");
 321       _igvn.replace_node(cmpx, makecon(TypeInt::CC_EQ));
 322       // There is no G1 pre barrier in this case
 323     }
 324     // Now CastP2X can be removed since it is used only on dead path
 325     // which currently still alive until igvn optimize it.
 326     assert(p2x->outcnt() == 0 || p2x->unique_out()->Opcode() == Op_URShiftX, "");
 327     _igvn.replace_node(p2x, top());
 328   }

 329 }
 330 
 331 // Search for a memory operation for the specified memory slice.
 332 static Node *scan_mem_chain(Node *mem, int alias_idx, int offset, Node *start_mem, Node *alloc, PhaseGVN *phase) {
 333   Node *orig_mem = mem;
 334   Node *alloc_mem = alloc->in(TypeFunc::Memory);
 335   const TypeOopPtr *tinst = phase->C->get_adr_type(alias_idx)->isa_oopptr();
 336   while (true) {
 337     if (mem == alloc_mem || mem == start_mem ) {
 338       return mem;  // hit one of our sentinels
 339     } else if (mem->is_MergeMem()) {
 340       mem = mem->as_MergeMem()->memory_at(alias_idx);
 341     } else if (mem->is_Proj() && mem->as_Proj()->_con == TypeFunc::Memory) {
 342       Node *in = mem->in(0);
 343       // we can safely skip over safepoints, calls, locks and membars because we
 344       // already know that the object is safe to eliminate.
 345       if (in->is_Initialize() && in->as_Initialize()->allocation() == alloc) {
 346         return in;
 347       } else if (in->is_Call()) {
 348         CallNode *call = in->as_Call();




  30 #include "opto/arraycopynode.hpp"
  31 #include "opto/callnode.hpp"
  32 #include "opto/castnode.hpp"
  33 #include "opto/cfgnode.hpp"
  34 #include "opto/compile.hpp"
  35 #include "opto/convertnode.hpp"
  36 #include "opto/graphKit.hpp"
  37 #include "opto/locknode.hpp"
  38 #include "opto/loopnode.hpp"
  39 #include "opto/macro.hpp"
  40 #include "opto/memnode.hpp"
  41 #include "opto/narrowptrnode.hpp"
  42 #include "opto/node.hpp"
  43 #include "opto/opaquenode.hpp"
  44 #include "opto/phaseX.hpp"
  45 #include "opto/rootnode.hpp"
  46 #include "opto/runtime.hpp"
  47 #include "opto/subnode.hpp"
  48 #include "opto/type.hpp"
  49 #include "runtime/sharedRuntime.hpp"
  50 #if INCLUDE_G1GC
  51 #include "gc/g1/g1ThreadLocalData.hpp"
  52 #endif // INCLUDE_G1GC
  53 
  54 
  55 //
  56 // Replace any references to "oldref" in inputs to "use" with "newref".
  57 // Returns the number of replacements made.
  58 //
  59 int PhaseMacroExpand::replace_input(Node *use, Node *oldref, Node *newref) {
  60   int nreplacements = 0;
  61   uint req = use->req();
  62   for (uint j = 0; j < use->len(); j++) {
  63     Node *uin = use->in(j);
  64     if (uin == oldref) {
  65       if (j < req)
  66         use->set_req(j, newref);
  67       else
  68         use->set_prec(j, newref);
  69       nreplacements++;
  70     } else if (j >= req && uin == NULL) {
  71       break;
  72     }


 229 
 230 // Eliminate a card mark sequence.  p2x is a ConvP2XNode
 231 void PhaseMacroExpand::eliminate_card_mark(Node* p2x) {
 232   assert(p2x->Opcode() == Op_CastP2X, "ConvP2XNode required");
 233   if (!UseG1GC) {
 234     // vanilla/CMS post barrier
 235     Node *shift = p2x->unique_out();
 236     Node *addp = shift->unique_out();
 237     for (DUIterator_Last jmin, j = addp->last_outs(jmin); j >= jmin; --j) {
 238       Node *mem = addp->last_out(j);
 239       if (UseCondCardMark && mem->is_Load()) {
 240         assert(mem->Opcode() == Op_LoadB, "unexpected code shape");
 241         // The load is checking if the card has been written so
 242         // replace it with zero to fold the test.
 243         _igvn.replace_node(mem, intcon(0));
 244         continue;
 245       }
 246       assert(mem->is_Store(), "store required");
 247       _igvn.replace_node(mem, mem->in(MemNode::Memory));
 248     }
 249   }
 250 #if INCLUDE_G1GC
 251   else {
 252     // G1 pre/post barriers
 253     assert(p2x->outcnt() <= 2, "expects 1 or 2 users: Xor and URShift nodes");
 254     // It could be only one user, URShift node, in Object.clone() intrinsic
 255     // but the new allocation is passed to arraycopy stub and it could not
 256     // be scalar replaced. So we don't check the case.
 257 
 258     // An other case of only one user (Xor) is when the value check for NULL
 259     // in G1 post barrier is folded after CCP so the code which used URShift
 260     // is removed.
 261 
 262     // Take Region node before eliminating post barrier since it also
 263     // eliminates CastP2X node when it has only one user.
 264     Node* this_region = p2x->in(0);
 265     assert(this_region != NULL, "");
 266 
 267     // Remove G1 post barrier.
 268 
 269     // Search for CastP2X->Xor->URShift->Cmp path which
 270     // checks if the store done to a different from the value's region.
 271     // And replace Cmp with #0 (false) to collapse G1 post barrier.


 311       // This is a G1 post barrier emitted by the Object.clone() intrinsic.
 312       // Search for the CastP2X->URShiftX->AddP->LoadB->Cmp path which checks if the card
 313       // is marked as young_gen and replace the Cmp with 0 (false) to collapse the barrier.
 314       Node* shift = p2x->find_out_with(Op_URShiftX);
 315       assert(shift != NULL, "missing G1 post barrier");
 316       Node* addp = shift->unique_out();
 317       Node* load = addp->find_out_with(Op_LoadB);
 318       assert(load != NULL, "missing G1 post barrier");
 319       Node* cmpx = load->unique_out();
 320       assert(cmpx->is_Cmp() && cmpx->unique_out()->is_Bool() &&
 321              cmpx->unique_out()->as_Bool()->_test._test == BoolTest::ne,
 322              "missing card value check in G1 post barrier");
 323       _igvn.replace_node(cmpx, makecon(TypeInt::CC_EQ));
 324       // There is no G1 pre barrier in this case
 325     }
 326     // Now CastP2X can be removed since it is used only on dead path
 327     // which currently still alive until igvn optimize it.
 328     assert(p2x->outcnt() == 0 || p2x->unique_out()->Opcode() == Op_URShiftX, "");
 329     _igvn.replace_node(p2x, top());
 330   }
 331 #endif // INCLUDE_G1GC
 332 }
 333 
 334 // Search for a memory operation for the specified memory slice.
 335 static Node *scan_mem_chain(Node *mem, int alias_idx, int offset, Node *start_mem, Node *alloc, PhaseGVN *phase) {
 336   Node *orig_mem = mem;
 337   Node *alloc_mem = alloc->in(TypeFunc::Memory);
 338   const TypeOopPtr *tinst = phase->C->get_adr_type(alias_idx)->isa_oopptr();
 339   while (true) {
 340     if (mem == alloc_mem || mem == start_mem ) {
 341       return mem;  // hit one of our sentinels
 342     } else if (mem->is_MergeMem()) {
 343       mem = mem->as_MergeMem()->memory_at(alias_idx);
 344     } else if (mem->is_Proj() && mem->as_Proj()->_con == TypeFunc::Memory) {
 345       Node *in = mem->in(0);
 346       // we can safely skip over safepoints, calls, locks and membars because we
 347       // already know that the object is safe to eliminate.
 348       if (in->is_Initialize() && in->as_Initialize()->allocation() == alloc) {
 349         return in;
 350       } else if (in->is_Call()) {
 351         CallNode *call = in->as_Call();


< prev index next >