Reviewers: jarin,
https://codereview.chromium.org/748773002/diff/1/src/compiler/graph-visualizer.cc
File src/compiler/graph-visualizer.cc (right):
https://codereview.chromium.org/748773002/diff/1/src/compiler/graph-visualizer.cc#newcode726
src/compiler/graph-visualizer.cc:726: int index = -1;
On 2014/11/21 10:55:39, jarin wrote:
How about DCHECK((range->TopLevel()->GetSpillRange() != nullptr) ==
FLAG_turbo_reuse_spill_slots)?
benedikt saw a crash here, so i was fixing it - nothing to do with this
cl
https://codereview.chromium.org/748773002/diff/1/src/compiler/register-allocator.cc
File src/compiler/register-allocator.cc (right):
https://codereview.chromium.org/748773002/diff/1/src/compiler/register-allocator.cc#newcode549
src/compiler/register-allocator.cc:549:
use_spill_ranges_(FLAG_turbo_reuse_spill_slots) {
On 2014/11/21 10:55:39, jarin wrote:
Why is there this extra indirection? Can't we use the naked flag?
(That will
simplify the removal once we are done.)
ok
https://codereview.chromium.org/748773002/diff/1/src/flag-definitions.h
File src/flag-definitions.h (right):
https://codereview.chromium.org/748773002/diff/1/src/flag-definitions.h#newcode391
src/flag-definitions.h:391: DEFINE_BOOL(turbo_reuse_spill_slots, false,
"reuse spill slots in TurboFan")
On 2014/11/21 10:55:39, jarin wrote:
Please, add a TODO explaining that this is just temporary for
experimentation.
okay
Description:
[turbofan] put spill slot reuse behind a flag
BUG=
Please review this at https://codereview.chromium.org/748773002/
Base URL: https://chromium.googlesource.com/v8/v8.git@master
Affected files (+60, -3 lines):
M src/compiler/graph-visualizer.cc
M src/compiler/pipeline.cc
M src/compiler/register-allocator.h
M src/compiler/register-allocator.cc
M src/flag-definitions.h
Index: src/compiler/graph-visualizer.cc
diff --git a/src/compiler/graph-visualizer.cc
b/src/compiler/graph-visualizer.cc
index
40b182a34c881352cef2b3242db5b1860e83e6a6..c9be0ac5ac2450f0f2bb2cde4a442aa0a264c11f
100644
--- a/src/compiler/graph-visualizer.cc
+++ b/src/compiler/graph-visualizer.cc
@@ -724,7 +724,8 @@ void GraphC1Visualizer::PrintLiveRange(LiveRange*
range, const char* type) {
}
} else if (range->IsSpilled()) {
int index = -1;
- if (range->TopLevel()->GetSpillRange()->id() != -1) {
+ if (range->TopLevel()->GetSpillRange() != nullptr &&
+ range->TopLevel()->GetSpillRange()->id() != -1) {
index = range->TopLevel()->GetSpillRange()->id();
} else {
index = range->TopLevel()->GetSpillOperand()->index();
Index: src/compiler/pipeline.cc
diff --git a/src/compiler/pipeline.cc b/src/compiler/pipeline.cc
index
10bbe7c1bc6d38e5b962b0646d6465b4b0e811cf..e5460d1fad6b0ad18221e1defa19d23b52e33fc1
100644
--- a/src/compiler/pipeline.cc
+++ b/src/compiler/pipeline.cc
@@ -944,7 +944,9 @@ void Pipeline::AllocateRegisters(const
RegisterConfiguration* config,
data->set_compilation_failed();
return;
}
- Run<ReuseSpillSlotsPhase>();
+ if (FLAG_turbo_reuse_spill_slots) {
+ Run<ReuseSpillSlotsPhase>();
+ }
Run<PopulatePointerMapsPhase>();
Run<ConnectRangesPhase>();
Run<ResolveControlFlowPhase>();
Index: src/compiler/register-allocator.cc
diff --git a/src/compiler/register-allocator.cc
b/src/compiler/register-allocator.cc
index
59d80c6f7c6fbfadda50fde5fac33da698b22892..283603a44e1728e6a9c8ae82b79fa053415a5c73
100644
--- a/src/compiler/register-allocator.cc
+++ b/src/compiler/register-allocator.cc
@@ -881,6 +881,8 @@ void SpillRange::MergeDisjointIntervals(UseInterval*
other, Zone* zone) {
void RegisterAllocator::ReuseSpillSlots() {
+ DCHECK(FLAG_turbo_reuse_spill_slots);
+
// Merge disjoint spill ranges
for (int i = 0; i < spill_ranges_.length(); i++) {
SpillRange* range = spill_ranges_.at(i);
@@ -915,6 +917,7 @@ void RegisterAllocator::ReuseSpillSlots() {
SpillRange* RegisterAllocator::AssignSpillRangeToLiveRange(LiveRange*
range) {
+ DCHECK(FLAG_turbo_reuse_spill_slots);
int spill_id = spill_ranges_.length();
SpillRange* spill_range =
new (local_zone()) SpillRange(range, spill_id, local_zone());
@@ -1932,10 +1935,40 @@ bool RegisterAllocator::UnhandledIsSorted() {
}
+void RegisterAllocator::FreeSpillSlot(LiveRange* range) {
+ DCHECK(!FLAG_turbo_reuse_spill_slots);
+ // Check that we are the last range.
+ if (range->next() != NULL) return;
+
+ if (!range->TopLevel()->HasAllocatedSpillOperand()) return;
+
+ InstructionOperand* spill_operand = range->TopLevel()->GetSpillOperand();
+ if (spill_operand->IsConstant()) return;
+ if (spill_operand->index() >= 0) {
+ reusable_slots_.Add(range, local_zone());
+ }
+}
+
+
+InstructionOperand* RegisterAllocator::TryReuseSpillSlot(LiveRange* range)
{
+ DCHECK(!FLAG_turbo_reuse_spill_slots);
+ if (reusable_slots_.is_empty()) return NULL;
+ if (reusable_slots_.first()->End().Value() >
+ range->TopLevel()->Start().Value()) {
+ return NULL;
+ }
+ InstructionOperand* result =
+ reusable_slots_.first()->TopLevel()->GetSpillOperand();
+ reusable_slots_.Remove(0);
+ return result;
+}
+
+
void RegisterAllocator::ActiveToHandled(LiveRange* range) {
DCHECK(active_live_ranges_.Contains(range));
active_live_ranges_.RemoveElement(range);
TraceAlloc("Moving live range %d from active to handled\n", range->id());
+ if (!FLAG_turbo_reuse_spill_slots) FreeSpillSlot(range);
}
@@ -1951,6 +1984,7 @@ void RegisterAllocator::InactiveToHandled(LiveRange*
range) {
DCHECK(inactive_live_ranges_.Contains(range));
inactive_live_ranges_.RemoveElement(range);
TraceAlloc("Moving live range %d from inactive to handled\n",
range->id());
+ if (!FLAG_turbo_reuse_spill_slots) FreeSpillSlot(range);
}
@@ -2335,7 +2369,23 @@ void RegisterAllocator::Spill(LiveRange* range) {
LiveRange* first = range->TopLevel();
if (!first->HasAllocatedSpillOperand()) {
- AssignSpillRangeToLiveRange(first);
+ if (FLAG_turbo_reuse_spill_slots) {
+ AssignSpillRangeToLiveRange(first);
+ } else {
+ InstructionOperand* op = TryReuseSpillSlot(range);
+ if (op == NULL) {
+ // Allocate a new operand referring to the spill slot.
+ RegisterKind kind = range->Kind();
+ int index = frame()->AllocateSpillSlot(kind == DOUBLE_REGISTERS);
+ if (kind == DOUBLE_REGISTERS) {
+ op = DoubleStackSlotOperand::Create(index, local_zone());
+ } else {
+ DCHECK(kind == GENERAL_REGISTERS);
+ op = StackSlotOperand::Create(index, local_zone());
+ }
+ }
+ first->SetSpillOperand(op);
+ }
}
range->MakeSpilled(code_zone());
}
Index: src/compiler/register-allocator.h
diff --git a/src/compiler/register-allocator.h
b/src/compiler/register-allocator.h
index
5fbb821ccfbcb90a252caff1a5770342a538511f..8499a7981a510193bfd28e2b569b3b3bea37552a
100644
--- a/src/compiler/register-allocator.h
+++ b/src/compiler/register-allocator.h
@@ -457,6 +457,8 @@ class RegisterAllocator FINAL : public ZoneObject {
bool TryAllocateFreeReg(LiveRange* range);
void AllocateBlockedReg(LiveRange* range);
SpillRange* AssignSpillRangeToLiveRange(LiveRange* range);
+ void FreeSpillSlot(LiveRange* range);
+ InstructionOperand* TryReuseSpillSlot(LiveRange* range);
// Live range splitting helpers.
Index: src/flag-definitions.h
diff --git a/src/flag-definitions.h b/src/flag-definitions.h
index
0d7363e8f52828e32617ba7f382325771226df7e..adc730fc44f116d4412b88e666088e9ee22ca054
100644
--- a/src/flag-definitions.h
+++ b/src/flag-definitions.h
@@ -388,6 +388,8 @@ DEFINE_BOOL(loop_assignment_analysis, true, "perform
loop assignment analysis")
DEFINE_IMPLICATION(turbo_inlining_intrinsics, turbo_inlining)
DEFINE_IMPLICATION(turbo_inlining, turbo_types)
DEFINE_BOOL(turbo_profiling, false, "enable profiling in TurboFan")
+// TODO(dcarney): this is just for experimentation, remove when default.
+DEFINE_BOOL(turbo_reuse_spill_slots, false, "reuse spill slots in
TurboFan")
DEFINE_INT(typed_array_max_size_in_heap, 64,
"threshold for in-heap typed array")
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.