< prev index next >

src/share/vm/opto/gcm.cpp

Print this page




  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "libadt/vectset.hpp"
  27 #include "memory/allocation.inline.hpp"
  28 #include "opto/block.hpp"
  29 #include "opto/c2compiler.hpp"
  30 #include "opto/callnode.hpp"
  31 #include "opto/cfgnode.hpp"
  32 #include "opto/machnode.hpp"
  33 #include "opto/opcodes.hpp"
  34 #include "opto/phaseX.hpp"
  35 #include "opto/rootnode.hpp"
  36 #include "opto/runtime.hpp"

  37 #include "runtime/deoptimization.hpp"
  38 
  39 // Portions of code courtesy of Clifford Click
  40 
  41 // Optimization - Graph Style
  42 
  43 // To avoid float value underflow
  44 #define MIN_BLOCK_FREQUENCY 1.e-35f
  45 
  46 //----------------------------schedule_node_into_block-------------------------
  47 // Insert node n into block b. Look for projections of n and make sure they
  48 // are in b also.
  49 void PhaseCFG::schedule_node_into_block( Node *n, Block *b ) {
  50   // Set basic block of n, Add n to b,
  51   map_node_to_block(n, b);
  52   b->add_inst(n);
  53 
  54   // After Matching, nearly any old Node may have projections trailing it.
  55   // These are usually machine-dependent flags.  In any case, they might
  56   // float to another block below this one.  Move them up.


1346   // Detect implicit-null-check opportunities.  Basically, find NULL checks
1347   // with suitable memory ops nearby.  Use the memory op to do the NULL check.
1348   // I can generate a memory op if there is not one nearby.
1349   if (C->is_method_compilation()) {
1350     // By reversing the loop direction we get a very minor gain on mpegaudio.
1351     // Feel free to revert to a forward loop for clarity.
1352     // for( int i=0; i < (int)matcher._null_check_tests.size(); i+=2 ) {
1353     for (int i = _matcher._null_check_tests.size() - 2; i >= 0; i -= 2) {
1354       Node* proj = _matcher._null_check_tests[i];
1355       Node* val  = _matcher._null_check_tests[i + 1];
1356       Block* block = get_block_for_node(proj);
1357       implicit_null_check(block, proj, val, C->allowed_deopt_reasons());
1358       // The implicit_null_check will only perform the transformation
1359       // if the null branch is truly uncommon, *and* it leads to an
1360       // uncommon trap.  Combined with the too_many_traps guards
1361       // above, this prevents SEGV storms reported in 6366351,
1362       // by recompiling offending methods without this optimization.
1363     }
1364   }
1365 



























1366 #ifndef PRODUCT
1367   if (trace_opto_pipelining()) {
1368     tty->print("\n---- Start Local Scheduling ----\n");
1369   }
1370 #endif
1371 
1372   // Schedule locally.  Right now a simple topological sort.
1373   // Later, do a real latency aware scheduler.
1374   GrowableArray<int> ready_cnt(C->unique(), C->unique(), -1);
1375   visited.Clear();
1376   for (uint i = 0; i < number_of_blocks(); i++) {
1377     Block* block = get_block(i);
1378     if (!schedule_local(block, ready_cnt, visited)) {
1379       if (!C->failure_reason_is(C2Compiler::retry_no_subsuming_loads())) {
1380         C->record_method_not_compilable("local schedule failed");
1381       }

1382       return;
1383     }
1384   }

1385 
1386   // If we inserted any instructions between a Call and his CatchNode,
1387   // clone the instructions on all paths below the Catch.
1388   for (uint i = 0; i < number_of_blocks(); i++) {
1389     Block* block = get_block(i);
1390     call_catch_cleanup(block);
1391   }
1392 
1393 #ifndef PRODUCT
1394   if (trace_opto_pipelining()) {
1395     tty->print("\n---- After GlobalCodeMotion ----\n");
1396     for (uint i = 0; i < number_of_blocks(); i++) {
1397       Block* block = get_block(i);
1398       block->dump();
1399     }
1400   }
1401 #endif
1402   // Dead.
1403   _node_latency = (GrowableArray<uint> *)0xdeadbeef;
1404 }




  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "libadt/vectset.hpp"
  27 #include "memory/allocation.inline.hpp"
  28 #include "opto/block.hpp"
  29 #include "opto/c2compiler.hpp"
  30 #include "opto/callnode.hpp"
  31 #include "opto/cfgnode.hpp"
  32 #include "opto/machnode.hpp"
  33 #include "opto/opcodes.hpp"
  34 #include "opto/phaseX.hpp"
  35 #include "opto/rootnode.hpp"
  36 #include "opto/runtime.hpp"
  37 #include "opto/chaitin.hpp"
  38 #include "runtime/deoptimization.hpp"
  39 
  40 // Portions of code courtesy of Clifford Click
  41 
  42 // Optimization - Graph Style
  43 
  44 // To avoid float value underflow
  45 #define MIN_BLOCK_FREQUENCY 1.e-35f
  46 
  47 //----------------------------schedule_node_into_block-------------------------
  48 // Insert node n into block b. Look for projections of n and make sure they
  49 // are in b also.
  50 void PhaseCFG::schedule_node_into_block( Node *n, Block *b ) {
  51   // Set basic block of n, Add n to b,
  52   map_node_to_block(n, b);
  53   b->add_inst(n);
  54 
  55   // After Matching, nearly any old Node may have projections trailing it.
  56   // These are usually machine-dependent flags.  In any case, they might
  57   // float to another block below this one.  Move them up.


1347   // Detect implicit-null-check opportunities.  Basically, find NULL checks
1348   // with suitable memory ops nearby.  Use the memory op to do the NULL check.
1349   // I can generate a memory op if there is not one nearby.
1350   if (C->is_method_compilation()) {
1351     // By reversing the loop direction we get a very minor gain on mpegaudio.
1352     // Feel free to revert to a forward loop for clarity.
1353     // for( int i=0; i < (int)matcher._null_check_tests.size(); i+=2 ) {
1354     for (int i = _matcher._null_check_tests.size() - 2; i >= 0; i -= 2) {
1355       Node* proj = _matcher._null_check_tests[i];
1356       Node* val  = _matcher._null_check_tests[i + 1];
1357       Block* block = get_block_for_node(proj);
1358       implicit_null_check(block, proj, val, C->allowed_deopt_reasons());
1359       // The implicit_null_check will only perform the transformation
1360       // if the null branch is truly uncommon, *and* it leads to an
1361       // uncommon trap.  Combined with the too_many_traps guards
1362       // above, this prevents SEGV storms reported in 6366351,
1363       // by recompiling offending methods without this optimization.
1364     }
1365   }
1366 
1367   PhaseChaitin regalloc(C->unique(), *this, _matcher, true);
1368   ResourceArea live_arena;      // Arena for liveness
1369   ResourceMark rm_live(&live_arena);
1370   PhaseLive live(*this, regalloc._lrg_map.names(), &live_arena, true);
1371   PhaseIFG ifg(&live_arena);
1372   intptr_t *recalc_pressure_nodes = NULL;
1373 
1374   if (OptoRegScheduling) {
1375     regalloc.mark_ssa();
1376     Compile::TracePhase tp("computeLive", &timers[_t_computeLive]);
1377     rm_live.reset_to_mark();           // Reclaim working storage
1378     IndexSet::reset_memory(C, &live_arena);
1379     uint node_size = regalloc._lrg_map.max_lrg_id();
1380     ifg.init(node_size); // Empty IFG
1381     regalloc.set_ifg(ifg);
1382     regalloc.set_live(live);
1383     regalloc.gather_lrg_masks(false);    // Collect LRG masks
1384     live.compute(node_size); // Compute liveness
1385 
1386     recalc_pressure_nodes = NEW_RESOURCE_ARRAY(intptr_t, node_size);
1387     for (uint i = 0; i < node_size; i++) {
1388       recalc_pressure_nodes[i] = 0;
1389     }
1390   }
1391 
1392   _regalloc = &regalloc;
1393 
1394 #ifndef PRODUCT
1395   if (trace_opto_pipelining()) {
1396     tty->print("\n---- Start Local Scheduling ----\n");
1397   }
1398 #endif
1399 
1400   // Schedule locally.  Right now a simple topological sort.
1401   // Later, do a real latency aware scheduler.
1402   GrowableArray<int> ready_cnt(C->unique(), C->unique(), -1);
1403   visited.Clear();
1404   for (uint i = 0; i < number_of_blocks(); i++) {
1405     Block* block = get_block(i);
1406     if (!schedule_local(block, ready_cnt, visited, recalc_pressure_nodes)) {
1407       if (!C->failure_reason_is(C2Compiler::retry_no_subsuming_loads())) {
1408         C->record_method_not_compilable("local schedule failed");
1409       }
1410       _regalloc = NULL;
1411       return;
1412     }
1413   }
1414   _regalloc = NULL;
1415 
1416   // If we inserted any instructions between a Call and his CatchNode,
1417   // clone the instructions on all paths below the Catch.
1418   for (uint i = 0; i < number_of_blocks(); i++) {
1419     Block* block = get_block(i);
1420     call_catch_cleanup(block);
1421   }
1422 
1423 #ifndef PRODUCT
1424   if (trace_opto_pipelining()) {
1425     tty->print("\n---- After GlobalCodeMotion ----\n");
1426     for (uint i = 0; i < number_of_blocks(); i++) {
1427       Block* block = get_block(i);
1428       block->dump();
1429     }
1430   }
1431 #endif
1432   // Dead.
1433   _node_latency = (GrowableArray<uint> *)0xdeadbeef;
1434 }


< prev index next >