1 /*
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 "base/macros.h"
18 #include "builder.h"
19 #include "dex/dex_instruction.h"
20 #include "nodes.h"
21 #include "optimizing_unit_test.h"
22 #include "pretty_printer.h"
23
24 #include "gtest/gtest.h"
25
26 namespace art HIDDEN {
27
28 /**
29 * Check that the HGraphBuilder adds suspend checks to backward branches.
30 */
31
32 class SuspendCheckTest : public CommonCompilerTest, public OptimizingUnitTestHelper {
33 protected:
34 void TestCode(const std::vector<uint16_t>& data);
35 };
36
TestCode(const std::vector<uint16_t> & data)37 void SuspendCheckTest::TestCode(const std::vector<uint16_t>& data) {
38 HGraph* graph = CreateCFG(data);
39 HBasicBlock* first_block = graph->GetEntryBlock()->GetSingleSuccessor();
40 HBasicBlock* loop_header = first_block->GetSingleSuccessor();
41 ASSERT_TRUE(loop_header->IsLoopHeader());
42 ASSERT_EQ(loop_header->GetLoopInformation()->GetPreHeader(), first_block);
43 ASSERT_TRUE(loop_header->GetFirstInstruction()->IsSuspendCheck());
44 }
45
TEST_F(SuspendCheckTest,CFG1)46 TEST_F(SuspendCheckTest, CFG1) {
47 const std::vector<uint16_t> data = ZERO_REGISTER_CODE_ITEM(
48 Instruction::NOP,
49 Instruction::GOTO | 0xFF00);
50
51 TestCode(data);
52 }
53
TEST_F(SuspendCheckTest,CFG2)54 TEST_F(SuspendCheckTest, CFG2) {
55 const std::vector<uint16_t> data = ZERO_REGISTER_CODE_ITEM(
56 Instruction::GOTO_32, 0, 0);
57
58 TestCode(data);
59 }
60
TEST_F(SuspendCheckTest,CFG3)61 TEST_F(SuspendCheckTest, CFG3) {
62 const std::vector<uint16_t> data = ONE_REGISTER_CODE_ITEM(
63 Instruction::CONST_4 | 0 | 0,
64 Instruction::IF_EQ, 0xFFFF,
65 Instruction::RETURN_VOID);
66
67 TestCode(data);
68 }
69
TEST_F(SuspendCheckTest,CFG4)70 TEST_F(SuspendCheckTest, CFG4) {
71 const std::vector<uint16_t> data = ONE_REGISTER_CODE_ITEM(
72 Instruction::CONST_4 | 0 | 0,
73 Instruction::IF_NE, 0xFFFF,
74 Instruction::RETURN_VOID);
75
76 TestCode(data);
77 }
78
TEST_F(SuspendCheckTest,CFG5)79 TEST_F(SuspendCheckTest, CFG5) {
80 const std::vector<uint16_t> data = ONE_REGISTER_CODE_ITEM(
81 Instruction::CONST_4 | 0 | 0,
82 Instruction::IF_EQZ, 0xFFFF,
83 Instruction::RETURN_VOID);
84
85 TestCode(data);
86 }
87
TEST_F(SuspendCheckTest,CFG6)88 TEST_F(SuspendCheckTest, CFG6) {
89 const std::vector<uint16_t> data = ONE_REGISTER_CODE_ITEM(
90 Instruction::CONST_4 | 0 | 0,
91 Instruction::IF_NEZ, 0xFFFF,
92 Instruction::RETURN_VOID);
93
94 TestCode(data);
95 }
96 } // namespace art
97