From a350f0d60852a0ac7fa6d6c832e0bc6017d8734c Mon Sep 17 00:00:00 2001 From: "dcarney@chromium.org" Date: Thu, 6 Nov 2014 12:56:18 +0000 Subject: [PATCH] [turbofan] phis cannot take registers as inputs BUG= R=bmeurer@chromium.org Review URL: https://codereview.chromium.org/704153002 Cr-Commit-Position: refs/heads/master@{#25191} git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@25191 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/compiler/register-allocator.cc | 8 +++- .../compiler/regress-register-allocator3.js | 46 ++++++++++++++++++ .../compiler/register-allocator-unittest.cc | 55 ++++++++++++++++++++++ 3 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 test/mjsunit/compiler/regress-register-allocator3.js diff --git a/src/compiler/register-allocator.cc b/src/compiler/register-allocator.cc index c65b906..23a7df6 100644 --- a/src/compiler/register-allocator.cc +++ b/src/compiler/register-allocator.cc @@ -1525,7 +1525,13 @@ void RegisterAllocator::BuildLiveRanges() { for (UsePosition* pos = range->first_pos(); pos != NULL; pos = pos->next_) { pos->register_beneficial_ = true; - pos->requires_reg_ = true; + // TODO(dcarney): should the else case assert requires_reg_ == false? + // Can't mark phis as needing a register. + if (!code() + ->InstructionAt(pos->pos().InstructionIndex()) + ->IsGapMoves()) { + pos->requires_reg_ = true; + } } } } diff --git a/test/mjsunit/compiler/regress-register-allocator3.js b/test/mjsunit/compiler/regress-register-allocator3.js new file mode 100644 index 0000000..f412c57 --- /dev/null +++ b/test/mjsunit/compiler/regress-register-allocator3.js @@ -0,0 +1,46 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + + +function Module() { + "use asm"; + function f() { + var $0 = 0, $25 = 0, $i$014$i = 0, $sum$013$i = 0, $v_0$01$i = 0, $v_1$02$i = 0, $v_10$011$i = 0, $v_11$012$i = 0, $v_2$03$i = 0, $v_3$04$i = 0, $v_4$05$i = 0, $v_5$06$i = 0, $v_6$07$i = 0, $v_7$08$i = 0, $v_8$09$i = 0, $v_9$010$i = 0; + $i$014$i = 0; + $sum$013$i = 0; + $v_0$01$i = 8; + $v_1$02$i = 9; + $v_10$011$i = 18; + $v_11$012$i = 19; + $v_2$03$i = 10; + $v_3$04$i = 11; + $v_4$05$i = 12; + $v_5$06$i = 13; + $v_6$07$i = 14; + $v_7$08$i = 15; + $v_8$09$i = 16; + $v_9$010$i = 17; + do { + $v_0$01$i = $v_3$04$i + $v_9$010$i + $v_0$01$i | 0; + $v_1$02$i = $v_4$05$i + $v_10$011$i + $v_1$02$i | 0; + $v_2$03$i = $v_5$06$i + $v_11$012$i + $v_2$03$i | 0; + $v_3$04$i = $v_3$04$i + $v_6$07$i + $v_0$01$i | 0; + $v_4$05$i = $v_4$05$i + $v_7$08$i + $v_1$02$i | 0; + $v_5$06$i = $v_5$06$i + $v_8$09$i + $v_2$03$i | 0; + $v_6$07$i = $v_6$07$i + $v_9$010$i + $v_3$04$i | 0; + $v_7$08$i = $v_7$08$i + $v_10$011$i + $v_4$05$i | 0; + $v_8$09$i = $v_8$09$i + $v_11$012$i + $v_5$06$i | 0; + $v_9$010$i = $v_0$01$i + $v_9$010$i + $v_6$07$i | 0; + $v_10$011$i = $v_1$02$i + $v_10$011$i + $v_7$08$i | 0; + $v_11$012$i = $v_2$03$i + $v_11$012$i + $v_8$09$i | 0; + $25 = $v_0$01$i + $v_1$02$i | 0; + $sum$013$i = $v_2$03$i + $sum$013$i + $v_5$06$i + $v_4$05$i + $v_8$09$i + $v_3$04$i + $25 + $v_7$08$i + $v_11$012$i + $v_6$07$i + $v_10$011$i + $v_9$010$i | 0; + $i$014$i = $i$014$i + 1 | 0; + } while (($i$014$i | 0) <= 0); + return $sum$013$i - ($v_5$06$i + $v_2$03$i + $v_4$05$i + $v_8$09$i + $25 + $v_3$04$i + $v_7$08$i + $v_11$012$i + $v_6$07$i + $v_10$011$i + $v_9$010$i); + } + return { f: f }; +} + +Module().f(); diff --git a/test/unittests/compiler/register-allocator-unittest.cc b/test/unittests/compiler/register-allocator-unittest.cc index b1597c1..dbcdedb 100644 --- a/test/unittests/compiler/register-allocator-unittest.cc +++ b/test/unittests/compiler/register-allocator-unittest.cc @@ -453,6 +453,61 @@ TEST_F(RegisterAllocatorTest, SimpleBranch) { Allocate(); } + +TEST_F(RegisterAllocatorTest, RegressionPhisNeedTooManyRegisters) { + const size_t kNumRegs = 3; + const size_t kParams = kNumRegs + 1; + int parameters[kParams]; + + // Override number of registers. + SetNumRegs(kNumRegs, kNumRegs); + + // Initial block. + StartBlock(); + int constant = DefineConstant(); + for (size_t i = 0; i < arraysize(parameters); ++i) { + parameters[i] = DefineConstant(); + } + EndBlock(); + + PhiInstruction* phis[kParams]; + { + StartLoop(2); + + // Loop header. + StartBlock(); + + for (size_t i = 0; i < arraysize(parameters); ++i) { + phis[i] = Phi(parameters[i]); + } + + // Perform some computations. + // something like phi[i] += const + for (size_t i = 0; i < arraysize(parameters); ++i) { + int result = NewReg(); + EmitFRU(result, phis[i]->virtual_register(), constant); + phis[i]->operands().push_back(result); + } + + EndBlock(Branch(DefineConstant(), 1, 2)); + + // Jump back to loop header. + StartBlock(); + EndBlock(Jump(-1)); + + EndLoop(); + } + + // End block. + StartLastBlock(); + + // Return sum. + Return(DefineConstant()); + EndBlock(); + + Allocate(); +} + } // namespace compiler } // namespace internal } // namespace v8 -- 2.7.4