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

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: Add a TODO. 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
52 TEST_F(InstructionTest, OperandInterference) {
53 // All general registers and slots interfere only with themselves.
54 for (int i = 0; i < RegisterConfiguration::kMaxGeneralRegisters; ++i) {
55 EXPECT_TRUE(Interfere(LocationOperand::REGISTER, kWord, i, kWord, i));
56 EXPECT_TRUE(Interfere(LocationOperand::STACK_SLOT, kWord, i, kWord, i));
57 for (int j = i + 1; j < RegisterConfiguration::kMaxGeneralRegisters; ++j) {
58 EXPECT_FALSE(Interfere(LocationOperand::REGISTER, kWord, i, kWord, j));
59 EXPECT_FALSE(Interfere(LocationOperand::STACK_SLOT, kWord, i, kWord, j));
60 }
61 }
62
63 // All FP registers interfere with themselves.
64 for (int i = 0; i < RegisterConfiguration::kMaxFPRegisters; ++i) {
65 EXPECT_TRUE(Interfere(LocationOperand::REGISTER, kFloat, i, kFloat, i));
66 EXPECT_TRUE(Interfere(LocationOperand::STACK_SLOT, kFloat, i, kFloat, i));
67 EXPECT_TRUE(Interfere(LocationOperand::REGISTER, kDouble, i, kDouble, i));
68 EXPECT_TRUE(Interfere(LocationOperand::STACK_SLOT, kDouble, i, kDouble, i));
69 }
70
71 if (kSimpleFPAliasing) {
72 // Simple FP aliasing: interfering registers of different reps have the same
73 // index.
74 for (int i = 0; i < RegisterConfiguration::kMaxFPRegisters; ++i) {
75 EXPECT_TRUE(Interfere(LocationOperand::REGISTER, kFloat, i, kDouble, i));
76 EXPECT_TRUE(Interfere(LocationOperand::REGISTER, kDouble, i, kFloat, i));
77 for (int j = i + 1; j < RegisterConfiguration::kMaxFPRegisters; ++j) {
78 EXPECT_FALSE(Interfere(LocationOperand::REGISTER, kWord, i, kWord, j));
79 EXPECT_FALSE(
80 Interfere(LocationOperand::STACK_SLOT, kWord, i, kWord, j));
81 }
82 }
83 } else {
84 // Complex FP aliasing: sub-registers intefere with containing registers.
85 // Test sub-register indices which may not exist on the platform. This is
86 // necessary since the GapResolver may split large moves into smaller ones.
87 for (int i = 0; i < RegisterConfiguration::kMaxFPRegisters; ++i) {
88 EXPECT_TRUE(
89 Interfere(LocationOperand::REGISTER, kFloat, i * 2, kDouble, i));
90 EXPECT_TRUE(
91 Interfere(LocationOperand::REGISTER, kFloat, i * 2 + 1, kDouble, i));
92 EXPECT_TRUE(
93 Interfere(LocationOperand::REGISTER, kDouble, i, kFloat, i * 2));
94 EXPECT_TRUE(
95 Interfere(LocationOperand::REGISTER, kDouble, i, kFloat, i * 2 + 1));
96
97 for (int j = i + 1; j < RegisterConfiguration::kMaxFPRegisters; ++j) {
98 EXPECT_FALSE(
99 Interfere(LocationOperand::REGISTER, kFloat, i * 2, kDouble, j));
100 EXPECT_FALSE(Interfere(LocationOperand::REGISTER, kFloat, i * 2 + 1,
101 kDouble, j));
102 EXPECT_FALSE(
103 Interfere(LocationOperand::REGISTER, kDouble, i, kFloat, j * 2));
104 EXPECT_FALSE(Interfere(LocationOperand::REGISTER, kDouble, i, kFloat,
105 j * 2 + 1));
106 }
107 }
108 }
109 }
110
111 TEST_F(InstructionTest, PrepareInsertAfter) {
112 InstructionOperand r0 = AllocatedOperand(LocationOperand::REGISTER,
113 MachineRepresentation::kWord32, 0);
114 InstructionOperand r1 = AllocatedOperand(LocationOperand::REGISTER,
115 MachineRepresentation::kWord32, 1);
116 InstructionOperand r2 = AllocatedOperand(LocationOperand::REGISTER,
117 MachineRepresentation::kWord32, 2);
118
119 InstructionOperand d0 = AllocatedOperand(LocationOperand::REGISTER,
120 MachineRepresentation::kFloat64, 0);
121 InstructionOperand d1 = AllocatedOperand(LocationOperand::REGISTER,
122 MachineRepresentation::kFloat64, 1);
123 InstructionOperand d2 = AllocatedOperand(LocationOperand::REGISTER,
124 MachineRepresentation::kFloat64, 2);
125
126 {
127 // Moves inserted after should pick up assignments to their sources.
128 // Moves inserted after should cause interfering moves to be eliminated.
129 ZoneVector<MoveOperands*> to_eliminate(zone());
130 std::vector<InstructionOperand> moves = {
131 r1, r0, // r1 <- r0
132 r2, r0, // r2 <- r0
133 d1, d0, // d1 <- d0
134 d2, d0 // d2 <- d0
135 };
136
137 ParallelMove* pm = CreateParallelMove(moves);
138 MoveOperands m1(r1, r2); // r2 <- r1
139 pm->PrepareInsertAfter(&m1, &to_eliminate);
140 CHECK(m1.source().Equals(r0));
141 CHECK(Contains(&to_eliminate, r2, r0));
142 MoveOperands m2(d1, d2); // d2 <- d1
143 pm->PrepareInsertAfter(&m2, &to_eliminate);
144 CHECK(m2.source().Equals(d0));
145 CHECK(Contains(&to_eliminate, d2, d0));
146 }
147
148 if (!kSimpleFPAliasing) {
149 // Moves inserted after should cause all interfering moves to be eliminated.
150 auto s0 = AllocatedOperand(LocationOperand::REGISTER,
151 MachineRepresentation::kFloat32, 0);
152 auto s1 = AllocatedOperand(LocationOperand::REGISTER,
153 MachineRepresentation::kFloat32, 1);
154 auto s2 = AllocatedOperand(LocationOperand::REGISTER,
155 MachineRepresentation::kFloat32, 2);
156
157 {
158 ZoneVector<MoveOperands*> to_eliminate(zone());
159 std::vector<InstructionOperand> moves = {
160 s0, s2, // s0 <- s2
161 s1, s2 // s1 <- s2
162 };
163
164 ParallelMove* pm = CreateParallelMove(moves);
165 MoveOperands m1(d1, d0); // d0 <- d1
166 pm->PrepareInsertAfter(&m1, &to_eliminate);
167 CHECK(Contains(&to_eliminate, s0, s2));
168 CHECK(Contains(&to_eliminate, s1, s2));
169 }
170 }
171 }
172
173 } // namespace compiler
174 } // namespace internal
175 } // namespace v8
OLDNEW
« no previous file with comments | « test/unittests/compiler/instruction-sequence-unittest.cc ('k') | test/unittests/compiler/move-optimizer-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698