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

Side by Side Diff: test/unittests/compiler/instruction-unittest.cc

Issue 2410673002: [Turbofan] Add concept of FP register aliasing on ARM 32. (Closed)
Patch Set: Block default fns on InstructionTest. Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/compiler/instruction.h"
6 #include "src/register-configuration.h"
7 #include "test/unittests/test-utils.h"
8 #include "testing/gtest-support.h"
9
10 namespace v8 {
11 namespace internal {
12 namespace compiler {
13
14 namespace {
15
16 const MachineRepresentation kWord = MachineRepresentation::kWord32;
17 const MachineRepresentation kFloat = MachineRepresentation::kFloat32;
18 const MachineRepresentation kDouble = MachineRepresentation::kFloat64;
19
20 bool Interfere(LocationOperand::LocationKind kind, MachineRepresentation rep1,
21 int index1, MachineRepresentation rep2, int index2) {
22 return AllocatedOperand(kind, rep1, index1)
23 .InterferesWith(AllocatedOperand(kind, rep2, index2));
24 }
25
26 bool Contains(const ZoneVector<MoveOperands*>* moves,
27 const InstructionOperand& to, const InstructionOperand& from) {
28 for (auto move : *moves) {
29 if (move->destination().Equals(to) && move->source().Equals(from)) {
30 return true;
31 }
32 }
33 return false;
34 }
35
36 } // namespace
37
38 class InstructionTest : public TestWithZone {
39 public:
40 InstructionTest() {}
41 virtual ~InstructionTest() {}
42
43 ParallelMove* CreateParallelMove(
44 const std::vector<InstructionOperand>& operand_pairs) {
45 ParallelMove* parallel_move = new (zone()) ParallelMove(zone());
46 for (size_t i = 0; i < operand_pairs.size(); i += 2)
47 parallel_move->AddMove(operand_pairs[i + 1], operand_pairs[i]);
48 return parallel_move;
49 }
50
51 private:
52 DISALLOW_COPY_AND_ASSIGN(InstructionTest);
53 };
54
55 TEST_F(InstructionTest, OperandInterference) {
56 // All general registers and slots interfere only with themselves.
57 for (int i = 0; i < RegisterConfiguration::kMaxGeneralRegisters; ++i) {
58 EXPECT_TRUE(Interfere(LocationOperand::REGISTER, kWord, i, kWord, i));
59 EXPECT_TRUE(Interfere(LocationOperand::STACK_SLOT, kWord, i, kWord, i));
60 for (int j = i + 1; j < RegisterConfiguration::kMaxGeneralRegisters; ++j) {
61 EXPECT_FALSE(Interfere(LocationOperand::REGISTER, kWord, i, kWord, j));
62 EXPECT_FALSE(Interfere(LocationOperand::STACK_SLOT, kWord, i, kWord, j));
63 }
64 }
65
66 // All FP registers interfere with themselves.
67 for (int i = 0; i < RegisterConfiguration::kMaxFPRegisters; ++i) {
68 EXPECT_TRUE(Interfere(LocationOperand::REGISTER, kFloat, i, kFloat, i));
69 EXPECT_TRUE(Interfere(LocationOperand::STACK_SLOT, kFloat, i, kFloat, i));
70 EXPECT_TRUE(Interfere(LocationOperand::REGISTER, kDouble, i, kDouble, i));
71 EXPECT_TRUE(Interfere(LocationOperand::STACK_SLOT, kDouble, i, kDouble, i));
72 }
73
74 if (kSimpleFPAliasing) {
75 // Simple FP aliasing: interfering registers of different reps have the same
76 // index.
77 for (int i = 0; i < RegisterConfiguration::kMaxFPRegisters; ++i) {
78 EXPECT_TRUE(Interfere(LocationOperand::REGISTER, kFloat, i, kDouble, i));
79 EXPECT_TRUE(Interfere(LocationOperand::REGISTER, kDouble, i, kFloat, i));
80 for (int j = i + 1; j < RegisterConfiguration::kMaxFPRegisters; ++j) {
81 EXPECT_FALSE(Interfere(LocationOperand::REGISTER, kWord, i, kWord, j));
82 EXPECT_FALSE(
83 Interfere(LocationOperand::STACK_SLOT, kWord, i, kWord, j));
84 }
85 }
86 } else {
87 // Complex FP aliasing: sub-registers intefere with containing registers.
88 // Test sub-register indices which may not exist on the platform. This is
89 // necessary since the GapResolver may split large moves into smaller ones.
90 for (int i = 0; i < RegisterConfiguration::kMaxFPRegisters; ++i) {
91 EXPECT_TRUE(
92 Interfere(LocationOperand::REGISTER, kFloat, i * 2, kDouble, i));
93 EXPECT_TRUE(
94 Interfere(LocationOperand::REGISTER, kFloat, i * 2 + 1, kDouble, i));
95 EXPECT_TRUE(
96 Interfere(LocationOperand::REGISTER, kDouble, i, kFloat, i * 2));
97 EXPECT_TRUE(
98 Interfere(LocationOperand::REGISTER, kDouble, i, kFloat, i * 2 + 1));
99
100 for (int j = i + 1; j < RegisterConfiguration::kMaxFPRegisters; ++j) {
101 EXPECT_FALSE(
102 Interfere(LocationOperand::REGISTER, kFloat, i * 2, kDouble, j));
103 EXPECT_FALSE(Interfere(LocationOperand::REGISTER, kFloat, i * 2 + 1,
104 kDouble, j));
105 EXPECT_FALSE(
106 Interfere(LocationOperand::REGISTER, kDouble, i, kFloat, j * 2));
107 EXPECT_FALSE(Interfere(LocationOperand::REGISTER, kDouble, i, kFloat,
108 j * 2 + 1));
109 }
110 }
111 }
112 }
113
114 TEST_F(InstructionTest, PrepareInsertAfter) {
115 InstructionOperand r0 = AllocatedOperand(LocationOperand::REGISTER,
116 MachineRepresentation::kWord32, 0);
117 InstructionOperand r1 = AllocatedOperand(LocationOperand::REGISTER,
118 MachineRepresentation::kWord32, 1);
119 InstructionOperand r2 = AllocatedOperand(LocationOperand::REGISTER,
120 MachineRepresentation::kWord32, 2);
121
122 InstructionOperand d0 = AllocatedOperand(LocationOperand::REGISTER,
123 MachineRepresentation::kFloat64, 0);
124 InstructionOperand d1 = AllocatedOperand(LocationOperand::REGISTER,
125 MachineRepresentation::kFloat64, 1);
126 InstructionOperand d2 = AllocatedOperand(LocationOperand::REGISTER,
127 MachineRepresentation::kFloat64, 2);
128
129 {
130 // Moves inserted after should pick up assignments to their sources.
131 // Moves inserted after should cause interfering moves to be eliminated.
132 ZoneVector<MoveOperands*> to_eliminate(zone());
133 std::vector<InstructionOperand> moves = {
134 r1, r0, // r1 <- r0
135 r2, r0, // r2 <- r0
136 d1, d0, // d1 <- d0
137 d2, d0 // d2 <- d0
138 };
139
140 ParallelMove* pm = CreateParallelMove(moves);
141 MoveOperands m1(r1, r2); // r2 <- r1
142 pm->PrepareInsertAfter(&m1, &to_eliminate);
143 CHECK(m1.source().Equals(r0));
144 CHECK(Contains(&to_eliminate, r2, r0));
145 MoveOperands m2(d1, d2); // d2 <- d1
146 pm->PrepareInsertAfter(&m2, &to_eliminate);
147 CHECK(m2.source().Equals(d0));
148 CHECK(Contains(&to_eliminate, d2, d0));
149 }
150
151 if (!kSimpleFPAliasing) {
152 // Moves inserted after should cause all interfering moves to be eliminated.
153 auto s0 = AllocatedOperand(LocationOperand::REGISTER,
154 MachineRepresentation::kFloat32, 0);
155 auto s1 = AllocatedOperand(LocationOperand::REGISTER,
156 MachineRepresentation::kFloat32, 1);
157 auto s2 = AllocatedOperand(LocationOperand::REGISTER,
158 MachineRepresentation::kFloat32, 2);
159
160 {
161 ZoneVector<MoveOperands*> to_eliminate(zone());
162 std::vector<InstructionOperand> moves = {
163 s0, s2, // s0 <- s2
164 s1, s2 // s1 <- s2
165 };
166
167 ParallelMove* pm = CreateParallelMove(moves);
168 MoveOperands m1(d1, d0); // d0 <- d1
169 pm->PrepareInsertAfter(&m1, &to_eliminate);
170 CHECK(Contains(&to_eliminate, s0, s2));
171 CHECK(Contains(&to_eliminate, s1, s2));
172 }
173 }
174 }
175
176 } // namespace compiler
177 } // namespace internal
178 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698