blob: e4f9371e62f4bb8afc901c86826c033e6c54a3ab [file] [log] [blame]
Nicolas Geoffray0d3f5782014-05-14 09:43:38 +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 <fstream>
18
19#include "base/stringprintf.h"
20#include "builder.h"
Nicolas Geoffray31d76b42014-06-09 15:02:22 +010021#include "code_generator.h"
Nicolas Geoffray0d3f5782014-05-14 09:43:38 +010022#include "dex_file.h"
23#include "dex_instruction.h"
24#include "graph_visualizer.h"
25#include "nodes.h"
26#include "optimizing_unit_test.h"
27#include "pretty_printer.h"
28#include "ssa_builder.h"
29#include "ssa_liveness_analysis.h"
30#include "utils/arena_allocator.h"
31
32#include "gtest/gtest.h"
33
34namespace art {
35
36static void TestCode(const uint16_t* data, const int* expected_order, size_t number_of_blocks) {
37 ArenaPool pool;
38 ArenaAllocator allocator(&pool);
39 HGraphBuilder builder(&allocator);
40 const DexFile::CodeItem* item = reinterpret_cast<const DexFile::CodeItem*>(data);
41 HGraph* graph = builder.BuildGraph(*item);
42 ASSERT_NE(graph, nullptr);
43
44 graph->BuildDominatorTree();
Nicolas Geoffray31d76b42014-06-09 15:02:22 +010045 graph->TransformToSSA();
Nicolas Geoffray0d3f5782014-05-14 09:43:38 +010046 graph->FindNaturalLoops();
Nicolas Geoffray31d76b42014-06-09 15:02:22 +010047
48 CodeGenerator* codegen = CodeGenerator::Create(&allocator, graph, InstructionSet::kX86);
49 SsaLivenessAnalysis liveness(*graph, codegen);
Nicolas Geoffray0d3f5782014-05-14 09:43:38 +010050 liveness.Analyze();
51
52 ASSERT_EQ(liveness.GetLinearPostOrder().Size(), number_of_blocks);
53 for (size_t i = 0; i < number_of_blocks; ++i) {
54 ASSERT_EQ(liveness.GetLinearPostOrder().Get(number_of_blocks - i - 1)->GetBlockId(),
55 expected_order[i]);
56 }
57}
58
59TEST(LinearizeTest, CFG1) {
Nicolas Geoffray8f1a4d42014-05-16 09:36:00 +010060 // Structure of this graph (+ are back edges)
Nicolas Geoffray0d3f5782014-05-14 09:43:38 +010061 // Block0
62 // |
63 // Block1
64 // |
Nicolas Geoffray8f1a4d42014-05-16 09:36:00 +010065 // Block2 ++++++
66 // / \ +
67 // Block5 Block7 +
68 // | | +
69 // Block6 Block3 +
70 // + / \ +
Nicolas Geoffray0d3f5782014-05-14 09:43:38 +010071 // Block4 Block8
72
73 const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
74 Instruction::CONST_4 | 0 | 0,
75 Instruction::IF_EQ, 5,
76 Instruction::IF_EQ, 0xFFFE,
77 Instruction::GOTO | 0xFE00,
78 Instruction::RETURN_VOID);
79
80 const int blocks[] = {0, 1, 2, 7, 3, 4, 8, 5, 6};
81 TestCode(data, blocks, 9);
82}
83
84TEST(LinearizeTest, CFG2) {
Nicolas Geoffray8f1a4d42014-05-16 09:36:00 +010085 // Structure of this graph (+ are back edges)
Nicolas Geoffray0d3f5782014-05-14 09:43:38 +010086 // Block0
87 // |
88 // Block1
89 // |
Nicolas Geoffray8f1a4d42014-05-16 09:36:00 +010090 // Block2 ++++++
91 // / \ +
92 // Block3 Block7 +
93 // | | +
94 // Block6 Block4 +
95 // + / \ +
Nicolas Geoffray0d3f5782014-05-14 09:43:38 +010096 // Block5 Block8
97
98 const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
99 Instruction::CONST_4 | 0 | 0,
100 Instruction::IF_EQ, 3,
101 Instruction::RETURN_VOID,
102 Instruction::IF_EQ, 0xFFFD,
103 Instruction::GOTO | 0xFE00);
104
105 const int blocks[] = {0, 1, 2, 7, 4, 5, 8, 3, 6};
106 TestCode(data, blocks, 9);
107}
108
109TEST(LinearizeTest, CFG3) {
Nicolas Geoffray8f1a4d42014-05-16 09:36:00 +0100110 // Structure of this graph (+ are back edges)
Nicolas Geoffray0d3f5782014-05-14 09:43:38 +0100111 // Block0
112 // |
113 // Block1
114 // |
Nicolas Geoffray8f1a4d42014-05-16 09:36:00 +0100115 // Block2 ++++++
116 // / \ +
117 // Block3 Block8 +
118 // | | +
119 // Block7 Block5 +
120 // / + \ +
121 // Block6 + Block9
122 // | +
123 // Block4 ++
Nicolas Geoffray0d3f5782014-05-14 09:43:38 +0100124 const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
125 Instruction::CONST_4 | 0 | 0,
126 Instruction::IF_EQ, 4,
127 Instruction::RETURN_VOID,
128 Instruction::GOTO | 0x0100,
129 Instruction::IF_EQ, 0xFFFC,
130 Instruction::GOTO | 0xFD00);
131
132 const int blocks[] = {0, 1, 2, 8, 5, 6, 4, 9, 3, 7};
133 TestCode(data, blocks, 10);
134}
135
136TEST(LinearizeTest, CFG4) {
Nicolas Geoffray8f1a4d42014-05-16 09:36:00 +0100137 /* Structure of this graph (+ are back edges)
Nicolas Geoffray0d3f5782014-05-14 09:43:38 +0100138 // Block0
139 // |
140 // Block1
141 // |
142 // Block2
Nicolas Geoffray8f1a4d42014-05-16 09:36:00 +0100143 // / + \
144 // Block6 + Block8
145 // | + |
146 // Block7 + Block3 +++++++
147 // + / \ +
148 // Block9 Block10 +
149 // | +
150 // Block4 +
151 // + / \ +
Nicolas Geoffray0d3f5782014-05-14 09:43:38 +0100152 // Block5 Block11
Nicolas Geoffray8f1a4d42014-05-16 09:36:00 +0100153 */
Nicolas Geoffray0d3f5782014-05-14 09:43:38 +0100154 const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
155 Instruction::CONST_4 | 0 | 0,
156 Instruction::IF_EQ, 7,
157 Instruction::IF_EQ, 0xFFFE,
158 Instruction::IF_EQ, 0xFFFE,
159 Instruction::GOTO | 0xFE00,
160 Instruction::RETURN_VOID);
161
162 const int blocks[] = {0, 1, 2, 8, 3, 10, 4, 5, 11, 9, 6, 7};
163 TestCode(data, blocks, 12);
164}
165
166TEST(LinearizeTest, CFG5) {
Nicolas Geoffray8f1a4d42014-05-16 09:36:00 +0100167 /* Structure of this graph (+ are back edges)
Nicolas Geoffray0d3f5782014-05-14 09:43:38 +0100168 // Block0
169 // |
170 // Block1
171 // |
172 // Block2
Nicolas Geoffray8f1a4d42014-05-16 09:36:00 +0100173 // / + \
174 // Block3 + Block8
175 // | + |
176 // Block7 + Block4 +++++++
177 // + / \ +
178 // Block9 Block10 +
179 // | +
180 // Block5 +
181 // +/ \ +
Nicolas Geoffray0d3f5782014-05-14 09:43:38 +0100182 // Block6 Block11
Nicolas Geoffray8f1a4d42014-05-16 09:36:00 +0100183 */
Nicolas Geoffray0d3f5782014-05-14 09:43:38 +0100184 const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
185 Instruction::CONST_4 | 0 | 0,
186 Instruction::IF_EQ, 3,
187 Instruction::RETURN_VOID,
188 Instruction::IF_EQ, 0xFFFD,
189 Instruction::IF_EQ, 0xFFFE,
190 Instruction::GOTO | 0xFE00);
191
192 const int blocks[] = {0, 1, 2, 8, 4, 10, 5, 6, 11, 9, 3, 7};
193 TestCode(data, blocks, 12);
194}
195
196} // namespace art