< prev index next >
src/share/vm/opto/gcm.cpp
Print this page
@@ -32,10 +32,11 @@
#include "opto/machnode.hpp"
#include "opto/opcodes.hpp"
#include "opto/phaseX.hpp"
#include "opto/rootnode.hpp"
#include "opto/runtime.hpp"
+#include "opto/chaitin.hpp"
#include "runtime/deoptimization.hpp"
// Portions of code courtesy of Clifford Click
// Optimization - Graph Style
@@ -1361,10 +1362,50 @@
// above, this prevents SEGV storms reported in 6366351,
// by recompiling offending methods without this optimization.
}
}
+ PhaseChaitin regalloc(C->unique(), *this, _matcher, true);
+ ResourceArea live_arena; // Arena for liveness
+ ResourceMark rm_live(&live_arena);
+ PhaseLive live(*this, regalloc._lrg_map.names(), &live_arena, true);
+ PhaseIFG ifg(&live_arena);
+ intptr_t *recalc_pressure_nodes = NULL;
+
+ bool block_size_threshold_ok = false;
+ if (OptoRegScheduling) {
+ for (uint i = 0; i < number_of_blocks(); i++) {
+ Block* block = get_block(i);
+ if (block->number_of_nodes() > 10) {
+ block_size_threshold_ok = true;
+ break;
+ }
+ }
+ }
+
+ // Enabling the scheduler for register pressure plus finding blocks of size to schedule for it
+ // is key to enabling this feature.
+ if (OptoRegScheduling && block_size_threshold_ok) {
+ regalloc.mark_ssa();
+ Compile::TracePhase tp("computeLive", &timers[_t_computeLive]);
+ rm_live.reset_to_mark(); // Reclaim working storage
+ IndexSet::reset_memory(C, &live_arena);
+ uint node_size = regalloc._lrg_map.max_lrg_id();
+ ifg.init(node_size); // Empty IFG
+ regalloc.set_ifg(ifg);
+ regalloc.set_live(live);
+ regalloc.gather_lrg_masks(false); // Collect LRG masks
+ live.compute(node_size); // Compute liveness
+
+ recalc_pressure_nodes = NEW_RESOURCE_ARRAY(intptr_t, node_size);
+ for (uint i = 0; i < node_size; i++) {
+ recalc_pressure_nodes[i] = 0;
+ }
+ }
+
+ _regalloc = ®alloc;
+
#ifndef PRODUCT
if (trace_opto_pipelining()) {
tty->print("\n---- Start Local Scheduling ----\n");
}
#endif
@@ -1373,17 +1414,19 @@
// Later, do a real latency aware scheduler.
GrowableArray<int> ready_cnt(C->unique(), C->unique(), -1);
visited.Clear();
for (uint i = 0; i < number_of_blocks(); i++) {
Block* block = get_block(i);
- if (!schedule_local(block, ready_cnt, visited)) {
+ if (!schedule_local(block, ready_cnt, visited, recalc_pressure_nodes)) {
if (!C->failure_reason_is(C2Compiler::retry_no_subsuming_loads())) {
C->record_method_not_compilable("local schedule failed");
}
+ _regalloc = NULL;
return;
}
}
+ _regalloc = NULL;
// If we inserted any instructions between a Call and his CatchNode,
// clone the instructions on all paths below the Catch.
for (uint i = 0; i < number_of_blocks(); i++) {
Block* block = get_block(i);
< prev index next >