src/share/vm/opto/macro.cpp

Print this page
rev 3361 : 7173584: Implement arraycopy as a macro node
Summary: delay the conversion of arraycopy to stub calls to macro expansion
Reviewed-by:


2380       progress = progress || success;
2381     }
2382   }
2383   // Next, attempt to eliminate allocations
2384   progress = true;
2385   while (progress) {
2386     progress = false;
2387     for (int i = C->macro_count(); i > 0; i--) {
2388       Node * n = C->macro_node(i-1);
2389       bool success = false;
2390       debug_only(int old_macro_count = C->macro_count(););
2391       switch (n->class_id()) {
2392       case Node::Class_Allocate:
2393       case Node::Class_AllocateArray:
2394         success = eliminate_allocate_node(n->as_Allocate());
2395         break;
2396       case Node::Class_Lock:
2397       case Node::Class_Unlock:
2398         assert(!n->as_AbstractLock()->is_eliminated(), "sanity");
2399         break;


2400       default:
2401         assert(n->Opcode() == Op_LoopLimit ||
2402                n->Opcode() == Op_Opaque1   ||
2403                n->Opcode() == Op_Opaque2, "unknown node type in macro list");
2404       }
2405       assert(success == (C->macro_count() < old_macro_count), "elimination reduces macro count");
2406       progress = progress || success;
2407     }
2408   }
2409 }
2410 
2411 //------------------------------expand_macro_nodes----------------------
2412 //  Returns true if a failure occurred.
2413 bool PhaseMacroExpand::expand_macro_nodes() {
2414   // Last attempt to eliminate macro nodes.
2415   eliminate_macro_nodes();
2416 
2417   // Make sure expansion will not cause node limit to be exceeded.
2418   // Worst case is a macro node gets expanded into about 50 nodes.
2419   // Allow 50% more for optimization.


2423   // Eliminate Opaque and LoopLimit nodes. Do it after all loop optimizations.
2424   bool progress = true;
2425   while (progress) {
2426     progress = false;
2427     for (int i = C->macro_count(); i > 0; i--) {
2428       Node * n = C->macro_node(i-1);
2429       bool success = false;
2430       debug_only(int old_macro_count = C->macro_count(););
2431       if (n->Opcode() == Op_LoopLimit) {
2432         // Remove it from macro list and put on IGVN worklist to optimize.
2433         C->remove_macro_node(n);
2434         _igvn._worklist.push(n);
2435         success = true;
2436       } else if (n->Opcode() == Op_Opaque1 || n->Opcode() == Op_Opaque2) {
2437         _igvn.replace_node(n, n->in(1));
2438         success = true;
2439       }
2440       assert(success == (C->macro_count() < old_macro_count), "elimination reduces macro count");
2441       progress = progress || success;
2442     }



















2443   }
2444 
2445   // expand "macro" nodes
2446   // nodes are removed from the macro list as they are processed
2447   while (C->macro_count() > 0) {
2448     int macro_count = C->macro_count();
2449     Node * n = C->macro_node(macro_count-1);
2450     assert(n->is_macro(), "only macro nodes expected here");
2451     if (_igvn.type(n) == Type::TOP || n->in(0)->is_top() ) {
2452       // node is unreachable, so don't try to expand it
2453       C->remove_macro_node(n);
2454       continue;
2455     }
2456     switch (n->class_id()) {
2457     case Node::Class_Allocate:
2458       expand_allocate(n->as_Allocate());
2459       break;
2460     case Node::Class_AllocateArray:
2461       expand_allocate_array(n->as_AllocateArray());
2462       break;


2380       progress = progress || success;
2381     }
2382   }
2383   // Next, attempt to eliminate allocations
2384   progress = true;
2385   while (progress) {
2386     progress = false;
2387     for (int i = C->macro_count(); i > 0; i--) {
2388       Node * n = C->macro_node(i-1);
2389       bool success = false;
2390       debug_only(int old_macro_count = C->macro_count(););
2391       switch (n->class_id()) {
2392       case Node::Class_Allocate:
2393       case Node::Class_AllocateArray:
2394         success = eliminate_allocate_node(n->as_Allocate());
2395         break;
2396       case Node::Class_Lock:
2397       case Node::Class_Unlock:
2398         assert(!n->as_AbstractLock()->is_eliminated(), "sanity");
2399         break;
2400       case Node::Class_ArrayCopy:
2401         break;
2402       default:
2403         assert(n->Opcode() == Op_LoopLimit ||
2404                n->Opcode() == Op_Opaque1   ||
2405                n->Opcode() == Op_Opaque2, "unknown node type in macro list");
2406       }
2407       assert(success == (C->macro_count() < old_macro_count), "elimination reduces macro count");
2408       progress = progress || success;
2409     }
2410   }
2411 }
2412 
2413 //------------------------------expand_macro_nodes----------------------
2414 //  Returns true if a failure occurred.
2415 bool PhaseMacroExpand::expand_macro_nodes() {
2416   // Last attempt to eliminate macro nodes.
2417   eliminate_macro_nodes();
2418 
2419   // Make sure expansion will not cause node limit to be exceeded.
2420   // Worst case is a macro node gets expanded into about 50 nodes.
2421   // Allow 50% more for optimization.


2425   // Eliminate Opaque and LoopLimit nodes. Do it after all loop optimizations.
2426   bool progress = true;
2427   while (progress) {
2428     progress = false;
2429     for (int i = C->macro_count(); i > 0; i--) {
2430       Node * n = C->macro_node(i-1);
2431       bool success = false;
2432       debug_only(int old_macro_count = C->macro_count(););
2433       if (n->Opcode() == Op_LoopLimit) {
2434         // Remove it from macro list and put on IGVN worklist to optimize.
2435         C->remove_macro_node(n);
2436         _igvn._worklist.push(n);
2437         success = true;
2438       } else if (n->Opcode() == Op_Opaque1 || n->Opcode() == Op_Opaque2) {
2439         _igvn.replace_node(n, n->in(1));
2440         success = true;
2441       }
2442       assert(success == (C->macro_count() < old_macro_count), "elimination reduces macro count");
2443       progress = progress || success;
2444     }
2445   }
2446 
2447   // expand arraycopy "macro" nodes first
2448   // For ReduceBulkZeroing, we must first process all arraycopy nodes
2449   // before the allocate nodes are expanded.
2450   int macro_idx = C->macro_count() - 1;
2451   while (macro_idx >= 0) {
2452     Node * n = C->macro_node(macro_idx);
2453     assert(n->is_macro(), "only macro nodes expected here");
2454     if (_igvn.type(n) == Type::TOP || n->in(0)->is_top() ) {
2455       // node is unreachable, so don't try to expand it
2456       C->remove_macro_node(n);
2457     } else if (n->is_ArrayCopy()){
2458       int macro_count = C->macro_count();
2459       expand_arraycopy_node(n->as_ArrayCopy());
2460       assert(C->macro_count() < macro_count, "must have deleted a node from macro list");
2461     }
2462     if (C->failing())  return true;
2463     macro_idx --;
2464   }
2465 
2466   // expand "macro" nodes
2467   // nodes are removed from the macro list as they are processed
2468   while (C->macro_count() > 0) {
2469     int macro_count = C->macro_count();
2470     Node * n = C->macro_node(macro_count-1);
2471     assert(n->is_macro(), "only macro nodes expected here");
2472     if (_igvn.type(n) == Type::TOP || n->in(0)->is_top() ) {
2473       // node is unreachable, so don't try to expand it
2474       C->remove_macro_node(n);
2475       continue;
2476     }
2477     switch (n->class_id()) {
2478     case Node::Class_Allocate:
2479       expand_allocate(n->as_Allocate());
2480       break;
2481     case Node::Class_AllocateArray:
2482       expand_allocate_array(n->as_AllocateArray());
2483       break;