blob: 62629bcd0c868293526546fb760dab88819e8348 [file] [log] [blame]
Nicolas Geoffray4e3d23a2014-05-22 18:32:45 +01001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "nodes.h"
18#include "parallel_move_resolver.h"
19#include "utils/arena_allocator.h"
20
21#include "gtest/gtest.h"
22
23namespace art {
24
25class TestParallelMoveResolver : public ParallelMoveResolver {
26 public:
27 explicit TestParallelMoveResolver(ArenaAllocator* allocator) : ParallelMoveResolver(allocator) {}
28
29 virtual void EmitMove(size_t index) {
30 MoveOperands* move = moves_.Get(index);
31 if (!message_.str().empty()) {
32 message_ << " ";
33 }
34 message_ << "("
Nicolas Geoffray56b9ee62014-10-09 11:47:51 +010035 << move->GetSource().reg()
Nicolas Geoffray4e3d23a2014-05-22 18:32:45 +010036 << " -> "
Nicolas Geoffray56b9ee62014-10-09 11:47:51 +010037 << move->GetDestination().reg()
Nicolas Geoffray4e3d23a2014-05-22 18:32:45 +010038 << ")";
39 }
40
41 virtual void EmitSwap(size_t index) {
42 MoveOperands* move = moves_.Get(index);
43 if (!message_.str().empty()) {
44 message_ << " ";
45 }
46 message_ << "("
Nicolas Geoffray56b9ee62014-10-09 11:47:51 +010047 << move->GetSource().reg()
Nicolas Geoffray4e3d23a2014-05-22 18:32:45 +010048 << " <-> "
Nicolas Geoffray56b9ee62014-10-09 11:47:51 +010049 << move->GetDestination().reg()
Nicolas Geoffray4e3d23a2014-05-22 18:32:45 +010050 << ")";
51 }
52
Ian Rogers6a3c1fc2014-10-31 00:33:20 -070053 virtual void SpillScratch(int reg ATTRIBUTE_UNUSED) {}
54 virtual void RestoreScratch(int reg ATTRIBUTE_UNUSED) {}
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +010055
Nicolas Geoffray4e3d23a2014-05-22 18:32:45 +010056 std::string GetMessage() const {
57 return message_.str();
58 }
59
60 private:
61 std::ostringstream message_;
62
63
64 DISALLOW_COPY_AND_ASSIGN(TestParallelMoveResolver);
65};
66
67static HParallelMove* BuildParallelMove(ArenaAllocator* allocator,
68 const size_t operands[][2],
69 size_t number_of_moves) {
70 HParallelMove* moves = new (allocator) HParallelMove(allocator);
71 for (size_t i = 0; i < number_of_moves; ++i) {
72 moves->AddMove(new (allocator) MoveOperands(
Nicolas Geoffray56b9ee62014-10-09 11:47:51 +010073 Location::RegisterLocation(operands[i][0]),
74 Location::RegisterLocation(operands[i][1]),
Nicolas Geoffray740475d2014-09-29 10:33:25 +010075 nullptr));
Nicolas Geoffray4e3d23a2014-05-22 18:32:45 +010076 }
77 return moves;
78}
79
80TEST(ParallelMoveTest, Dependency) {
81 ArenaPool pool;
82 ArenaAllocator allocator(&pool);
83
84 {
85 TestParallelMoveResolver resolver(&allocator);
86 static constexpr size_t moves[][2] = {{0, 1}, {1, 2}};
87 resolver.EmitNativeCode(BuildParallelMove(&allocator, moves, arraysize(moves)));
88 ASSERT_STREQ("(1 -> 2) (0 -> 1)", resolver.GetMessage().c_str());
89 }
90
91 {
92 TestParallelMoveResolver resolver(&allocator);
93 static constexpr size_t moves[][2] = {{0, 1}, {1, 2}, {2, 3}, {1, 4}};
94 resolver.EmitNativeCode(BuildParallelMove(&allocator, moves, arraysize(moves)));
95 ASSERT_STREQ("(2 -> 3) (1 -> 2) (1 -> 4) (0 -> 1)", resolver.GetMessage().c_str());
96 }
97}
98
99TEST(ParallelMoveTest, Swap) {
100 ArenaPool pool;
101 ArenaAllocator allocator(&pool);
102
103 {
104 TestParallelMoveResolver resolver(&allocator);
105 static constexpr size_t moves[][2] = {{0, 1}, {1, 0}};
106 resolver.EmitNativeCode(BuildParallelMove(&allocator, moves, arraysize(moves)));
107 ASSERT_STREQ("(1 <-> 0)", resolver.GetMessage().c_str());
108 }
109
110 {
111 TestParallelMoveResolver resolver(&allocator);
112 static constexpr size_t moves[][2] = {{0, 1}, {1, 2}, {1, 0}};
113 resolver.EmitNativeCode(BuildParallelMove(&allocator, moves, arraysize(moves)));
114 ASSERT_STREQ("(1 -> 2) (1 <-> 0)", resolver.GetMessage().c_str());
115 }
116
117 {
118 TestParallelMoveResolver resolver(&allocator);
119 static constexpr size_t moves[][2] = {{0, 1}, {1, 2}, {2, 3}, {3, 4}, {4, 1}};
120 resolver.EmitNativeCode(BuildParallelMove(&allocator, moves, arraysize(moves)));
121 ASSERT_STREQ("(4 <-> 1) (3 <-> 4) (2 <-> 3) (0 -> 1)", resolver.GetMessage().c_str());
122 }
123
124 {
125 TestParallelMoveResolver resolver(&allocator);
126 static constexpr size_t moves[][2] = {{0, 1}, {1, 2}, {2, 3}, {3, 4}, {4, 1}, {5, 4}};
127 resolver.EmitNativeCode(BuildParallelMove(&allocator, moves, arraysize(moves)));
128 ASSERT_STREQ("(4 <-> 1) (3 <-> 4) (2 <-> 3) (0 -> 1) (5 -> 4)", resolver.GetMessage().c_str());
129 }
130}
131
132} // namespace art