v8/test/cctest/compiler/test-code-generator.cc

1426 lines
57 KiB
C++
Raw Normal View History

Reland "[arm] Restrict grouping pushes before a TailCall to registers only" This is a reland of a72b2f88a8cb44f12002f1168c639e07db9d5600 Original change's description: > [arm] Restrict grouping pushes before a TailCall to registers only > > We optimize parallel moves performed before a TailCall by grouping adjacent > pushes. This way, we may use a single instruction to push multiple registers at > once. However, we also have support for pushing immediates and stack slots for > which the benefit is questionnable therefore this patch removes support for > them. > > Concerning immediate pushes, it looks like a mistake since we do not have > support for this case in `AssembleMove` so this patch removes it. Furthermore, > if we add a test for this case, we see that a `push ip` instruction is > generated, effectively pushing whatever was in `ip` at the time instead of > pushing a constant. > > Concerning stack slot pushes, we generate a more or less equivalent sequence of > instructions. > > Finally, grouping floating point pushes is not used anywhere so this patch > removes support for this also. > > Bug: v8:6553 > Change-Id: I9b820d33361fc442dd813f66e1f96cda41009110 > Reviewed-on: https://chromium-review.googlesource.com/567191 > Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> > Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> > Cr-Commit-Position: refs/heads/master@{#46718} Bug: v8:6553 Change-Id: Ib9a55dae7cc5db6185d163c56088ff23426d04bb Reviewed-on: https://chromium-review.googlesource.com/576087 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Cr-Commit-Position: refs/heads/master@{#46754}
2017-07-13 09:55:16 +00:00
// Copyright 2017 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.
#include "src/base/utils/random-number-generator.h"
#include "src/codegen/assembler-inl.h"
#include "src/codegen/code-stub-assembler.h"
#include "src/codegen/optimized-compilation-info.h"
#include "src/compiler/backend/code-generator.h"
#include "src/compiler/backend/instruction.h"
Reland "[arm] Restrict grouping pushes before a TailCall to registers only" This is a reland of a72b2f88a8cb44f12002f1168c639e07db9d5600 Original change's description: > [arm] Restrict grouping pushes before a TailCall to registers only > > We optimize parallel moves performed before a TailCall by grouping adjacent > pushes. This way, we may use a single instruction to push multiple registers at > once. However, we also have support for pushing immediates and stack slots for > which the benefit is questionnable therefore this patch removes support for > them. > > Concerning immediate pushes, it looks like a mistake since we do not have > support for this case in `AssembleMove` so this patch removes it. Furthermore, > if we add a test for this case, we see that a `push ip` instruction is > generated, effectively pushing whatever was in `ip` at the time instead of > pushing a constant. > > Concerning stack slot pushes, we generate a more or less equivalent sequence of > instructions. > > Finally, grouping floating point pushes is not used anywhere so this patch > removes support for this also. > > Bug: v8:6553 > Change-Id: I9b820d33361fc442dd813f66e1f96cda41009110 > Reviewed-on: https://chromium-review.googlesource.com/567191 > Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> > Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> > Cr-Commit-Position: refs/heads/master@{#46718} Bug: v8:6553 Change-Id: Ib9a55dae7cc5db6185d163c56088ff23426d04bb Reviewed-on: https://chromium-review.googlesource.com/576087 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Cr-Commit-Position: refs/heads/master@{#46754}
2017-07-13 09:55:16 +00:00
#include "src/compiler/linkage.h"
#include "src/execution/isolate.h"
#include "src/objects/heap-number-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/smi.h"
Reland "[arm] Restrict grouping pushes before a TailCall to registers only" This is a reland of a72b2f88a8cb44f12002f1168c639e07db9d5600 Original change's description: > [arm] Restrict grouping pushes before a TailCall to registers only > > We optimize parallel moves performed before a TailCall by grouping adjacent > pushes. This way, we may use a single instruction to push multiple registers at > once. However, we also have support for pushing immediates and stack slots for > which the benefit is questionnable therefore this patch removes support for > them. > > Concerning immediate pushes, it looks like a mistake since we do not have > support for this case in `AssembleMove` so this patch removes it. Furthermore, > if we add a test for this case, we see that a `push ip` instruction is > generated, effectively pushing whatever was in `ip` at the time instead of > pushing a constant. > > Concerning stack slot pushes, we generate a more or less equivalent sequence of > instructions. > > Finally, grouping floating point pushes is not used anywhere so this patch > removes support for this also. > > Bug: v8:6553 > Change-Id: I9b820d33361fc442dd813f66e1f96cda41009110 > Reviewed-on: https://chromium-review.googlesource.com/567191 > Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> > Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> > Cr-Commit-Position: refs/heads/master@{#46718} Bug: v8:6553 Change-Id: Ib9a55dae7cc5db6185d163c56088ff23426d04bb Reviewed-on: https://chromium-review.googlesource.com/576087 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Cr-Commit-Position: refs/heads/master@{#46754}
2017-07-13 09:55:16 +00:00
#include "test/cctest/cctest.h"
#include "test/cctest/compiler/code-assembler-tester.h"
#include "test/cctest/compiler/function-tester.h"
Reland "[arm] Restrict grouping pushes before a TailCall to registers only" This is a reland of a72b2f88a8cb44f12002f1168c639e07db9d5600 Original change's description: > [arm] Restrict grouping pushes before a TailCall to registers only > > We optimize parallel moves performed before a TailCall by grouping adjacent > pushes. This way, we may use a single instruction to push multiple registers at > once. However, we also have support for pushing immediates and stack slots for > which the benefit is questionnable therefore this patch removes support for > them. > > Concerning immediate pushes, it looks like a mistake since we do not have > support for this case in `AssembleMove` so this patch removes it. Furthermore, > if we add a test for this case, we see that a `push ip` instruction is > generated, effectively pushing whatever was in `ip` at the time instead of > pushing a constant. > > Concerning stack slot pushes, we generate a more or less equivalent sequence of > instructions. > > Finally, grouping floating point pushes is not used anywhere so this patch > removes support for this also. > > Bug: v8:6553 > Change-Id: I9b820d33361fc442dd813f66e1f96cda41009110 > Reviewed-on: https://chromium-review.googlesource.com/567191 > Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> > Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> > Cr-Commit-Position: refs/heads/master@{#46718} Bug: v8:6553 Change-Id: Ib9a55dae7cc5db6185d163c56088ff23426d04bb Reviewed-on: https://chromium-review.googlesource.com/576087 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Cr-Commit-Position: refs/heads/master@{#46754}
2017-07-13 09:55:16 +00:00
namespace v8 {
namespace internal {
namespace compiler {
#define __ assembler.
namespace {
int GetSlotSizeInBytes(MachineRepresentation rep) {
switch (rep) {
case MachineRepresentation::kTagged:
// Spill slots for tagged values are always uncompressed.
return kSystemPointerSize;
case MachineRepresentation::kFloat32:
return kSystemPointerSize;
case MachineRepresentation::kFloat64:
return kDoubleSize;
case MachineRepresentation::kSimd128:
return kSimd128Size;
default:
break;
}
UNREACHABLE();
}
// Forward declaration.
Handle<Code> BuildTeardownFunction(Isolate* isolate,
CallDescriptor* call_descriptor,
std::vector<AllocatedOperand> parameters);
// Build the `setup` function. It takes a code object and a FixedArray as
// parameters and calls the former while passing it each element of the array as
// arguments:
// ~~~
// FixedArray setup(CodeObject* test, FixedArray state_in) {
// FixedArray state_out = AllocateZeroedFixedArray(state_in.length());
// // `test` will tail-call to its first parameter which will be `teardown`.
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
// return test(teardown, state_out, state_in[0], state_in[1],
// state_in[2], ...);
// }
// ~~~
//
// This function needs to convert each element of the FixedArray to raw unboxed
// values to pass to the `test` function. The array will have been created using
// `GenerateInitialState()` and needs to be converted in the following way:
//
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
// | Parameter type | FixedArray element | Conversion |
// |----------------+---------------------+------------------------------------|
// | kTagged | Smi | None. |
// | kFloat32 | HeapNumber | Load value and convert to Float32. |
// | kFloat64 | HeapNumber | Load value. |
// | kSimd128 | FixedArray<Smi>[4] | Untag each Smi and write the |
// | | | results into lanes of a new |
// | | | 128-bit vector. |
//
Handle<Code> BuildSetupFunction(Isolate* isolate,
CallDescriptor* call_descriptor,
std::vector<AllocatedOperand> parameters) {
CodeAssemblerTester tester(isolate, 2, Code::BUILTIN, "setup");
CodeStubAssembler assembler(tester.state());
std::vector<Node*> params;
// The first parameter is always the callee.
params.push_back(__ Parameter(0));
params.push_back(__ HeapConstant(
BuildTeardownFunction(isolate, call_descriptor, parameters)));
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
// First allocate the FixedArray which will hold the final results. Here we
// should take care of all allocations, meaning we allocate HeapNumbers and
// FixedArrays representing Simd128 values.
TNode<FixedArray> state_out =
__ AllocateZeroedFixedArray(__ IntPtrConstant(parameters.size()));
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
for (int i = 0; i < static_cast<int>(parameters.size()); i++) {
switch (parameters[i].representation()) {
case MachineRepresentation::kTagged:
break;
case MachineRepresentation::kFloat32:
case MachineRepresentation::kFloat64:
__ StoreFixedArrayElement(state_out, i, __ AllocateHeapNumber());
break;
case MachineRepresentation::kSimd128: {
TNode<FixedArray> vector =
__ AllocateZeroedFixedArray(__ IntPtrConstant(4));
for (int lane = 0; lane < 4; lane++) {
__ StoreFixedArrayElement(vector, lane, __ SmiConstant(0));
}
__ StoreFixedArrayElement(state_out, i, vector);
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
break;
}
default:
UNREACHABLE();
break;
}
}
params.push_back(state_out);
// Then take each element of the initial state and pass them as arguments.
TNode<FixedArray> state_in = __ Cast(__ Parameter(1));
for (int i = 0; i < static_cast<int>(parameters.size()); i++) {
Node* element = __ LoadFixedArrayElement(state_in, __ IntPtrConstant(i));
// Unbox all elements before passing them as arguments.
switch (parameters[i].representation()) {
// Tagged parameters are Smis, they do not need unboxing.
case MachineRepresentation::kTagged:
break;
case MachineRepresentation::kFloat32:
element = __ TruncateFloat64ToFloat32(__ LoadHeapNumberValue(element));
break;
case MachineRepresentation::kFloat64:
element = __ LoadHeapNumberValue(element);
break;
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
case MachineRepresentation::kSimd128: {
Node* vector = tester.raw_assembler_for_testing()->AddNode(
tester.raw_assembler_for_testing()->machine()->I32x4Splat(),
__ Int32Constant(0));
for (int lane = 0; lane < 4; lane++) {
TNode<Int32T> lane_value = __ LoadAndUntagToWord32FixedArrayElement(
__ CAST(element), __ IntPtrConstant(lane));
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
vector = tester.raw_assembler_for_testing()->AddNode(
tester.raw_assembler_for_testing()->machine()->I32x4ReplaceLane(
lane),
vector, lane_value);
}
element = vector;
break;
}
default:
UNREACHABLE();
break;
}
params.push_back(element);
}
__ Return(tester.raw_assembler_for_testing()->AddNode(
tester.raw_assembler_for_testing()->common()->Call(call_descriptor),
static_cast<int>(params.size()), params.data()));
return tester.GenerateCodeCloseAndEscape();
}
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
// Build the `teardown` function. It takes a FixedArray as argument, fills it
// with the rest of its parameters and returns it. The parameters need to be
// consistent with `parameters`.
// ~~~
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
// FixedArray teardown(CodeObject* /* unused */, FixedArray result,
// // Tagged registers.
// Object r0, Object r1, ...,
// // FP registers.
// Float32 s0, Float64 d1, ...,
// // Mixed stack slots.
// Float64 mem0, Object mem1, Float32 mem2, ...) {
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
// result[0] = r0;
// result[1] = r1;
// ...
// result[..] = s0;
// ...
// result[..] = mem0;
// ...
// return result;
// }
// ~~~
//
// This function needs to convert its parameters into values fit for a
// FixedArray, essentially reverting what the `setup` function did:
//
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
// | Parameter type | Parameter value | Conversion |
// |----------------+-------------------+--------------------------------------|
// | kTagged | Smi or HeapNumber | None. |
// | kFloat32 | Raw Float32 | Convert to Float64. |
// | kFloat64 | Raw Float64 | None. |
// | kSimd128 | Raw Simd128 | Split into 4 Word32 values and tag |
// | | | them. |
//
// Note that it is possible for a `kTagged` value to go from a Smi to a
// HeapNumber. This is because `AssembleMove` will allocate a new HeapNumber if
// it is asked to move a FP constant to a tagged register or slot.
//
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
// Finally, it is important that this function does not call `RecordWrite` which
// is why "setup" is in charge of all allocations and we are using
Reland: [csa] verify skipped write-barriers in MemoryOptimizer With very few exceptions, this verifies all skipped write-barriers in CSA and Torque, showing that the MemoryOptimizer together with some type information on the stored value are enough to avoid unsafe skipped write-barriers. Changes to CSA: SKIP_WRITE_BARRIER and Store*NoWriteBarrier are verified by the MemoryOptimizer by default. Type information about the stored values (TNode<Smi>) is exploited to safely skip write barriers for stored Smi values. In some cases, the code is re-structured to make it easier to consume for the MemoryOptimizer (manual branch and load elimination). Changes to the MemoryOptimizer: Improve the MemoryOptimizer to remove write barriers: - When the store happens to a CSA-generated InnerAllocate, by ignoring Bitcasts and additions. - When the stored value is the HeapConstant of an immortal immovable root. - When the stored value is a SmiConstant (recognized by BitcastToTaggedSigned). - Fast C-calls are treated as non-allocating. - Runtime calls can be white-listed as non-allocating. Remaining missing cases: - C++-style iterator loops with inner pointers. - Inner allocates that are reloaded from a field where they were just stored (for example an elements backing store). Load elimination would fix that. - Safe stored value types that cannot be expressed in CSA (e.g., Smi|Hole). We could handle that in Torque. - Double-aligned allocations, which are not lowered in the MemoryOptimizer but in CSA. Drive-by change: Avoid Smi suffix for StoreFixedArrayElement since this can be handled by overload resolution (in Torque and C++). Reland Change: Support pointer compression operands. R=jarin@chromium.org TBR=mvstanton@chromium.org Bug: v8:7793 Change-Id: I84e1831eb6bf9be14f36db3f8b485ee4fab6b22e Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1612904 Auto-Submit: Tobias Tebbi <tebbi@chromium.org> Reviewed-by: Michael Stanton <mvstanton@chromium.org> Commit-Queue: Tobias Tebbi <tebbi@chromium.org> Cr-Commit-Position: refs/heads/master@{#61522}
2019-05-15 08:45:36 +00:00
// UNSAFE_SKIP_WRITE_BARRIER. The reason for this is that `RecordWrite` may
// clobber the top 64 bits of Simd128 registers. This is the case on x64, ia32
// and Arm64 for example.
Handle<Code> BuildTeardownFunction(Isolate* isolate,
CallDescriptor* call_descriptor,
std::vector<AllocatedOperand> parameters) {
CodeAssemblerTester tester(isolate, call_descriptor, "teardown");
CodeStubAssembler assembler(tester.state());
TNode<FixedArray> result_array = __ Cast(__ Parameter(1));
for (int i = 0; i < static_cast<int>(parameters.size()); i++) {
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
// The first argument is not used and the second is "result_array".
Node* param = __ Parameter(i + 2);
switch (parameters[i].representation()) {
case MachineRepresentation::kTagged:
Reland: [csa] verify skipped write-barriers in MemoryOptimizer With very few exceptions, this verifies all skipped write-barriers in CSA and Torque, showing that the MemoryOptimizer together with some type information on the stored value are enough to avoid unsafe skipped write-barriers. Changes to CSA: SKIP_WRITE_BARRIER and Store*NoWriteBarrier are verified by the MemoryOptimizer by default. Type information about the stored values (TNode<Smi>) is exploited to safely skip write barriers for stored Smi values. In some cases, the code is re-structured to make it easier to consume for the MemoryOptimizer (manual branch and load elimination). Changes to the MemoryOptimizer: Improve the MemoryOptimizer to remove write barriers: - When the store happens to a CSA-generated InnerAllocate, by ignoring Bitcasts and additions. - When the stored value is the HeapConstant of an immortal immovable root. - When the stored value is a SmiConstant (recognized by BitcastToTaggedSigned). - Fast C-calls are treated as non-allocating. - Runtime calls can be white-listed as non-allocating. Remaining missing cases: - C++-style iterator loops with inner pointers. - Inner allocates that are reloaded from a field where they were just stored (for example an elements backing store). Load elimination would fix that. - Safe stored value types that cannot be expressed in CSA (e.g., Smi|Hole). We could handle that in Torque. - Double-aligned allocations, which are not lowered in the MemoryOptimizer but in CSA. Drive-by change: Avoid Smi suffix for StoreFixedArrayElement since this can be handled by overload resolution (in Torque and C++). Reland Change: Support pointer compression operands. R=jarin@chromium.org TBR=mvstanton@chromium.org Bug: v8:7793 Change-Id: I84e1831eb6bf9be14f36db3f8b485ee4fab6b22e Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1612904 Auto-Submit: Tobias Tebbi <tebbi@chromium.org> Reviewed-by: Michael Stanton <mvstanton@chromium.org> Commit-Queue: Tobias Tebbi <tebbi@chromium.org> Cr-Commit-Position: refs/heads/master@{#61522}
2019-05-15 08:45:36 +00:00
__ StoreFixedArrayElement(result_array, i, param,
UNSAFE_SKIP_WRITE_BARRIER);
break;
// Box FP values into HeapNumbers.
case MachineRepresentation::kFloat32:
param =
tester.raw_assembler_for_testing()->ChangeFloat32ToFloat64(param);
V8_FALLTHROUGH;
case MachineRepresentation::kFloat64:
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
__ StoreObjectFieldNoWriteBarrier(
__ LoadFixedArrayElement(result_array, i), HeapNumber::kValueOffset,
param, MachineRepresentation::kFloat64);
break;
case MachineRepresentation::kSimd128: {
TNode<FixedArray> vector =
__ Cast(__ LoadFixedArrayElement(result_array, i));
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
for (int lane = 0; lane < 4; lane++) {
Node* lane_value =
__ SmiFromInt32(tester.raw_assembler_for_testing()->AddNode(
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
tester.raw_assembler_for_testing()
->machine()
->I32x4ExtractLane(lane),
param));
__ StoreFixedArrayElement(vector, lane, lane_value,
Reland: [csa] verify skipped write-barriers in MemoryOptimizer With very few exceptions, this verifies all skipped write-barriers in CSA and Torque, showing that the MemoryOptimizer together with some type information on the stored value are enough to avoid unsafe skipped write-barriers. Changes to CSA: SKIP_WRITE_BARRIER and Store*NoWriteBarrier are verified by the MemoryOptimizer by default. Type information about the stored values (TNode<Smi>) is exploited to safely skip write barriers for stored Smi values. In some cases, the code is re-structured to make it easier to consume for the MemoryOptimizer (manual branch and load elimination). Changes to the MemoryOptimizer: Improve the MemoryOptimizer to remove write barriers: - When the store happens to a CSA-generated InnerAllocate, by ignoring Bitcasts and additions. - When the stored value is the HeapConstant of an immortal immovable root. - When the stored value is a SmiConstant (recognized by BitcastToTaggedSigned). - Fast C-calls are treated as non-allocating. - Runtime calls can be white-listed as non-allocating. Remaining missing cases: - C++-style iterator loops with inner pointers. - Inner allocates that are reloaded from a field where they were just stored (for example an elements backing store). Load elimination would fix that. - Safe stored value types that cannot be expressed in CSA (e.g., Smi|Hole). We could handle that in Torque. - Double-aligned allocations, which are not lowered in the MemoryOptimizer but in CSA. Drive-by change: Avoid Smi suffix for StoreFixedArrayElement since this can be handled by overload resolution (in Torque and C++). Reland Change: Support pointer compression operands. R=jarin@chromium.org TBR=mvstanton@chromium.org Bug: v8:7793 Change-Id: I84e1831eb6bf9be14f36db3f8b485ee4fab6b22e Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1612904 Auto-Submit: Tobias Tebbi <tebbi@chromium.org> Reviewed-by: Michael Stanton <mvstanton@chromium.org> Commit-Queue: Tobias Tebbi <tebbi@chromium.org> Cr-Commit-Position: refs/heads/master@{#61522}
2019-05-15 08:45:36 +00:00
UNSAFE_SKIP_WRITE_BARRIER);
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
}
break;
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
}
default:
UNREACHABLE();
break;
}
}
__ Return(result_array);
return tester.GenerateCodeCloseAndEscape();
}
// Print the content of `value`, representing the register or stack slot
// described by `operand`.
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
void PrintStateValue(std::ostream& os, Isolate* isolate, Handle<Object> value,
AllocatedOperand operand) {
switch (operand.representation()) {
case MachineRepresentation::kTagged:
if (value->IsSmi()) {
os << Smi::cast(*value).value();
} else {
os << value->Number();
}
break;
case MachineRepresentation::kFloat32:
case MachineRepresentation::kFloat64:
os << value->Number();
break;
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
case MachineRepresentation::kSimd128: {
FixedArray vector = FixedArray::cast(*value);
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
os << "[";
for (int lane = 0; lane < 4; lane++) {
os << Smi::cast(vector.get(lane)).value();
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
if (lane < 3) {
os << ", ";
}
}
os << "]";
break;
}
default:
UNREACHABLE();
}
os << " (" << operand.representation() << " ";
if (operand.location_kind() == AllocatedOperand::REGISTER) {
os << "register";
} else {
DCHECK_EQ(operand.location_kind(), AllocatedOperand::STACK_SLOT);
os << "stack slot";
}
os << ")";
}
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
bool TestSimd128Moves() {
return CpuFeatures::SupportsWasmSimd128();
}
} // namespace
#undef __
// Representation of a test environment. It describes a set of registers, stack
// slots and constants available to the CodeGeneratorTester to perform moves
// with. It has the ability to randomly generate lists of moves and run the code
// generated by the CodeGeneratorTester.
//
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
// The following representations are tested:
// - kTagged
// - kFloat32
// - kFloat64
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
// - kSimd128 (if supported)
// There is no need to test using Word32 or Word64 as they are the same as
// Tagged as far as the code generator is concerned.
//
// Testing the generated code is achieved by wrapping it around `setup` and
// `teardown` functions, written using the CodeStubAssembler. The key idea here
// is that `teardown` and the generated code share the same custom
// CallDescriptor. This descriptor assigns parameters to either registers or
// stack slot of a given representation and therefore essentially describes the
// environment.
//
// What happens is the following:
//
// - The `setup` function receives a FixedArray as the initial state. It
// unpacks it and passes each element as arguments to the generated code
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
// `test`. We also pass the `teardown` function as a first argument as well
// as a newly allocated FixedArray as a second argument which will hold the
// final results. Thanks to the custom CallDescriptor, registers and stack
// slots get initialised according to the content of the initial FixedArray.
//
// - The `test` function performs the list of moves on its parameters and
// eventually tail-calls to its first parameter, which is the `teardown`
// function.
//
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
// - The `teardown` function receives the final results as a FixedArray, fills
// it with the rest of its arguments and returns it. Thanks to the
// tail-call, this is as if the `setup` function called `teardown` directly,
// except now moves were performed!
//
// .----------------setup--------------------------.
// | Take a FixedArray as parameters with |
// | all the initial values of registers |
// | and stack slots. | <- CodeStubAssembler
// | |
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
// | Allocate a new FixedArray `result` with |
// | initial values. |
// | |
// | Call test(teardown, result, state[0], |
// | state[1], state[2], ...); |
// '-----------------------------------------------'
// |
// V
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
// .----------------test-------------------------------.
// | - Move(param3, param42); |
// | - Swap(param64, param4); |
// | - Move(param2, param6); | <- CodeGeneratorTester
// | ... |
// | |
// | // "teardown" is the first parameter as well as |
// | // the callee. |
// | TailCall teardown(teardown, result, param2, ...); |
// '---------------------------------------------------'
// |
// V
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
// .----------------teardown---------------------------.
// | Fill in the incoming `result` FixedArray with all |
// | parameters and return it. | <- CodeStubAssembler
// '---------------------------------------------------'
class TestEnvironment : public HandleAndZoneScope {
Reland "[arm] Restrict grouping pushes before a TailCall to registers only" This is a reland of a72b2f88a8cb44f12002f1168c639e07db9d5600 Original change's description: > [arm] Restrict grouping pushes before a TailCall to registers only > > We optimize parallel moves performed before a TailCall by grouping adjacent > pushes. This way, we may use a single instruction to push multiple registers at > once. However, we also have support for pushing immediates and stack slots for > which the benefit is questionnable therefore this patch removes support for > them. > > Concerning immediate pushes, it looks like a mistake since we do not have > support for this case in `AssembleMove` so this patch removes it. Furthermore, > if we add a test for this case, we see that a `push ip` instruction is > generated, effectively pushing whatever was in `ip` at the time instead of > pushing a constant. > > Concerning stack slot pushes, we generate a more or less equivalent sequence of > instructions. > > Finally, grouping floating point pushes is not used anywhere so this patch > removes support for this also. > > Bug: v8:6553 > Change-Id: I9b820d33361fc442dd813f66e1f96cda41009110 > Reviewed-on: https://chromium-review.googlesource.com/567191 > Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> > Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> > Cr-Commit-Position: refs/heads/master@{#46718} Bug: v8:6553 Change-Id: Ib9a55dae7cc5db6185d163c56088ff23426d04bb Reviewed-on: https://chromium-review.googlesource.com/576087 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Cr-Commit-Position: refs/heads/master@{#46754}
2017-07-13 09:55:16 +00:00
public:
// These constants may be tuned to experiment with different environments.
#ifdef V8_TARGET_ARCH_IA32
static constexpr int kGeneralRegisterCount = 3;
#else
static constexpr int kGeneralRegisterCount = 4;
#endif
static constexpr int kDoubleRegisterCount = 6;
static constexpr int kTaggedSlotCount = 64;
static constexpr int kFloat32SlotCount = 64;
static constexpr int kFloat64SlotCount = 64;
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
static constexpr int kSimd128SlotCount = 16;
// TODO(all): Test all types of constants (e.g. ExternalReference and
// HeapObject).
static constexpr int kSmiConstantCount = 4;
static constexpr int kFloatConstantCount = 4;
static constexpr int kDoubleConstantCount = 4;
TestEnvironment()
: blocks_(1, NewBlock(main_zone(), RpoNumber::FromInt(0)), main_zone()),
instructions_(main_isolate(), main_zone(), &blocks_),
rng_(CcTest::random_number_generator()),
supported_reps_({MachineRepresentation::kTagged,
MachineRepresentation::kFloat32,
MachineRepresentation::kFloat64}) {
stack_slot_count_ =
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
kTaggedSlotCount + kFloat32SlotCount + kFloat64SlotCount;
if (TestSimd128Moves()) {
stack_slot_count_ += kSimd128SlotCount;
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
supported_reps_.push_back(MachineRepresentation::kSimd128);
}
// The "teardown" and "test" functions share the same descriptor with the
// following signature:
// ~~~
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
// FixedArray f(CodeObject* teardown, FixedArray preallocated_result,
// // Tagged registers.
// Object, Object, ...,
// // FP registers.
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
// Float32, Float64, Simd128, ...,
// // Mixed stack slots.
// Float64, Object, Float32, Simd128, ...);
// ~~~
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
LocationSignature::Builder test_signature(
main_zone(), 1,
2 + kGeneralRegisterCount + kDoubleRegisterCount + stack_slot_count_);
// The first parameter will be the code object of the "teardown"
// function. This way, the "test" function can tail-call to it.
test_signature.AddParam(LinkageLocation::ForRegister(
kReturnRegister0.code(), MachineType::AnyTagged()));
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
// The second parameter will be a pre-allocated FixedArray that the
// "teardown" function will fill with result and then return. We place this
// parameter on the first stack argument slot which is always -1. And
// therefore slots to perform moves on start at -2.
test_signature.AddParam(
LinkageLocation::ForCallerFrameSlot(-1, MachineType::AnyTagged()));
int slot_parameter_n = -2;
const int kTotalStackParameterCount = stack_slot_count_ + 1;
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
// Initialise registers.
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
// Make sure that the target has enough general purpose registers to
// generate a call to a CodeObject using this descriptor. We have reserved
// kReturnRegister0 as the first parameter, and the call will need a
// register to hold the CodeObject address. So the maximum number of
// registers left to test with is the number of available registers minus 2.
DCHECK_LE(kGeneralRegisterCount,
GetRegConfig()->num_allocatable_general_registers() - 2);
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
int32_t general_mask = GetRegConfig()->allocatable_general_codes_mask();
// kReturnRegister0 is used to hold the "teardown" code object, do not
// generate moves using it.
std::unique_ptr<const RegisterConfiguration> registers(
RegisterConfiguration::RestrictGeneralRegisters(
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
general_mask & ~kReturnRegister0.bit()));
for (int i = 0; i < kGeneralRegisterCount; i++) {
int code = registers->GetAllocatableGeneralCode(i);
AddRegister(&test_signature, MachineRepresentation::kTagged, code);
}
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
// We assume that Double, Float and Simd128 registers alias, depending on
// kSimpleFPAliasing. For this reason, we allocate a Float, Double and
// Simd128 together, hence the reason why `kDoubleRegisterCount` should be a
// multiple of 3 and 2 in case Simd128 is not supported.
static_assert(
((kDoubleRegisterCount % 2) == 0) && ((kDoubleRegisterCount % 3) == 0),
"kDoubleRegisterCount should be a multiple of two and three.");
for (int i = 0; i < kDoubleRegisterCount; i += 2) {
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
if (kSimpleFPAliasing) {
// Allocate three registers at once if kSimd128 is supported, else
// allocate in pairs.
AddRegister(&test_signature, MachineRepresentation::kFloat32,
registers->GetAllocatableFloatCode(i));
AddRegister(&test_signature, MachineRepresentation::kFloat64,
registers->GetAllocatableDoubleCode(i + 1));
if (TestSimd128Moves()) {
AddRegister(&test_signature, MachineRepresentation::kSimd128,
registers->GetAllocatableSimd128Code(i + 2));
i++;
}
} else {
// Make sure we do not allocate FP registers which alias. To do this, we
// allocate three 128-bit registers and then convert two of them to a
// float and a double. With this aliasing scheme, a Simd128 register
// aliases two Double registers and four Float registers, so we need to
// scale indexes accordingly:
//
// Simd128 register: q0, q1, q2, q3, q4, q5
// | | | |
// V V V V
// Aliases: s0, d2, q2, s12, d8, q5
//
// This isn't space efficient at all but suits our need.
static_assert(
kDoubleRegisterCount < 8,
"Arm has a q8 and a d16 register but no overlapping s32 register.");
int first_simd128 = registers->GetAllocatableSimd128Code(i);
int second_simd128 = registers->GetAllocatableSimd128Code(i + 1);
AddRegister(&test_signature, MachineRepresentation::kFloat32,
first_simd128 * 4);
AddRegister(&test_signature, MachineRepresentation::kFloat64,
second_simd128 * 2);
if (TestSimd128Moves()) {
int third_simd128 = registers->GetAllocatableSimd128Code(i + 2);
AddRegister(&test_signature, MachineRepresentation::kSimd128,
third_simd128);
i++;
}
}
}
// Initialise stack slots.
std::map<MachineRepresentation, int> slots = {
{MachineRepresentation::kTagged, kTaggedSlotCount},
{MachineRepresentation::kFloat32, kFloat32SlotCount},
{MachineRepresentation::kFloat64, kFloat64SlotCount}};
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
if (TestSimd128Moves()) {
slots.emplace(MachineRepresentation::kSimd128, kSimd128SlotCount);
}
// Allocate new slots until we run out of them.
while (std::any_of(slots.cbegin(), slots.cend(),
[](const std::pair<MachineRepresentation, int>& entry) {
// True if there are slots left to allocate for this
// representation.
return entry.second > 0;
})) {
// Pick a random MachineRepresentation from supported_reps_.
MachineRepresentation rep = CreateRandomMachineRepresentation();
auto entry = slots.find(rep);
DCHECK(entry != slots.end());
// We may have picked a representation for which all slots have already
// been allocated.
if (entry->second > 0) {
// Keep a map of (MachineRepresentation . std::vector<int>) with
// allocated slots to pick from for each representation.
int slot = slot_parameter_n;
slot_parameter_n -= (GetSlotSizeInBytes(rep) / kSystemPointerSize);
AddStackSlot(&test_signature, rep, slot);
entry->second--;
}
}
// Initialise random constants.
// While constants do not know about Smis, we need to be able to
// differentiate between a pointer to a HeapNumber and a integer. For this
// reason, we make sure all integers are Smis, including constants.
for (int i = 0; i < kSmiConstantCount; i++) {
intptr_t smi_value = static_cast<intptr_t>(
Smi::FromInt(rng_->NextInt(Smi::kMaxValue)).ptr());
Constant constant = kSystemPointerSize == 8
? Constant(static_cast<int64_t>(smi_value))
: Constant(static_cast<int32_t>(smi_value));
AddConstant(MachineRepresentation::kTagged, AllocateConstant(constant));
}
// Float and Double constants can be moved to both Tagged and FP registers
// or slots. Register them as compatible with both FP and Tagged
// destinations.
for (int i = 0; i < kFloatConstantCount; i++) {
int virtual_register =
AllocateConstant(Constant(DoubleToFloat32(rng_->NextDouble())));
AddConstant(MachineRepresentation::kTagged, virtual_register);
AddConstant(MachineRepresentation::kFloat32, virtual_register);
}
for (int i = 0; i < kDoubleConstantCount; i++) {
int virtual_register = AllocateConstant(Constant(rng_->NextDouble()));
AddConstant(MachineRepresentation::kTagged, virtual_register);
AddConstant(MachineRepresentation::kFloat64, virtual_register);
}
// The "teardown" function returns a FixedArray with the resulting state.
test_signature.AddReturn(LinkageLocation::ForRegister(
kReturnRegister0.code(), MachineType::AnyTagged()));
test_descriptor_ = new (main_zone())
CallDescriptor(CallDescriptor::kCallCodeObject, // kind
MachineType::AnyTagged(), // target MachineType
LinkageLocation::ForAnyRegister(
MachineType::AnyTagged()), // target location
test_signature.Build(), // location_sig
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
kTotalStackParameterCount, // stack_parameter_count
Operator::kNoProperties, // properties
kNoCalleeSaved, // callee-saved registers
kNoCalleeSaved, // callee-saved fp
CallDescriptor::kNoFlags); // flags
}
int AllocateConstant(Constant constant) {
int virtual_register = instructions_.NextVirtualRegister();
instructions_.AddConstant(virtual_register, constant);
return virtual_register;
}
// Register a constant referenced by `virtual_register` as compatible with
// `rep`.
void AddConstant(MachineRepresentation rep, int virtual_register) {
auto entry = allocated_constants_.find(rep);
if (entry == allocated_constants_.end()) {
allocated_constants_.emplace(
rep, std::vector<ConstantOperand>{ConstantOperand(virtual_register)});
} else {
entry->second.emplace_back(virtual_register);
}
}
// Register a new register or stack slot as compatible with `rep`. As opposed
// to constants, registers and stack slots are written to on `setup` and read
// from on `teardown`. Therefore they are part of the environment's layout,
// and are parameters of the `test` function.
void AddRegister(LocationSignature::Builder* test_signature,
MachineRepresentation rep, int code) {
AllocatedOperand operand(AllocatedOperand::REGISTER, rep, code);
layout_.push_back(operand);
test_signature->AddParam(LinkageLocation::ForRegister(
code, MachineType::TypeForRepresentation(rep)));
auto entry = allocated_registers_.find(rep);
if (entry == allocated_registers_.end()) {
allocated_registers_.emplace(rep, std::vector<AllocatedOperand>{operand});
} else {
entry->second.push_back(operand);
}
}
void AddStackSlot(LocationSignature::Builder* test_signature,
MachineRepresentation rep, int slot) {
AllocatedOperand operand(AllocatedOperand::STACK_SLOT, rep, slot);
layout_.push_back(operand);
test_signature->AddParam(LinkageLocation::ForCallerFrameSlot(
slot, MachineType::TypeForRepresentation(rep)));
auto entry = allocated_slots_.find(rep);
if (entry == allocated_slots_.end()) {
allocated_slots_.emplace(rep, std::vector<AllocatedOperand>{operand});
} else {
entry->second.push_back(operand);
}
Reland "[arm] Restrict grouping pushes before a TailCall to registers only" This is a reland of a72b2f88a8cb44f12002f1168c639e07db9d5600 Original change's description: > [arm] Restrict grouping pushes before a TailCall to registers only > > We optimize parallel moves performed before a TailCall by grouping adjacent > pushes. This way, we may use a single instruction to push multiple registers at > once. However, we also have support for pushing immediates and stack slots for > which the benefit is questionnable therefore this patch removes support for > them. > > Concerning immediate pushes, it looks like a mistake since we do not have > support for this case in `AssembleMove` so this patch removes it. Furthermore, > if we add a test for this case, we see that a `push ip` instruction is > generated, effectively pushing whatever was in `ip` at the time instead of > pushing a constant. > > Concerning stack slot pushes, we generate a more or less equivalent sequence of > instructions. > > Finally, grouping floating point pushes is not used anywhere so this patch > removes support for this also. > > Bug: v8:6553 > Change-Id: I9b820d33361fc442dd813f66e1f96cda41009110 > Reviewed-on: https://chromium-review.googlesource.com/567191 > Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> > Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> > Cr-Commit-Position: refs/heads/master@{#46718} Bug: v8:6553 Change-Id: Ib9a55dae7cc5db6185d163c56088ff23426d04bb Reviewed-on: https://chromium-review.googlesource.com/576087 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Cr-Commit-Position: refs/heads/master@{#46754}
2017-07-13 09:55:16 +00:00
}
// Generate a random initial state to test moves against. A "state" is a
// packed FixedArray with Smis and HeapNumbers, according to the layout of the
// environment.
Handle<FixedArray> GenerateInitialState() {
Handle<FixedArray> state = main_isolate()->factory()->NewFixedArray(
static_cast<int>(layout_.size()));
for (int i = 0; i < state->length(); i++) {
switch (layout_[i].representation()) {
case MachineRepresentation::kTagged:
state->set(i, Smi::FromInt(rng_->NextInt(Smi::kMaxValue)));
break;
case MachineRepresentation::kFloat32: {
// HeapNumbers are Float64 values. However, we will convert it to a
// Float32 and back inside `setup` and `teardown`. Make sure the value
// we pick fits in a Float32.
Handle<HeapNumber> num = main_isolate()->factory()->NewHeapNumber(
static_cast<double>(DoubleToFloat32(rng_->NextDouble())));
state->set(i, *num);
break;
}
case MachineRepresentation::kFloat64: {
Handle<HeapNumber> num =
main_isolate()->factory()->NewHeapNumber(rng_->NextDouble());
state->set(i, *num);
break;
}
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
case MachineRepresentation::kSimd128: {
Handle<FixedArray> vector =
main_isolate()->factory()->NewFixedArray(4);
for (int lane = 0; lane < 4; lane++) {
vector->set(lane, Smi::FromInt(rng_->NextInt(Smi::kMaxValue)));
}
state->set(i, *vector);
break;
}
default:
UNREACHABLE();
break;
}
}
return state;
}
// Run the code generated by a CodeGeneratorTester against `state_in` and
// return a new resulting state.
Handle<FixedArray> Run(Handle<Code> test, Handle<FixedArray> state_in) {
Handle<FixedArray> state_out = main_isolate()->factory()->NewFixedArray(
static_cast<int>(layout_.size()));
{
#ifdef ENABLE_SLOW_DCHECKS
// The "setup" and "teardown" functions are relatively big, and with
// runtime assertions enabled they get so big that memory during register
// allocation becomes a problem. Temporarily disable such assertions.
bool old_enable_slow_asserts = FLAG_enable_slow_asserts;
FLAG_enable_slow_asserts = false;
#endif
Handle<Code> setup =
BuildSetupFunction(main_isolate(), test_descriptor_, layout_);
#ifdef ENABLE_SLOW_DCHECKS
FLAG_enable_slow_asserts = old_enable_slow_asserts;
#endif
// FunctionTester maintains its own HandleScope which means that its
// return value will be freed along with it. Copy the result into
// state_out.
FunctionTester ft(setup, 2);
Handle<FixedArray> result = ft.CallChecked<FixedArray>(test, state_in);
CHECK_EQ(result->length(), state_in->length());
result->CopyTo(0, *state_out, 0, result->length());
}
return state_out;
}
// For a given operand representing either a register or a stack slot, return
// what position it should live in inside a FixedArray state.
int OperandToStatePosition(const AllocatedOperand& operand) const {
// Search `layout_` for `operand`.
auto it = std::find_if(layout_.cbegin(), layout_.cend(),
[operand](const AllocatedOperand& this_operand) {
return this_operand.Equals(operand);
});
DCHECK_NE(it, layout_.cend());
return static_cast<int>(std::distance(layout_.cbegin(), it));
}
// Perform the given list of moves on `state_in` and return a newly allocated
// state with the results.
Handle<FixedArray> SimulateMoves(ParallelMove* moves,
Handle<FixedArray> state_in) {
Handle<FixedArray> state_out = main_isolate()->factory()->NewFixedArray(
static_cast<int>(layout_.size()));
// We do not want to modify `state_in` in place so perform the moves on a
// copy.
state_in->CopyTo(0, *state_out, 0, state_in->length());
for (auto move : *moves) {
int to_index =
OperandToStatePosition(AllocatedOperand::cast(move->destination()));
InstructionOperand from = move->source();
if (from.IsConstant()) {
Constant constant = instructions_.GetConstant(
ConstantOperand::cast(from).virtual_register());
Handle<Object> constant_value;
switch (constant.type()) {
case Constant::kInt32:
constant_value =
Handle<Smi>(Smi(static_cast<Address>(
static_cast<intptr_t>(constant.ToInt32()))),
main_isolate());
break;
case Constant::kInt64:
constant_value = Handle<Smi>(
Smi(static_cast<Address>(constant.ToInt64())), main_isolate());
break;
case Constant::kFloat32:
constant_value = main_isolate()->factory()->NewHeapNumber(
static_cast<double>(constant.ToFloat32()));
break;
case Constant::kFloat64:
constant_value = main_isolate()->factory()->NewHeapNumber(
constant.ToFloat64().value());
break;
default:
UNREACHABLE();
break;
}
state_out->set(to_index, *constant_value);
} else {
int from_index = OperandToStatePosition(AllocatedOperand::cast(from));
state_out->set(to_index, state_out->get(from_index));
}
}
return state_out;
}
// Perform the given list of swaps on `state_in` and return a newly allocated
// state with the results.
Handle<FixedArray> SimulateSwaps(ParallelMove* swaps,
Handle<FixedArray> state_in) {
Handle<FixedArray> state_out = main_isolate()->factory()->NewFixedArray(
static_cast<int>(layout_.size()));
// We do not want to modify `state_in` in place so perform the swaps on a
// copy.
state_in->CopyTo(0, *state_out, 0, state_in->length());
for (auto swap : *swaps) {
int lhs_index =
OperandToStatePosition(AllocatedOperand::cast(swap->destination()));
int rhs_index =
OperandToStatePosition(AllocatedOperand::cast(swap->source()));
Handle<Object> lhs{state_out->get(lhs_index), main_isolate()};
Handle<Object> rhs{state_out->get(rhs_index), main_isolate()};
state_out->set(lhs_index, *rhs);
state_out->set(rhs_index, *lhs);
}
return state_out;
}
// Compare the given state with a reference.
void CheckState(Handle<FixedArray> actual, Handle<FixedArray> expected) {
for (int i = 0; i < static_cast<int>(layout_.size()); i++) {
Handle<Object> actual_value{actual->get(i), main_isolate()};
Handle<Object> expected_value{expected->get(i), main_isolate()};
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
if (!CompareValues(actual_value, expected_value,
layout_[i].representation())) {
std::ostringstream expected_str;
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
PrintStateValue(expected_str, main_isolate(), expected_value,
layout_[i]);
std::ostringstream actual_str;
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
PrintStateValue(actual_str, main_isolate(), actual_value, layout_[i]);
FATAL("Expected: '%s' but got '%s'", expected_str.str().c_str(),
actual_str.str().c_str());
}
}
}
Reland "[arm] Restrict grouping pushes before a TailCall to registers only" This is a reland of a72b2f88a8cb44f12002f1168c639e07db9d5600 Original change's description: > [arm] Restrict grouping pushes before a TailCall to registers only > > We optimize parallel moves performed before a TailCall by grouping adjacent > pushes. This way, we may use a single instruction to push multiple registers at > once. However, we also have support for pushing immediates and stack slots for > which the benefit is questionnable therefore this patch removes support for > them. > > Concerning immediate pushes, it looks like a mistake since we do not have > support for this case in `AssembleMove` so this patch removes it. Furthermore, > if we add a test for this case, we see that a `push ip` instruction is > generated, effectively pushing whatever was in `ip` at the time instead of > pushing a constant. > > Concerning stack slot pushes, we generate a more or less equivalent sequence of > instructions. > > Finally, grouping floating point pushes is not used anywhere so this patch > removes support for this also. > > Bug: v8:6553 > Change-Id: I9b820d33361fc442dd813f66e1f96cda41009110 > Reviewed-on: https://chromium-review.googlesource.com/567191 > Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> > Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> > Cr-Commit-Position: refs/heads/master@{#46718} Bug: v8:6553 Change-Id: Ib9a55dae7cc5db6185d163c56088ff23426d04bb Reviewed-on: https://chromium-review.googlesource.com/576087 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Cr-Commit-Position: refs/heads/master@{#46754}
2017-07-13 09:55:16 +00:00
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
bool CompareValues(Handle<Object> actual, Handle<Object> expected,
MachineRepresentation rep) {
switch (rep) {
case MachineRepresentation::kTagged:
case MachineRepresentation::kFloat32:
case MachineRepresentation::kFloat64:
return actual->StrictEquals(*expected);
case MachineRepresentation::kSimd128:
for (int lane = 0; lane < 4; lane++) {
int actual_lane =
Smi::cast(FixedArray::cast(*actual).get(lane)).value();
int expected_lane =
Smi::cast(FixedArray::cast(*expected).get(lane)).value();
if (actual_lane != expected_lane) {
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
return false;
}
}
return true;
default:
UNREACHABLE();
break;
}
}
enum OperandConstraint {
kNone,
// Restrict operands to non-constants. This is useful when generating a
// destination.
kCannotBeConstant
};
// Generate parallel moves at random. Note that they may not be compatible
// between each other as this doesn't matter to the code generator.
ParallelMove* GenerateRandomMoves(int size) {
ParallelMove* parallel_move = new (main_zone()) ParallelMove(main_zone());
for (int i = 0; i < size;) {
MachineRepresentation rep = CreateRandomMachineRepresentation();
MoveOperands mo(CreateRandomOperand(kNone, rep),
CreateRandomOperand(kCannotBeConstant, rep));
// It isn't valid to call `AssembleMove` and `AssembleSwap` with redundant
// moves.
if (mo.IsRedundant()) continue;
parallel_move->AddMove(mo.source(), mo.destination());
// Iterate only when a move was created.
i++;
}
return parallel_move;
}
ParallelMove* GenerateRandomSwaps(int size) {
ParallelMove* parallel_move = new (main_zone()) ParallelMove(main_zone());
for (int i = 0; i < size;) {
MachineRepresentation rep = CreateRandomMachineRepresentation();
InstructionOperand lhs = CreateRandomOperand(kCannotBeConstant, rep);
InstructionOperand rhs = CreateRandomOperand(kCannotBeConstant, rep);
MoveOperands mo(lhs, rhs);
// It isn't valid to call `AssembleMove` and `AssembleSwap` with redundant
// moves.
if (mo.IsRedundant()) continue;
// Canonicalize the swap: the register operand has to be the left hand
// side.
if (lhs.IsStackSlot() || lhs.IsFPStackSlot()) {
std::swap(lhs, rhs);
}
parallel_move->AddMove(lhs, rhs);
// Iterate only when a swap was created.
i++;
}
return parallel_move;
}
MachineRepresentation CreateRandomMachineRepresentation() {
int index = rng_->NextInt(static_cast<int>(supported_reps_.size()));
return supported_reps_[index];
}
InstructionOperand CreateRandomOperand(OperandConstraint constraint,
MachineRepresentation rep) {
// Only generate a Constant if the operand is a source and we have a
// constant with a compatible representation in stock.
bool generate_constant =
(constraint != kCannotBeConstant) &&
(allocated_constants_.find(rep) != allocated_constants_.end());
switch (rng_->NextInt(generate_constant ? 3 : 2)) {
case 0:
return CreateRandomStackSlotOperand(rep);
case 1:
return CreateRandomRegisterOperand(rep);
case 2:
return CreateRandomConstant(rep);
}
UNREACHABLE();
}
AllocatedOperand CreateRandomRegisterOperand(MachineRepresentation rep) {
int index =
rng_->NextInt(static_cast<int>(allocated_registers_[rep].size()));
return allocated_registers_[rep][index];
}
AllocatedOperand CreateRandomStackSlotOperand(MachineRepresentation rep) {
int index = rng_->NextInt(static_cast<int>(allocated_slots_[rep].size()));
return allocated_slots_[rep][index];
}
ConstantOperand CreateRandomConstant(MachineRepresentation rep) {
int index =
rng_->NextInt(static_cast<int>(allocated_constants_[rep].size()));
return allocated_constants_[rep][index];
}
static InstructionBlock* NewBlock(Zone* zone, RpoNumber rpo) {
return new (zone) InstructionBlock(zone, rpo, RpoNumber::Invalid(),
RpoNumber::Invalid(), false, false);
}
v8::base::RandomNumberGenerator* rng() const { return rng_; }
InstructionSequence* instructions() { return &instructions_; }
CallDescriptor* test_descriptor() { return test_descriptor_; }
int stack_slot_count() const { return stack_slot_count_; }
private:
ZoneVector<InstructionBlock*> blocks_;
InstructionSequence instructions_;
v8::base::RandomNumberGenerator* rng_;
// The layout describes the type of each element in the environment, in order.
std::vector<AllocatedOperand> layout_;
CallDescriptor* test_descriptor_;
// Allocated constants, registers and stack slots that we can generate moves
// with. Each per compatible representation.
std::vector<MachineRepresentation> supported_reps_;
std::map<MachineRepresentation, std::vector<ConstantOperand>>
allocated_constants_;
std::map<MachineRepresentation, std::vector<AllocatedOperand>>
allocated_registers_;
std::map<MachineRepresentation, std::vector<AllocatedOperand>>
allocated_slots_;
int stack_slot_count_;
};
// static
constexpr int TestEnvironment::kGeneralRegisterCount;
constexpr int TestEnvironment::kDoubleRegisterCount;
constexpr int TestEnvironment::kTaggedSlotCount;
constexpr int TestEnvironment::kFloat32SlotCount;
constexpr int TestEnvironment::kFloat64SlotCount;
[cctest] Support testing Simd128 moves and swaps Extend the code-generator tests to cover AssembleMove and AssembleSwap with Simd128 registers and stack slots, for targets that support them. For this to work however, we need support for passing Simd128 stack parameters in TurboFan which this patch implements for Arm and x86. PPC and S390 both do not support the Simd128 representation and it appears MIPS and MIPS64's implementation of AssembleMove and AssembleSwap do not support it either. As per the design of the tests, the set of values to perform moves on are represented in a FixedArray of Smis (for kTagged) and HeapNumbers (for kFloat32 and kFloat64). They are converted to raw values for the moves to be performed on, to be then converted back into a FixedArray. For the kSimd128 representation, we represent values as a FixedArray of 4 Smis, each representing a lane. They are converted to a raw Simd128 vector using the `I32x4ReplaceLane` and `I32x4ExtractLane` operations. Finally, these tests need Simd128 variables mixed with the CodeStubAssembler which is not a use-case officially supported. And as a result, the `RecordWrite` stub does not guarantee to preserve Simd128 registers. To get around this, we have to be careful to skip write barriers when dealing with Simd128 parameters inside the "teardown" function, and we've had to move all allocations to the "setup" function. Thanks to this, we are able to catch bugs such as this one https://bugs.chromium.org/p/v8/issues/detail?id=6843. Bug: v8:6848 Change-Id: I8787d6339cdbfcd9356c5e8995925f0b45c562fa Reviewed-on: https://chromium-review.googlesource.com/728599 Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#50326}
2018-01-02 11:27:15 +00:00
constexpr int TestEnvironment::kSimd128SlotCount;
constexpr int TestEnvironment::kSmiConstantCount;
constexpr int TestEnvironment::kFloatConstantCount;
constexpr int TestEnvironment::kDoubleConstantCount;
// Wrapper around the CodeGenerator. Code generated by this can only be called
// using the given `TestEnvironment`.
class CodeGeneratorTester {
public:
explicit CodeGeneratorTester(TestEnvironment* environment,
int extra_stack_space = 0)
: zone_(environment->main_zone()),
info_(ArrayVector("test"), environment->main_zone(), Code::STUB),
linkage_(environment->test_descriptor()),
frame_(environment->test_descriptor()->CalculateFixedFrameSize(
Code::STUB)) {
// Pick half of the stack parameters at random and move them into spill
// slots, separated by `extra_stack_space` bytes.
// When testing a move with stack slots using CheckAssembleMove or
// CheckAssembleSwap, we'll transparently make use of local spill slots
// instead of stack parameters for those that were picked. This allows us to
// test negative, positive, far and near ranges.
for (int i = 0; i < (environment->stack_slot_count() / 2);) {
MachineRepresentation rep =
environment->CreateRandomMachineRepresentation();
LocationOperand old_slot =
LocationOperand::cast(environment->CreateRandomStackSlotOperand(rep));
// Do not pick the same slot twice.
if (GetSpillSlot(&old_slot) != spill_slots_.end()) {
continue;
}
LocationOperand new_slot =
AllocatedOperand(LocationOperand::STACK_SLOT, rep,
frame_.AllocateSpillSlot(GetSlotSizeInBytes(rep)));
// Artificially create space on the stack by allocating a new slot.
if (extra_stack_space > 0) {
frame_.AllocateSpillSlot(extra_stack_space);
}
spill_slots_.emplace_back(old_slot, new_slot);
i++;
}
generator_ = new CodeGenerator(
environment->main_zone(), &frame_, &linkage_,
environment->instructions(), &info_, environment->main_isolate(),
base::Optional<OsrHelper>(), kNoSourcePosition, nullptr,
PoisoningMitigationLevel::kDontPoison,
AssemblerOptions::Default(environment->main_isolate()),
Builtins::kNoBuiltinId);
// Force a frame to be created.
generator_->frame_access_state()->MarkHasFrame(true);
generator_->AssembleConstructFrame();
// TODO(all): Generate a stack check here so that we fail gracefully if the
// frame is too big.
// Move chosen stack parameters into spill slots.
for (auto move : spill_slots_) {
generator_->AssembleMove(&move.first, &move.second);
}
}
~CodeGeneratorTester() { delete generator_; }
std::vector<std::pair<LocationOperand, LocationOperand>>::iterator
GetSpillSlot(InstructionOperand* op) {
if (op->IsAnyStackSlot()) {
LocationOperand slot = LocationOperand::cast(*op);
return std::find_if(
spill_slots_.begin(), spill_slots_.end(),
[slot](
const std::pair<LocationOperand, LocationOperand>& moved_pair) {
return moved_pair.first.index() == slot.index();
});
} else {
return spill_slots_.end();
}
}
// If the operand corresponds to a spill slot, return it. Else just pass it
// through.
InstructionOperand* MaybeTranslateSlot(InstructionOperand* op) {
auto it = GetSpillSlot(op);
if (it != spill_slots_.end()) {
// The second element is the spill slot associated with op.
return &it->second;
} else {
return op;
}
}
Instruction* CreateTailCall(int stack_slot_delta) {
int optional_padding_slot = stack_slot_delta;
InstructionOperand callee[] = {
[turbofan] IA32 port of branch load poisoning. The tricky part here is to take away one register from register allocation for the mask. The only problem is with calls that need an input operand to be passed in the poison register. For such calls, we change the register constraint in the instruction selector to pass the value in whatever place the register allocator sees fit. During code generation, we then copy the value from that place to the poison register. By that time, the mask is not necessary (once we bake the mask into the target, it should be done before this move). For the branches, the mask update does not use cmov (unlike x64) because cmov does not take an immediate and we do not have a scratch register. Instead we use bit-twiddling tricks (suggested by @tebbi). For example, here is the code for masking register update after a bailout on non-zero: jnz deopt_bailout ;; Bailout branch setnz bl ;; These three instructions update the mask add ebx, 255 sar ebx, 31 (On x64, the sequence is: jnz deopt_bailout mov r10, 0 ;; We have a scratch register for zero cmovnz r9, r10 ;; Set to zero if we execute this branch ;; in branch mis-speculation ) This CL also fixes a bug in register configuration, where we used to wrongly restrict the array of register name. Change-Id: I5fceff2faf8bdc527d9934afc284b749574ab69e Bug: chromium:798964 Reviewed-on: https://chromium-review.googlesource.com/946251 Commit-Queue: Jaroslav Sevcik <jarin@chromium.org> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Michael Starzinger <mstarzinger@chromium.org> Cr-Commit-Position: refs/heads/master@{#51798}
2018-03-07 06:35:45 +00:00
AllocatedOperand(LocationOperand::REGISTER,
MachineRepresentation::kTagged,
kReturnRegister0.code()),
ImmediateOperand(ImmediateOperand::INLINE, -1), // poison index.
ImmediateOperand(ImmediateOperand::INLINE, optional_padding_slot),
ImmediateOperand(ImmediateOperand::INLINE, stack_slot_delta)};
[turbofan] IA32 port of branch load poisoning. The tricky part here is to take away one register from register allocation for the mask. The only problem is with calls that need an input operand to be passed in the poison register. For such calls, we change the register constraint in the instruction selector to pass the value in whatever place the register allocator sees fit. During code generation, we then copy the value from that place to the poison register. By that time, the mask is not necessary (once we bake the mask into the target, it should be done before this move). For the branches, the mask update does not use cmov (unlike x64) because cmov does not take an immediate and we do not have a scratch register. Instead we use bit-twiddling tricks (suggested by @tebbi). For example, here is the code for masking register update after a bailout on non-zero: jnz deopt_bailout ;; Bailout branch setnz bl ;; These three instructions update the mask add ebx, 255 sar ebx, 31 (On x64, the sequence is: jnz deopt_bailout mov r10, 0 ;; We have a scratch register for zero cmovnz r9, r10 ;; Set to zero if we execute this branch ;; in branch mis-speculation ) This CL also fixes a bug in register configuration, where we used to wrongly restrict the array of register name. Change-Id: I5fceff2faf8bdc527d9934afc284b749574ab69e Bug: chromium:798964 Reviewed-on: https://chromium-review.googlesource.com/946251 Commit-Queue: Jaroslav Sevcik <jarin@chromium.org> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Michael Starzinger <mstarzinger@chromium.org> Cr-Commit-Position: refs/heads/master@{#51798}
2018-03-07 06:35:45 +00:00
Instruction* tail_call =
Instruction::New(zone_, kArchTailCallCodeObject, 0, nullptr,
arraysize(callee), callee, 0, nullptr);
return tail_call;
}
enum PushTypeFlag {
kRegisterPush = CodeGenerator::kRegisterPush,
kStackSlotPush = CodeGenerator::kStackSlotPush,
kScalarPush = CodeGenerator::kScalarPush
};
Reland "[arm] Restrict grouping pushes before a TailCall to registers only" This is a reland of a72b2f88a8cb44f12002f1168c639e07db9d5600 Original change's description: > [arm] Restrict grouping pushes before a TailCall to registers only > > We optimize parallel moves performed before a TailCall by grouping adjacent > pushes. This way, we may use a single instruction to push multiple registers at > once. However, we also have support for pushing immediates and stack slots for > which the benefit is questionnable therefore this patch removes support for > them. > > Concerning immediate pushes, it looks like a mistake since we do not have > support for this case in `AssembleMove` so this patch removes it. Furthermore, > if we add a test for this case, we see that a `push ip` instruction is > generated, effectively pushing whatever was in `ip` at the time instead of > pushing a constant. > > Concerning stack slot pushes, we generate a more or less equivalent sequence of > instructions. > > Finally, grouping floating point pushes is not used anywhere so this patch > removes support for this also. > > Bug: v8:6553 > Change-Id: I9b820d33361fc442dd813f66e1f96cda41009110 > Reviewed-on: https://chromium-review.googlesource.com/567191 > Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> > Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> > Cr-Commit-Position: refs/heads/master@{#46718} Bug: v8:6553 Change-Id: Ib9a55dae7cc5db6185d163c56088ff23426d04bb Reviewed-on: https://chromium-review.googlesource.com/576087 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Cr-Commit-Position: refs/heads/master@{#46754}
2017-07-13 09:55:16 +00:00
void CheckAssembleTailCallGaps(Instruction* instr,
int first_unused_stack_slot,
CodeGeneratorTester::PushTypeFlag push_type) {
generator_->AssembleTailCallBeforeGap(instr, first_unused_stack_slot);
#if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_S390) || \
defined(V8_TARGET_ARCH_PPC)
Reland "[arm] Restrict grouping pushes before a TailCall to registers only" This is a reland of a72b2f88a8cb44f12002f1168c639e07db9d5600 Original change's description: > [arm] Restrict grouping pushes before a TailCall to registers only > > We optimize parallel moves performed before a TailCall by grouping adjacent > pushes. This way, we may use a single instruction to push multiple registers at > once. However, we also have support for pushing immediates and stack slots for > which the benefit is questionnable therefore this patch removes support for > them. > > Concerning immediate pushes, it looks like a mistake since we do not have > support for this case in `AssembleMove` so this patch removes it. Furthermore, > if we add a test for this case, we see that a `push ip` instruction is > generated, effectively pushing whatever was in `ip` at the time instead of > pushing a constant. > > Concerning stack slot pushes, we generate a more or less equivalent sequence of > instructions. > > Finally, grouping floating point pushes is not used anywhere so this patch > removes support for this also. > > Bug: v8:6553 > Change-Id: I9b820d33361fc442dd813f66e1f96cda41009110 > Reviewed-on: https://chromium-review.googlesource.com/567191 > Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> > Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> > Cr-Commit-Position: refs/heads/master@{#46718} Bug: v8:6553 Change-Id: Ib9a55dae7cc5db6185d163c56088ff23426d04bb Reviewed-on: https://chromium-review.googlesource.com/576087 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Cr-Commit-Position: refs/heads/master@{#46754}
2017-07-13 09:55:16 +00:00
// Only folding register pushes is supported on ARM.
bool supported = ((push_type & CodeGenerator::kRegisterPush) == push_type);
#elif defined(V8_TARGET_ARCH_X64) || defined(V8_TARGET_ARCH_IA32) || \
defined(V8_TARGET_ARCH_X87)
Reland "[arm] Restrict grouping pushes before a TailCall to registers only" This is a reland of a72b2f88a8cb44f12002f1168c639e07db9d5600 Original change's description: > [arm] Restrict grouping pushes before a TailCall to registers only > > We optimize parallel moves performed before a TailCall by grouping adjacent > pushes. This way, we may use a single instruction to push multiple registers at > once. However, we also have support for pushing immediates and stack slots for > which the benefit is questionnable therefore this patch removes support for > them. > > Concerning immediate pushes, it looks like a mistake since we do not have > support for this case in `AssembleMove` so this patch removes it. Furthermore, > if we add a test for this case, we see that a `push ip` instruction is > generated, effectively pushing whatever was in `ip` at the time instead of > pushing a constant. > > Concerning stack slot pushes, we generate a more or less equivalent sequence of > instructions. > > Finally, grouping floating point pushes is not used anywhere so this patch > removes support for this also. > > Bug: v8:6553 > Change-Id: I9b820d33361fc442dd813f66e1f96cda41009110 > Reviewed-on: https://chromium-review.googlesource.com/567191 > Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> > Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> > Cr-Commit-Position: refs/heads/master@{#46718} Bug: v8:6553 Change-Id: Ib9a55dae7cc5db6185d163c56088ff23426d04bb Reviewed-on: https://chromium-review.googlesource.com/576087 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Cr-Commit-Position: refs/heads/master@{#46754}
2017-07-13 09:55:16 +00:00
bool supported = ((push_type & CodeGenerator::kScalarPush) == push_type);
#else
bool supported = false;
#endif
if (supported) {
// Architectures supporting folding adjacent pushes should now have
// resolved all moves.
for (const auto& move :
*instr->parallel_moves()[Instruction::FIRST_GAP_POSITION]) {
CHECK(move->IsEliminated());
}
}
generator_->AssembleGaps(instr);
generator_->AssembleTailCallAfterGap(instr, first_unused_stack_slot);
Reland "[arm] Restrict grouping pushes before a TailCall to registers only" This is a reland of a72b2f88a8cb44f12002f1168c639e07db9d5600 Original change's description: > [arm] Restrict grouping pushes before a TailCall to registers only > > We optimize parallel moves performed before a TailCall by grouping adjacent > pushes. This way, we may use a single instruction to push multiple registers at > once. However, we also have support for pushing immediates and stack slots for > which the benefit is questionnable therefore this patch removes support for > them. > > Concerning immediate pushes, it looks like a mistake since we do not have > support for this case in `AssembleMove` so this patch removes it. Furthermore, > if we add a test for this case, we see that a `push ip` instruction is > generated, effectively pushing whatever was in `ip` at the time instead of > pushing a constant. > > Concerning stack slot pushes, we generate a more or less equivalent sequence of > instructions. > > Finally, grouping floating point pushes is not used anywhere so this patch > removes support for this also. > > Bug: v8:6553 > Change-Id: I9b820d33361fc442dd813f66e1f96cda41009110 > Reviewed-on: https://chromium-review.googlesource.com/567191 > Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> > Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> > Cr-Commit-Position: refs/heads/master@{#46718} Bug: v8:6553 Change-Id: Ib9a55dae7cc5db6185d163c56088ff23426d04bb Reviewed-on: https://chromium-review.googlesource.com/576087 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Cr-Commit-Position: refs/heads/master@{#46754}
2017-07-13 09:55:16 +00:00
}
void CheckAssembleMove(InstructionOperand* source,
InstructionOperand* destination) {
int start = generator_->tasm()->pc_offset();
generator_->AssembleMove(MaybeTranslateSlot(source),
MaybeTranslateSlot(destination));
CHECK(generator_->tasm()->pc_offset() > start);
}
void CheckAssembleSwap(InstructionOperand* source,
InstructionOperand* destination) {
int start = generator_->tasm()->pc_offset();
generator_->AssembleSwap(MaybeTranslateSlot(source),
MaybeTranslateSlot(destination));
CHECK(generator_->tasm()->pc_offset() > start);
}
Reland "[arm] Restrict grouping pushes before a TailCall to registers only" This is a reland of a72b2f88a8cb44f12002f1168c639e07db9d5600 Original change's description: > [arm] Restrict grouping pushes before a TailCall to registers only > > We optimize parallel moves performed before a TailCall by grouping adjacent > pushes. This way, we may use a single instruction to push multiple registers at > once. However, we also have support for pushing immediates and stack slots for > which the benefit is questionnable therefore this patch removes support for > them. > > Concerning immediate pushes, it looks like a mistake since we do not have > support for this case in `AssembleMove` so this patch removes it. Furthermore, > if we add a test for this case, we see that a `push ip` instruction is > generated, effectively pushing whatever was in `ip` at the time instead of > pushing a constant. > > Concerning stack slot pushes, we generate a more or less equivalent sequence of > instructions. > > Finally, grouping floating point pushes is not used anywhere so this patch > removes support for this also. > > Bug: v8:6553 > Change-Id: I9b820d33361fc442dd813f66e1f96cda41009110 > Reviewed-on: https://chromium-review.googlesource.com/567191 > Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> > Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> > Cr-Commit-Position: refs/heads/master@{#46718} Bug: v8:6553 Change-Id: Ib9a55dae7cc5db6185d163c56088ff23426d04bb Reviewed-on: https://chromium-review.googlesource.com/576087 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Cr-Commit-Position: refs/heads/master@{#46754}
2017-07-13 09:55:16 +00:00
Handle<Code> Finalize() {
generator_->FinishCode();
generator_->safepoints()->Emit(generator_->tasm(),
frame_.GetTotalFrameSlotCount());
generator_->MaybeEmitOutOfLineConstantPool();
return generator_->FinalizeCode().ToHandleChecked();
}
Handle<Code> FinalizeForExecuting() {
// The test environment expects us to have performed moves on stack
// parameters. However, some of them are mapped to local spill slots. They
// should be moved back into stack parameters so their values are passed
// along to the `teardown` function.
for (auto move : spill_slots_) {
generator_->AssembleMove(&move.second, &move.first);
}
InstructionSequence* sequence = generator_->instructions();
sequence->StartBlock(RpoNumber::FromInt(0));
// The environment expects this code to tail-call to it's first parameter
// placed in `kReturnRegister0`.
sequence->AddInstruction(Instruction::New(zone_, kArchPrepareTailCall));
// We use either zero or one slots.
int first_unused_stack_slot =
V8_TARGET_ARCH_STORES_RETURN_ADDRESS_ON_STACK ? 1 : 0;
int optional_padding_slot = first_unused_stack_slot;
InstructionOperand callee[] = {
AllocatedOperand(LocationOperand::REGISTER,
MachineRepresentation::kTagged,
kReturnRegister0.code()),
[turbofan] IA32 port of branch load poisoning. The tricky part here is to take away one register from register allocation for the mask. The only problem is with calls that need an input operand to be passed in the poison register. For such calls, we change the register constraint in the instruction selector to pass the value in whatever place the register allocator sees fit. During code generation, we then copy the value from that place to the poison register. By that time, the mask is not necessary (once we bake the mask into the target, it should be done before this move). For the branches, the mask update does not use cmov (unlike x64) because cmov does not take an immediate and we do not have a scratch register. Instead we use bit-twiddling tricks (suggested by @tebbi). For example, here is the code for masking register update after a bailout on non-zero: jnz deopt_bailout ;; Bailout branch setnz bl ;; These three instructions update the mask add ebx, 255 sar ebx, 31 (On x64, the sequence is: jnz deopt_bailout mov r10, 0 ;; We have a scratch register for zero cmovnz r9, r10 ;; Set to zero if we execute this branch ;; in branch mis-speculation ) This CL also fixes a bug in register configuration, where we used to wrongly restrict the array of register name. Change-Id: I5fceff2faf8bdc527d9934afc284b749574ab69e Bug: chromium:798964 Reviewed-on: https://chromium-review.googlesource.com/946251 Commit-Queue: Jaroslav Sevcik <jarin@chromium.org> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Michael Starzinger <mstarzinger@chromium.org> Cr-Commit-Position: refs/heads/master@{#51798}
2018-03-07 06:35:45 +00:00
ImmediateOperand(ImmediateOperand::INLINE, -1), // poison index.
ImmediateOperand(ImmediateOperand::INLINE, optional_padding_slot),
ImmediateOperand(ImmediateOperand::INLINE, first_unused_stack_slot)};
[turbofan] IA32 port of branch load poisoning. The tricky part here is to take away one register from register allocation for the mask. The only problem is with calls that need an input operand to be passed in the poison register. For such calls, we change the register constraint in the instruction selector to pass the value in whatever place the register allocator sees fit. During code generation, we then copy the value from that place to the poison register. By that time, the mask is not necessary (once we bake the mask into the target, it should be done before this move). For the branches, the mask update does not use cmov (unlike x64) because cmov does not take an immediate and we do not have a scratch register. Instead we use bit-twiddling tricks (suggested by @tebbi). For example, here is the code for masking register update after a bailout on non-zero: jnz deopt_bailout ;; Bailout branch setnz bl ;; These three instructions update the mask add ebx, 255 sar ebx, 31 (On x64, the sequence is: jnz deopt_bailout mov r10, 0 ;; We have a scratch register for zero cmovnz r9, r10 ;; Set to zero if we execute this branch ;; in branch mis-speculation ) This CL also fixes a bug in register configuration, where we used to wrongly restrict the array of register name. Change-Id: I5fceff2faf8bdc527d9934afc284b749574ab69e Bug: chromium:798964 Reviewed-on: https://chromium-review.googlesource.com/946251 Commit-Queue: Jaroslav Sevcik <jarin@chromium.org> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Michael Starzinger <mstarzinger@chromium.org> Cr-Commit-Position: refs/heads/master@{#51798}
2018-03-07 06:35:45 +00:00
Instruction* tail_call =
Instruction::New(zone_, kArchTailCallCodeObject, 0, nullptr,
arraysize(callee), callee, 0, nullptr);
sequence->AddInstruction(tail_call);
sequence->EndBlock(RpoNumber::FromInt(0));
generator_->AssembleBlock(
sequence->InstructionBlockAt(RpoNumber::FromInt(0)));
return Finalize();
Reland "[arm] Restrict grouping pushes before a TailCall to registers only" This is a reland of a72b2f88a8cb44f12002f1168c639e07db9d5600 Original change's description: > [arm] Restrict grouping pushes before a TailCall to registers only > > We optimize parallel moves performed before a TailCall by grouping adjacent > pushes. This way, we may use a single instruction to push multiple registers at > once. However, we also have support for pushing immediates and stack slots for > which the benefit is questionnable therefore this patch removes support for > them. > > Concerning immediate pushes, it looks like a mistake since we do not have > support for this case in `AssembleMove` so this patch removes it. Furthermore, > if we add a test for this case, we see that a `push ip` instruction is > generated, effectively pushing whatever was in `ip` at the time instead of > pushing a constant. > > Concerning stack slot pushes, we generate a more or less equivalent sequence of > instructions. > > Finally, grouping floating point pushes is not used anywhere so this patch > removes support for this also. > > Bug: v8:6553 > Change-Id: I9b820d33361fc442dd813f66e1f96cda41009110 > Reviewed-on: https://chromium-review.googlesource.com/567191 > Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> > Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> > Cr-Commit-Position: refs/heads/master@{#46718} Bug: v8:6553 Change-Id: Ib9a55dae7cc5db6185d163c56088ff23426d04bb Reviewed-on: https://chromium-review.googlesource.com/576087 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Cr-Commit-Position: refs/heads/master@{#46754}
2017-07-13 09:55:16 +00:00
}
private:
Zone* zone_;
OptimizedCompilationInfo info_;
Reland "[arm] Restrict grouping pushes before a TailCall to registers only" This is a reland of a72b2f88a8cb44f12002f1168c639e07db9d5600 Original change's description: > [arm] Restrict grouping pushes before a TailCall to registers only > > We optimize parallel moves performed before a TailCall by grouping adjacent > pushes. This way, we may use a single instruction to push multiple registers at > once. However, we also have support for pushing immediates and stack slots for > which the benefit is questionnable therefore this patch removes support for > them. > > Concerning immediate pushes, it looks like a mistake since we do not have > support for this case in `AssembleMove` so this patch removes it. Furthermore, > if we add a test for this case, we see that a `push ip` instruction is > generated, effectively pushing whatever was in `ip` at the time instead of > pushing a constant. > > Concerning stack slot pushes, we generate a more or less equivalent sequence of > instructions. > > Finally, grouping floating point pushes is not used anywhere so this patch > removes support for this also. > > Bug: v8:6553 > Change-Id: I9b820d33361fc442dd813f66e1f96cda41009110 > Reviewed-on: https://chromium-review.googlesource.com/567191 > Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> > Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> > Cr-Commit-Position: refs/heads/master@{#46718} Bug: v8:6553 Change-Id: Ib9a55dae7cc5db6185d163c56088ff23426d04bb Reviewed-on: https://chromium-review.googlesource.com/576087 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Cr-Commit-Position: refs/heads/master@{#46754}
2017-07-13 09:55:16 +00:00
Linkage linkage_;
Frame frame_;
CodeGenerator* generator_;
// List of operands to be moved from stack parameters to spill slots.
std::vector<std::pair<LocationOperand, LocationOperand>> spill_slots_;
Reland "[arm] Restrict grouping pushes before a TailCall to registers only" This is a reland of a72b2f88a8cb44f12002f1168c639e07db9d5600 Original change's description: > [arm] Restrict grouping pushes before a TailCall to registers only > > We optimize parallel moves performed before a TailCall by grouping adjacent > pushes. This way, we may use a single instruction to push multiple registers at > once. However, we also have support for pushing immediates and stack slots for > which the benefit is questionnable therefore this patch removes support for > them. > > Concerning immediate pushes, it looks like a mistake since we do not have > support for this case in `AssembleMove` so this patch removes it. Furthermore, > if we add a test for this case, we see that a `push ip` instruction is > generated, effectively pushing whatever was in `ip` at the time instead of > pushing a constant. > > Concerning stack slot pushes, we generate a more or less equivalent sequence of > instructions. > > Finally, grouping floating point pushes is not used anywhere so this patch > removes support for this also. > > Bug: v8:6553 > Change-Id: I9b820d33361fc442dd813f66e1f96cda41009110 > Reviewed-on: https://chromium-review.googlesource.com/567191 > Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> > Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> > Cr-Commit-Position: refs/heads/master@{#46718} Bug: v8:6553 Change-Id: Ib9a55dae7cc5db6185d163c56088ff23426d04bb Reviewed-on: https://chromium-review.googlesource.com/576087 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Cr-Commit-Position: refs/heads/master@{#46754}
2017-07-13 09:55:16 +00:00
};
// The following fuzz tests will assemble a lot of moves, wrap them in
// executable native code and run them. In order to check that moves were
// performed correctly, we need to setup an environment with an initial state
// and get it back after the list of moves were performed.
//
// We have two components to do this: TestEnvironment and CodeGeneratorTester.
//
// The TestEnvironment is in charge of bringing up an environment consisting of
// a set of registers, stack slots and constants, with initial values in
// them. The CodeGeneratorTester is a wrapper around the CodeGenerator and its
// only purpose is to generate code for a list of moves. The TestEnvironment is
// then able to run this code against the environment and return a resulting
// state.
//
// A "state" here is a packed FixedArray with tagged values which can either be
// Smis or HeapNumbers. When calling TestEnvironment::Run(...), registers and
// stack slots will be initialised according to this FixedArray. A new
// FixedArray is returned containing values that were moved by the generated
// code.
//
// And finally, we are able to compare the resulting FixedArray against a
// reference, computed with a simulation of AssembleMove and AssembleSwap. See
// SimulateMoves and SimulateSwaps.
// Allocate space between slots to increase coverage of moves with larger
// ranges. Note that this affects how much stack is allocated when running the
// generated code. It means we have to be careful not to exceed the stack limit,
// which is lower on Windows.
#ifdef V8_OS_WIN
constexpr int kExtraSpace = 0;
#else
constexpr int kExtraSpace = 1 * KB;
#endif
TEST(FuzzAssembleMove) {
TestEnvironment env;
Handle<FixedArray> state_in = env.GenerateInitialState();
ParallelMove* moves = env.GenerateRandomMoves(1000);
Handle<FixedArray> expected = env.SimulateMoves(moves, state_in);
// Test small and potentially large ranges separately.
for (int extra_space : {0, kExtraSpace}) {
CodeGeneratorTester c(&env, extra_space);
for (auto m : *moves) {
c.CheckAssembleMove(&m->source(), &m->destination());
}
Handle<Code> test = c.FinalizeForExecuting();
if (FLAG_print_code) {
test->Print();
}
Handle<FixedArray> actual = env.Run(test, state_in);
env.CheckState(actual, expected);
}
}
TEST(FuzzAssembleSwap) {
TestEnvironment env;
Handle<FixedArray> state_in = env.GenerateInitialState();
ParallelMove* swaps = env.GenerateRandomSwaps(1000);
Handle<FixedArray> expected = env.SimulateSwaps(swaps, state_in);
// Test small and potentially large ranges separately.
for (int extra_space : {0, kExtraSpace}) {
CodeGeneratorTester c(&env, extra_space);
for (auto s : *swaps) {
c.CheckAssembleSwap(&s->source(), &s->destination());
}
Handle<Code> test = c.FinalizeForExecuting();
if (FLAG_print_code) {
test->Print();
}
Handle<FixedArray> actual = env.Run(test, state_in);
env.CheckState(actual, expected);
}
}
TEST(FuzzAssembleMoveAndSwap) {
TestEnvironment env;
Handle<FixedArray> state_in = env.GenerateInitialState();
Handle<FixedArray> expected =
env.main_isolate()->factory()->NewFixedArray(state_in->length());
// Test small and potentially large ranges separately.
for (int extra_space : {0, kExtraSpace}) {
CodeGeneratorTester c(&env, extra_space);
state_in->CopyTo(0, *expected, 0, state_in->length());
for (int i = 0; i < 1000; i++) {
// Randomly alternate between swaps and moves.
if (env.rng()->NextInt(2) == 0) {
ParallelMove* move = env.GenerateRandomMoves(1);
expected = env.SimulateMoves(move, expected);
c.CheckAssembleMove(&move->at(0)->source(),
&move->at(0)->destination());
} else {
ParallelMove* swap = env.GenerateRandomSwaps(1);
expected = env.SimulateSwaps(swap, expected);
c.CheckAssembleSwap(&swap->at(0)->source(),
&swap->at(0)->destination());
}
}
Handle<Code> test = c.FinalizeForExecuting();
if (FLAG_print_code) {
test->Print();
}
Handle<FixedArray> actual = env.Run(test, state_in);
env.CheckState(actual, expected);
}
}
Reland "[arm] Restrict grouping pushes before a TailCall to registers only" This is a reland of a72b2f88a8cb44f12002f1168c639e07db9d5600 Original change's description: > [arm] Restrict grouping pushes before a TailCall to registers only > > We optimize parallel moves performed before a TailCall by grouping adjacent > pushes. This way, we may use a single instruction to push multiple registers at > once. However, we also have support for pushing immediates and stack slots for > which the benefit is questionnable therefore this patch removes support for > them. > > Concerning immediate pushes, it looks like a mistake since we do not have > support for this case in `AssembleMove` so this patch removes it. Furthermore, > if we add a test for this case, we see that a `push ip` instruction is > generated, effectively pushing whatever was in `ip` at the time instead of > pushing a constant. > > Concerning stack slot pushes, we generate a more or less equivalent sequence of > instructions. > > Finally, grouping floating point pushes is not used anywhere so this patch > removes support for this also. > > Bug: v8:6553 > Change-Id: I9b820d33361fc442dd813f66e1f96cda41009110 > Reviewed-on: https://chromium-review.googlesource.com/567191 > Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> > Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> > Cr-Commit-Position: refs/heads/master@{#46718} Bug: v8:6553 Change-Id: Ib9a55dae7cc5db6185d163c56088ff23426d04bb Reviewed-on: https://chromium-review.googlesource.com/576087 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Cr-Commit-Position: refs/heads/master@{#46754}
2017-07-13 09:55:16 +00:00
TEST(AssembleTailCallGap) {
const RegisterConfiguration* conf = GetRegConfig();
TestEnvironment env;
Reland "[arm] Restrict grouping pushes before a TailCall to registers only" This is a reland of a72b2f88a8cb44f12002f1168c639e07db9d5600 Original change's description: > [arm] Restrict grouping pushes before a TailCall to registers only > > We optimize parallel moves performed before a TailCall by grouping adjacent > pushes. This way, we may use a single instruction to push multiple registers at > once. However, we also have support for pushing immediates and stack slots for > which the benefit is questionnable therefore this patch removes support for > them. > > Concerning immediate pushes, it looks like a mistake since we do not have > support for this case in `AssembleMove` so this patch removes it. Furthermore, > if we add a test for this case, we see that a `push ip` instruction is > generated, effectively pushing whatever was in `ip` at the time instead of > pushing a constant. > > Concerning stack slot pushes, we generate a more or less equivalent sequence of > instructions. > > Finally, grouping floating point pushes is not used anywhere so this patch > removes support for this also. > > Bug: v8:6553 > Change-Id: I9b820d33361fc442dd813f66e1f96cda41009110 > Reviewed-on: https://chromium-review.googlesource.com/567191 > Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> > Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> > Cr-Commit-Position: refs/heads/master@{#46718} Bug: v8:6553 Change-Id: Ib9a55dae7cc5db6185d163c56088ff23426d04bb Reviewed-on: https://chromium-review.googlesource.com/576087 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Cr-Commit-Position: refs/heads/master@{#46754}
2017-07-13 09:55:16 +00:00
// This test assumes at least 4 registers are allocatable.
CHECK_LE(4, conf->num_allocatable_general_registers());
Reland "[arm] Restrict grouping pushes before a TailCall to registers only" This is a reland of a72b2f88a8cb44f12002f1168c639e07db9d5600 Original change's description: > [arm] Restrict grouping pushes before a TailCall to registers only > > We optimize parallel moves performed before a TailCall by grouping adjacent > pushes. This way, we may use a single instruction to push multiple registers at > once. However, we also have support for pushing immediates and stack slots for > which the benefit is questionnable therefore this patch removes support for > them. > > Concerning immediate pushes, it looks like a mistake since we do not have > support for this case in `AssembleMove` so this patch removes it. Furthermore, > if we add a test for this case, we see that a `push ip` instruction is > generated, effectively pushing whatever was in `ip` at the time instead of > pushing a constant. > > Concerning stack slot pushes, we generate a more or less equivalent sequence of > instructions. > > Finally, grouping floating point pushes is not used anywhere so this patch > removes support for this also. > > Bug: v8:6553 > Change-Id: I9b820d33361fc442dd813f66e1f96cda41009110 > Reviewed-on: https://chromium-review.googlesource.com/567191 > Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> > Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> > Cr-Commit-Position: refs/heads/master@{#46718} Bug: v8:6553 Change-Id: Ib9a55dae7cc5db6185d163c56088ff23426d04bb Reviewed-on: https://chromium-review.googlesource.com/576087 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Cr-Commit-Position: refs/heads/master@{#46754}
2017-07-13 09:55:16 +00:00
auto r0 = AllocatedOperand(LocationOperand::REGISTER,
MachineRepresentation::kTagged,
conf->GetAllocatableGeneralCode(0));
auto r1 = AllocatedOperand(LocationOperand::REGISTER,
MachineRepresentation::kTagged,
conf->GetAllocatableGeneralCode(1));
auto r2 = AllocatedOperand(LocationOperand::REGISTER,
MachineRepresentation::kTagged,
conf->GetAllocatableGeneralCode(2));
auto r3 = AllocatedOperand(LocationOperand::REGISTER,
MachineRepresentation::kTagged,
conf->GetAllocatableGeneralCode(3));
auto slot_minus_4 = AllocatedOperand(LocationOperand::STACK_SLOT,
MachineRepresentation::kTagged, -4);
auto slot_minus_3 = AllocatedOperand(LocationOperand::STACK_SLOT,
MachineRepresentation::kTagged, -3);
auto slot_minus_2 = AllocatedOperand(LocationOperand::STACK_SLOT,
MachineRepresentation::kTagged, -2);
auto slot_minus_1 = AllocatedOperand(LocationOperand::STACK_SLOT,
MachineRepresentation::kTagged, -1);
// Avoid slot 0 for architectures which use it store the return address.
int first_slot = V8_TARGET_ARCH_STORES_RETURN_ADDRESS_ON_STACK ? 1 : 0;
auto slot_0 = AllocatedOperand(LocationOperand::STACK_SLOT,
MachineRepresentation::kTagged, first_slot);
auto slot_1 =
AllocatedOperand(LocationOperand::STACK_SLOT,
MachineRepresentation::kTagged, first_slot + 1);
auto slot_2 =
AllocatedOperand(LocationOperand::STACK_SLOT,
MachineRepresentation::kTagged, first_slot + 2);
auto slot_3 =
AllocatedOperand(LocationOperand::STACK_SLOT,
MachineRepresentation::kTagged, first_slot + 3);
// These tests all generate series of moves that the code generator should
// detect as adjacent pushes. Depending on the architecture, we make sure
// these moves get eliminated.
// Also, disassembling with `--print-code` is useful when debugging.
{
// Generate a series of register pushes only.
CodeGeneratorTester c(&env);
Instruction* instr = c.CreateTailCall(first_slot + 4);
instr
->GetOrCreateParallelMove(Instruction::FIRST_GAP_POSITION,
env.main_zone())
Reland "[arm] Restrict grouping pushes before a TailCall to registers only" This is a reland of a72b2f88a8cb44f12002f1168c639e07db9d5600 Original change's description: > [arm] Restrict grouping pushes before a TailCall to registers only > > We optimize parallel moves performed before a TailCall by grouping adjacent > pushes. This way, we may use a single instruction to push multiple registers at > once. However, we also have support for pushing immediates and stack slots for > which the benefit is questionnable therefore this patch removes support for > them. > > Concerning immediate pushes, it looks like a mistake since we do not have > support for this case in `AssembleMove` so this patch removes it. Furthermore, > if we add a test for this case, we see that a `push ip` instruction is > generated, effectively pushing whatever was in `ip` at the time instead of > pushing a constant. > > Concerning stack slot pushes, we generate a more or less equivalent sequence of > instructions. > > Finally, grouping floating point pushes is not used anywhere so this patch > removes support for this also. > > Bug: v8:6553 > Change-Id: I9b820d33361fc442dd813f66e1f96cda41009110 > Reviewed-on: https://chromium-review.googlesource.com/567191 > Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> > Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> > Cr-Commit-Position: refs/heads/master@{#46718} Bug: v8:6553 Change-Id: Ib9a55dae7cc5db6185d163c56088ff23426d04bb Reviewed-on: https://chromium-review.googlesource.com/576087 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Cr-Commit-Position: refs/heads/master@{#46754}
2017-07-13 09:55:16 +00:00
->AddMove(r3, slot_0);
instr
->GetOrCreateParallelMove(Instruction::FIRST_GAP_POSITION,
env.main_zone())
Reland "[arm] Restrict grouping pushes before a TailCall to registers only" This is a reland of a72b2f88a8cb44f12002f1168c639e07db9d5600 Original change's description: > [arm] Restrict grouping pushes before a TailCall to registers only > > We optimize parallel moves performed before a TailCall by grouping adjacent > pushes. This way, we may use a single instruction to push multiple registers at > once. However, we also have support for pushing immediates and stack slots for > which the benefit is questionnable therefore this patch removes support for > them. > > Concerning immediate pushes, it looks like a mistake since we do not have > support for this case in `AssembleMove` so this patch removes it. Furthermore, > if we add a test for this case, we see that a `push ip` instruction is > generated, effectively pushing whatever was in `ip` at the time instead of > pushing a constant. > > Concerning stack slot pushes, we generate a more or less equivalent sequence of > instructions. > > Finally, grouping floating point pushes is not used anywhere so this patch > removes support for this also. > > Bug: v8:6553 > Change-Id: I9b820d33361fc442dd813f66e1f96cda41009110 > Reviewed-on: https://chromium-review.googlesource.com/567191 > Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> > Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> > Cr-Commit-Position: refs/heads/master@{#46718} Bug: v8:6553 Change-Id: Ib9a55dae7cc5db6185d163c56088ff23426d04bb Reviewed-on: https://chromium-review.googlesource.com/576087 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Cr-Commit-Position: refs/heads/master@{#46754}
2017-07-13 09:55:16 +00:00
->AddMove(r2, slot_1);
instr
->GetOrCreateParallelMove(Instruction::FIRST_GAP_POSITION,
env.main_zone())
Reland "[arm] Restrict grouping pushes before a TailCall to registers only" This is a reland of a72b2f88a8cb44f12002f1168c639e07db9d5600 Original change's description: > [arm] Restrict grouping pushes before a TailCall to registers only > > We optimize parallel moves performed before a TailCall by grouping adjacent > pushes. This way, we may use a single instruction to push multiple registers at > once. However, we also have support for pushing immediates and stack slots for > which the benefit is questionnable therefore this patch removes support for > them. > > Concerning immediate pushes, it looks like a mistake since we do not have > support for this case in `AssembleMove` so this patch removes it. Furthermore, > if we add a test for this case, we see that a `push ip` instruction is > generated, effectively pushing whatever was in `ip` at the time instead of > pushing a constant. > > Concerning stack slot pushes, we generate a more or less equivalent sequence of > instructions. > > Finally, grouping floating point pushes is not used anywhere so this patch > removes support for this also. > > Bug: v8:6553 > Change-Id: I9b820d33361fc442dd813f66e1f96cda41009110 > Reviewed-on: https://chromium-review.googlesource.com/567191 > Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> > Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> > Cr-Commit-Position: refs/heads/master@{#46718} Bug: v8:6553 Change-Id: Ib9a55dae7cc5db6185d163c56088ff23426d04bb Reviewed-on: https://chromium-review.googlesource.com/576087 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Cr-Commit-Position: refs/heads/master@{#46754}
2017-07-13 09:55:16 +00:00
->AddMove(r1, slot_2);
instr
->GetOrCreateParallelMove(Instruction::FIRST_GAP_POSITION,
env.main_zone())
Reland "[arm] Restrict grouping pushes before a TailCall to registers only" This is a reland of a72b2f88a8cb44f12002f1168c639e07db9d5600 Original change's description: > [arm] Restrict grouping pushes before a TailCall to registers only > > We optimize parallel moves performed before a TailCall by grouping adjacent > pushes. This way, we may use a single instruction to push multiple registers at > once. However, we also have support for pushing immediates and stack slots for > which the benefit is questionnable therefore this patch removes support for > them. > > Concerning immediate pushes, it looks like a mistake since we do not have > support for this case in `AssembleMove` so this patch removes it. Furthermore, > if we add a test for this case, we see that a `push ip` instruction is > generated, effectively pushing whatever was in `ip` at the time instead of > pushing a constant. > > Concerning stack slot pushes, we generate a more or less equivalent sequence of > instructions. > > Finally, grouping floating point pushes is not used anywhere so this patch > removes support for this also. > > Bug: v8:6553 > Change-Id: I9b820d33361fc442dd813f66e1f96cda41009110 > Reviewed-on: https://chromium-review.googlesource.com/567191 > Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> > Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> > Cr-Commit-Position: refs/heads/master@{#46718} Bug: v8:6553 Change-Id: Ib9a55dae7cc5db6185d163c56088ff23426d04bb Reviewed-on: https://chromium-review.googlesource.com/576087 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Cr-Commit-Position: refs/heads/master@{#46754}
2017-07-13 09:55:16 +00:00
->AddMove(r0, slot_3);
c.CheckAssembleTailCallGaps(instr, first_slot + 4,
CodeGeneratorTester::kRegisterPush);
Handle<Code> code = c.Finalize();
if (FLAG_print_code) {
code->Print();
}
Reland "[arm] Restrict grouping pushes before a TailCall to registers only" This is a reland of a72b2f88a8cb44f12002f1168c639e07db9d5600 Original change's description: > [arm] Restrict grouping pushes before a TailCall to registers only > > We optimize parallel moves performed before a TailCall by grouping adjacent > pushes. This way, we may use a single instruction to push multiple registers at > once. However, we also have support for pushing immediates and stack slots for > which the benefit is questionnable therefore this patch removes support for > them. > > Concerning immediate pushes, it looks like a mistake since we do not have > support for this case in `AssembleMove` so this patch removes it. Furthermore, > if we add a test for this case, we see that a `push ip` instruction is > generated, effectively pushing whatever was in `ip` at the time instead of > pushing a constant. > > Concerning stack slot pushes, we generate a more or less equivalent sequence of > instructions. > > Finally, grouping floating point pushes is not used anywhere so this patch > removes support for this also. > > Bug: v8:6553 > Change-Id: I9b820d33361fc442dd813f66e1f96cda41009110 > Reviewed-on: https://chromium-review.googlesource.com/567191 > Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> > Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> > Cr-Commit-Position: refs/heads/master@{#46718} Bug: v8:6553 Change-Id: Ib9a55dae7cc5db6185d163c56088ff23426d04bb Reviewed-on: https://chromium-review.googlesource.com/576087 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Cr-Commit-Position: refs/heads/master@{#46754}
2017-07-13 09:55:16 +00:00
}
{
// Generate a series of stack pushes only.
CodeGeneratorTester c(&env);
Instruction* instr = c.CreateTailCall(first_slot + 4);
instr
->GetOrCreateParallelMove(Instruction::FIRST_GAP_POSITION,
env.main_zone())
Reland "[arm] Restrict grouping pushes before a TailCall to registers only" This is a reland of a72b2f88a8cb44f12002f1168c639e07db9d5600 Original change's description: > [arm] Restrict grouping pushes before a TailCall to registers only > > We optimize parallel moves performed before a TailCall by grouping adjacent > pushes. This way, we may use a single instruction to push multiple registers at > once. However, we also have support for pushing immediates and stack slots for > which the benefit is questionnable therefore this patch removes support for > them. > > Concerning immediate pushes, it looks like a mistake since we do not have > support for this case in `AssembleMove` so this patch removes it. Furthermore, > if we add a test for this case, we see that a `push ip` instruction is > generated, effectively pushing whatever was in `ip` at the time instead of > pushing a constant. > > Concerning stack slot pushes, we generate a more or less equivalent sequence of > instructions. > > Finally, grouping floating point pushes is not used anywhere so this patch > removes support for this also. > > Bug: v8:6553 > Change-Id: I9b820d33361fc442dd813f66e1f96cda41009110 > Reviewed-on: https://chromium-review.googlesource.com/567191 > Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> > Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> > Cr-Commit-Position: refs/heads/master@{#46718} Bug: v8:6553 Change-Id: Ib9a55dae7cc5db6185d163c56088ff23426d04bb Reviewed-on: https://chromium-review.googlesource.com/576087 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Cr-Commit-Position: refs/heads/master@{#46754}
2017-07-13 09:55:16 +00:00
->AddMove(slot_minus_4, slot_0);
instr
->GetOrCreateParallelMove(Instruction::FIRST_GAP_POSITION,
env.main_zone())
Reland "[arm] Restrict grouping pushes before a TailCall to registers only" This is a reland of a72b2f88a8cb44f12002f1168c639e07db9d5600 Original change's description: > [arm] Restrict grouping pushes before a TailCall to registers only > > We optimize parallel moves performed before a TailCall by grouping adjacent > pushes. This way, we may use a single instruction to push multiple registers at > once. However, we also have support for pushing immediates and stack slots for > which the benefit is questionnable therefore this patch removes support for > them. > > Concerning immediate pushes, it looks like a mistake since we do not have > support for this case in `AssembleMove` so this patch removes it. Furthermore, > if we add a test for this case, we see that a `push ip` instruction is > generated, effectively pushing whatever was in `ip` at the time instead of > pushing a constant. > > Concerning stack slot pushes, we generate a more or less equivalent sequence of > instructions. > > Finally, grouping floating point pushes is not used anywhere so this patch > removes support for this also. > > Bug: v8:6553 > Change-Id: I9b820d33361fc442dd813f66e1f96cda41009110 > Reviewed-on: https://chromium-review.googlesource.com/567191 > Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> > Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> > Cr-Commit-Position: refs/heads/master@{#46718} Bug: v8:6553 Change-Id: Ib9a55dae7cc5db6185d163c56088ff23426d04bb Reviewed-on: https://chromium-review.googlesource.com/576087 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Cr-Commit-Position: refs/heads/master@{#46754}
2017-07-13 09:55:16 +00:00
->AddMove(slot_minus_3, slot_1);
instr
->GetOrCreateParallelMove(Instruction::FIRST_GAP_POSITION,
env.main_zone())
Reland "[arm] Restrict grouping pushes before a TailCall to registers only" This is a reland of a72b2f88a8cb44f12002f1168c639e07db9d5600 Original change's description: > [arm] Restrict grouping pushes before a TailCall to registers only > > We optimize parallel moves performed before a TailCall by grouping adjacent > pushes. This way, we may use a single instruction to push multiple registers at > once. However, we also have support for pushing immediates and stack slots for > which the benefit is questionnable therefore this patch removes support for > them. > > Concerning immediate pushes, it looks like a mistake since we do not have > support for this case in `AssembleMove` so this patch removes it. Furthermore, > if we add a test for this case, we see that a `push ip` instruction is > generated, effectively pushing whatever was in `ip` at the time instead of > pushing a constant. > > Concerning stack slot pushes, we generate a more or less equivalent sequence of > instructions. > > Finally, grouping floating point pushes is not used anywhere so this patch > removes support for this also. > > Bug: v8:6553 > Change-Id: I9b820d33361fc442dd813f66e1f96cda41009110 > Reviewed-on: https://chromium-review.googlesource.com/567191 > Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> > Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> > Cr-Commit-Position: refs/heads/master@{#46718} Bug: v8:6553 Change-Id: Ib9a55dae7cc5db6185d163c56088ff23426d04bb Reviewed-on: https://chromium-review.googlesource.com/576087 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Cr-Commit-Position: refs/heads/master@{#46754}
2017-07-13 09:55:16 +00:00
->AddMove(slot_minus_2, slot_2);
instr
->GetOrCreateParallelMove(Instruction::FIRST_GAP_POSITION,
env.main_zone())
Reland "[arm] Restrict grouping pushes before a TailCall to registers only" This is a reland of a72b2f88a8cb44f12002f1168c639e07db9d5600 Original change's description: > [arm] Restrict grouping pushes before a TailCall to registers only > > We optimize parallel moves performed before a TailCall by grouping adjacent > pushes. This way, we may use a single instruction to push multiple registers at > once. However, we also have support for pushing immediates and stack slots for > which the benefit is questionnable therefore this patch removes support for > them. > > Concerning immediate pushes, it looks like a mistake since we do not have > support for this case in `AssembleMove` so this patch removes it. Furthermore, > if we add a test for this case, we see that a `push ip` instruction is > generated, effectively pushing whatever was in `ip` at the time instead of > pushing a constant. > > Concerning stack slot pushes, we generate a more or less equivalent sequence of > instructions. > > Finally, grouping floating point pushes is not used anywhere so this patch > removes support for this also. > > Bug: v8:6553 > Change-Id: I9b820d33361fc442dd813f66e1f96cda41009110 > Reviewed-on: https://chromium-review.googlesource.com/567191 > Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> > Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> > Cr-Commit-Position: refs/heads/master@{#46718} Bug: v8:6553 Change-Id: Ib9a55dae7cc5db6185d163c56088ff23426d04bb Reviewed-on: https://chromium-review.googlesource.com/576087 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Cr-Commit-Position: refs/heads/master@{#46754}
2017-07-13 09:55:16 +00:00
->AddMove(slot_minus_1, slot_3);
c.CheckAssembleTailCallGaps(instr, first_slot + 4,
CodeGeneratorTester::kStackSlotPush);
Handle<Code> code = c.Finalize();
if (FLAG_print_code) {
code->Print();
}
Reland "[arm] Restrict grouping pushes before a TailCall to registers only" This is a reland of a72b2f88a8cb44f12002f1168c639e07db9d5600 Original change's description: > [arm] Restrict grouping pushes before a TailCall to registers only > > We optimize parallel moves performed before a TailCall by grouping adjacent > pushes. This way, we may use a single instruction to push multiple registers at > once. However, we also have support for pushing immediates and stack slots for > which the benefit is questionnable therefore this patch removes support for > them. > > Concerning immediate pushes, it looks like a mistake since we do not have > support for this case in `AssembleMove` so this patch removes it. Furthermore, > if we add a test for this case, we see that a `push ip` instruction is > generated, effectively pushing whatever was in `ip` at the time instead of > pushing a constant. > > Concerning stack slot pushes, we generate a more or less equivalent sequence of > instructions. > > Finally, grouping floating point pushes is not used anywhere so this patch > removes support for this also. > > Bug: v8:6553 > Change-Id: I9b820d33361fc442dd813f66e1f96cda41009110 > Reviewed-on: https://chromium-review.googlesource.com/567191 > Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> > Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> > Cr-Commit-Position: refs/heads/master@{#46718} Bug: v8:6553 Change-Id: Ib9a55dae7cc5db6185d163c56088ff23426d04bb Reviewed-on: https://chromium-review.googlesource.com/576087 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Cr-Commit-Position: refs/heads/master@{#46754}
2017-07-13 09:55:16 +00:00
}
{
// Generate a mix of stack and register pushes.
CodeGeneratorTester c(&env);
Instruction* instr = c.CreateTailCall(first_slot + 4);
instr
->GetOrCreateParallelMove(Instruction::FIRST_GAP_POSITION,
env.main_zone())
Reland "[arm] Restrict grouping pushes before a TailCall to registers only" This is a reland of a72b2f88a8cb44f12002f1168c639e07db9d5600 Original change's description: > [arm] Restrict grouping pushes before a TailCall to registers only > > We optimize parallel moves performed before a TailCall by grouping adjacent > pushes. This way, we may use a single instruction to push multiple registers at > once. However, we also have support for pushing immediates and stack slots for > which the benefit is questionnable therefore this patch removes support for > them. > > Concerning immediate pushes, it looks like a mistake since we do not have > support for this case in `AssembleMove` so this patch removes it. Furthermore, > if we add a test for this case, we see that a `push ip` instruction is > generated, effectively pushing whatever was in `ip` at the time instead of > pushing a constant. > > Concerning stack slot pushes, we generate a more or less equivalent sequence of > instructions. > > Finally, grouping floating point pushes is not used anywhere so this patch > removes support for this also. > > Bug: v8:6553 > Change-Id: I9b820d33361fc442dd813f66e1f96cda41009110 > Reviewed-on: https://chromium-review.googlesource.com/567191 > Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> > Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> > Cr-Commit-Position: refs/heads/master@{#46718} Bug: v8:6553 Change-Id: Ib9a55dae7cc5db6185d163c56088ff23426d04bb Reviewed-on: https://chromium-review.googlesource.com/576087 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Cr-Commit-Position: refs/heads/master@{#46754}
2017-07-13 09:55:16 +00:00
->AddMove(slot_minus_2, slot_0);
instr
->GetOrCreateParallelMove(Instruction::FIRST_GAP_POSITION,
env.main_zone())
Reland "[arm] Restrict grouping pushes before a TailCall to registers only" This is a reland of a72b2f88a8cb44f12002f1168c639e07db9d5600 Original change's description: > [arm] Restrict grouping pushes before a TailCall to registers only > > We optimize parallel moves performed before a TailCall by grouping adjacent > pushes. This way, we may use a single instruction to push multiple registers at > once. However, we also have support for pushing immediates and stack slots for > which the benefit is questionnable therefore this patch removes support for > them. > > Concerning immediate pushes, it looks like a mistake since we do not have > support for this case in `AssembleMove` so this patch removes it. Furthermore, > if we add a test for this case, we see that a `push ip` instruction is > generated, effectively pushing whatever was in `ip` at the time instead of > pushing a constant. > > Concerning stack slot pushes, we generate a more or less equivalent sequence of > instructions. > > Finally, grouping floating point pushes is not used anywhere so this patch > removes support for this also. > > Bug: v8:6553 > Change-Id: I9b820d33361fc442dd813f66e1f96cda41009110 > Reviewed-on: https://chromium-review.googlesource.com/567191 > Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> > Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> > Cr-Commit-Position: refs/heads/master@{#46718} Bug: v8:6553 Change-Id: Ib9a55dae7cc5db6185d163c56088ff23426d04bb Reviewed-on: https://chromium-review.googlesource.com/576087 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Cr-Commit-Position: refs/heads/master@{#46754}
2017-07-13 09:55:16 +00:00
->AddMove(r1, slot_1);
instr
->GetOrCreateParallelMove(Instruction::FIRST_GAP_POSITION,
env.main_zone())
Reland "[arm] Restrict grouping pushes before a TailCall to registers only" This is a reland of a72b2f88a8cb44f12002f1168c639e07db9d5600 Original change's description: > [arm] Restrict grouping pushes before a TailCall to registers only > > We optimize parallel moves performed before a TailCall by grouping adjacent > pushes. This way, we may use a single instruction to push multiple registers at > once. However, we also have support for pushing immediates and stack slots for > which the benefit is questionnable therefore this patch removes support for > them. > > Concerning immediate pushes, it looks like a mistake since we do not have > support for this case in `AssembleMove` so this patch removes it. Furthermore, > if we add a test for this case, we see that a `push ip` instruction is > generated, effectively pushing whatever was in `ip` at the time instead of > pushing a constant. > > Concerning stack slot pushes, we generate a more or less equivalent sequence of > instructions. > > Finally, grouping floating point pushes is not used anywhere so this patch > removes support for this also. > > Bug: v8:6553 > Change-Id: I9b820d33361fc442dd813f66e1f96cda41009110 > Reviewed-on: https://chromium-review.googlesource.com/567191 > Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> > Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> > Cr-Commit-Position: refs/heads/master@{#46718} Bug: v8:6553 Change-Id: Ib9a55dae7cc5db6185d163c56088ff23426d04bb Reviewed-on: https://chromium-review.googlesource.com/576087 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Cr-Commit-Position: refs/heads/master@{#46754}
2017-07-13 09:55:16 +00:00
->AddMove(slot_minus_1, slot_2);
instr
->GetOrCreateParallelMove(Instruction::FIRST_GAP_POSITION,
env.main_zone())
Reland "[arm] Restrict grouping pushes before a TailCall to registers only" This is a reland of a72b2f88a8cb44f12002f1168c639e07db9d5600 Original change's description: > [arm] Restrict grouping pushes before a TailCall to registers only > > We optimize parallel moves performed before a TailCall by grouping adjacent > pushes. This way, we may use a single instruction to push multiple registers at > once. However, we also have support for pushing immediates and stack slots for > which the benefit is questionnable therefore this patch removes support for > them. > > Concerning immediate pushes, it looks like a mistake since we do not have > support for this case in `AssembleMove` so this patch removes it. Furthermore, > if we add a test for this case, we see that a `push ip` instruction is > generated, effectively pushing whatever was in `ip` at the time instead of > pushing a constant. > > Concerning stack slot pushes, we generate a more or less equivalent sequence of > instructions. > > Finally, grouping floating point pushes is not used anywhere so this patch > removes support for this also. > > Bug: v8:6553 > Change-Id: I9b820d33361fc442dd813f66e1f96cda41009110 > Reviewed-on: https://chromium-review.googlesource.com/567191 > Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> > Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> > Cr-Commit-Position: refs/heads/master@{#46718} Bug: v8:6553 Change-Id: Ib9a55dae7cc5db6185d163c56088ff23426d04bb Reviewed-on: https://chromium-review.googlesource.com/576087 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Cr-Commit-Position: refs/heads/master@{#46754}
2017-07-13 09:55:16 +00:00
->AddMove(r0, slot_3);
c.CheckAssembleTailCallGaps(instr, first_slot + 4,
CodeGeneratorTester::kScalarPush);
Handle<Code> code = c.Finalize();
if (FLAG_print_code) {
code->Print();
}
Reland "[arm] Restrict grouping pushes before a TailCall to registers only" This is a reland of a72b2f88a8cb44f12002f1168c639e07db9d5600 Original change's description: > [arm] Restrict grouping pushes before a TailCall to registers only > > We optimize parallel moves performed before a TailCall by grouping adjacent > pushes. This way, we may use a single instruction to push multiple registers at > once. However, we also have support for pushing immediates and stack slots for > which the benefit is questionnable therefore this patch removes support for > them. > > Concerning immediate pushes, it looks like a mistake since we do not have > support for this case in `AssembleMove` so this patch removes it. Furthermore, > if we add a test for this case, we see that a `push ip` instruction is > generated, effectively pushing whatever was in `ip` at the time instead of > pushing a constant. > > Concerning stack slot pushes, we generate a more or less equivalent sequence of > instructions. > > Finally, grouping floating point pushes is not used anywhere so this patch > removes support for this also. > > Bug: v8:6553 > Change-Id: I9b820d33361fc442dd813f66e1f96cda41009110 > Reviewed-on: https://chromium-review.googlesource.com/567191 > Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> > Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> > Cr-Commit-Position: refs/heads/master@{#46718} Bug: v8:6553 Change-Id: Ib9a55dae7cc5db6185d163c56088ff23426d04bb Reviewed-on: https://chromium-review.googlesource.com/576087 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Pierre Langlois <pierre.langlois@arm.com> Cr-Commit-Position: refs/heads/master@{#46754}
2017-07-13 09:55:16 +00:00
}
}
} // namespace compiler
} // namespace internal
} // namespace v8