Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1222)

Unified Diff: runtime/vm/flow_graph_allocator.cc

Issue 12946004: Register allocation tweaks: (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/flow_graph_allocator.cc
diff --git a/runtime/vm/flow_graph_allocator.cc b/runtime/vm/flow_graph_allocator.cc
index 03723f4912b0a70c648e673e53fe4dd1be3c053b..5024030dd0841276574e642abcb4cbb196c21a15 100644
--- a/runtime/vm/flow_graph_allocator.cc
+++ b/runtime/vm/flow_graph_allocator.cc
@@ -510,6 +510,19 @@ static bool HasOnlyUnconstrainedUsesInLoop(LiveRange* range,
}
+// Returns true if all uses of the given range have Any allocation policy.
+static bool HasOnlyUnconstrainedUses(LiveRange* range) {
+ UsePosition* use = range->first_use();
+ while (use != NULL) {
+ if (!use->location_slot()->Equals(Location::Any())) {
+ return false;
+ }
+ use = use->next();
+ }
+ return true;
+}
+
+
void FlowGraphAllocator::BuildLiveRanges() {
const intptr_t block_count = postorder_.length();
ASSERT(postorder_.Last()->IsGraphEntry());
@@ -532,6 +545,10 @@ void FlowGraphAllocator::BuildLiveRanges() {
current_interference_set =
new BitVector(flow_graph_.max_virtual_register_number());
ASSERT(loop_header->backedge_interference() == NULL);
+ // All values flowing into the loop header are live at the back-edge and
+ // can interfere with phi moves.
+ current_interference_set->AddAll(
+ live_in_[loop_header->entry()->postorder_number()]);
loop_header->set_backedge_interference(
current_interference_set);
}
@@ -828,13 +845,30 @@ void FlowGraphAllocator::ProcessOneInstruction(BlockEntryInstr* block,
LocationSummary* locs = current->locs();
Definition* def = current->AsDefinition();
- if ((def != NULL) &&
- (def->AsConstant() != NULL) &&
- ((def->ssa_temp_index() == -1) ||
- (GetLiveRange(def->ssa_temp_index())->first_use() == NULL))) {
+ if ((def != NULL) && (def->AsConstant() != NULL)) {
+ LiveRange* range = (def->ssa_temp_index() != -1) ?
+ GetLiveRange(def->ssa_temp_index()) : NULL;
+
// Drop definitions of constants that have no uses.
- locs->set_out(Location::NoLocation());
- return;
+ if ((range == NULL) || (range->first_use() == NULL)) {
+ locs->set_out(Location::NoLocation());
+ return;
+ }
+
+ // If this constant has only unconstrained uses convert them all
+ // to use the constant directly and drop this definition.
+ // TODO(vegorov): improve allocation when we have enough registers to keep
+ // constants used in the loop in them.
+ if (HasOnlyUnconstrainedUses(range)) {
+ const Object& value = def->AsConstant()->value();
+ range->set_assigned_location(Location::Constant(value));
+ range->set_spill_slot(Location::Constant(value));
+ range->finger()->Initialize(range);
+ ConvertAllUses(range);
+
+ locs->set_out(Location::NoLocation());
+ return;
+ }
}
const intptr_t pos = current->lifetime_position();
@@ -1709,7 +1743,7 @@ bool FlowGraphAllocator::AllocateFreeRegister(LiveRange* unallocated) {
hint.Name(),
unallocated->vreg(),
free_until));
- } else if (free_until != kMaxPosition) {
+ } else {
for (intptr_t reg = 0; reg < NumberOfRegisters(); ++reg) {
if (!blocked_registers_[reg] && (registers_[reg].length() == 0)) {
candidate = reg;
@@ -1719,6 +1753,23 @@ bool FlowGraphAllocator::AllocateFreeRegister(LiveRange* unallocated) {
}
}
+ ASSERT(0 <= kMaxPosition);
+ if (free_until != kMaxPosition) {
+ for (intptr_t reg = 0; reg < NumberOfRegisters(); ++reg) {
+ if (blocked_registers_[reg] || (reg == candidate)) continue;
+ const intptr_t intersection =
+ FirstIntersectionWithAllocated(reg, unallocated);
+ if (intersection > free_until) {
+ candidate = reg;
+ free_until = intersection;
+ if (free_until == kMaxPosition) break;
+ }
+ }
+ }
+
+ // All registers are blocked by active ranges.
+ if (free_until <= unallocated->Start()) return false;
+
// We have a very good candidate (either hinted to us or completely free).
// If we are in a loop try to reduce number of moves on the back edge by
// searching for a candidate that does not interfere with phis on the back
@@ -1778,23 +1829,6 @@ bool FlowGraphAllocator::AllocateFreeRegister(LiveRange* unallocated) {
}
}
- ASSERT(0 <= kMaxPosition);
- if (free_until != kMaxPosition) {
- for (intptr_t reg = 0; reg < NumberOfRegisters(); ++reg) {
- if (blocked_registers_[reg] || (reg == candidate)) continue;
- const intptr_t intersection =
- FirstIntersectionWithAllocated(reg, unallocated);
- if (intersection > free_until) {
- candidate = reg;
- free_until = intersection;
- if (free_until == kMaxPosition) break;
- }
- }
- }
-
- // All registers are blocked by active ranges.
- if (free_until <= unallocated->Start()) return false;
-
TRACE_ALLOC(OS::Print("assigning free register "));
TRACE_ALLOC(MakeRegisterLocation(candidate, kUnboxedDouble).Print());
TRACE_ALLOC(OS::Print(" to v%"Pd"\n", unallocated->vreg()));
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698