• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "unit_test.h"
17 #include "optimizer/code_generator/codegen.h"
18 #include "optimizer/code_generator/method_properties.h"
19 
20 namespace panda::compiler {
21 class MethodPropertiesTest : public GraphTest {
22 public:
CheckCall(Opcode opcode)23     void CheckCall(Opcode opcode)
24     {
25         GRAPH(GetGraph())
26         {
27             PARAMETER(0, 0).ref();
28             BASIC_BLOCK(2, -1)
29             {
30                 INST(1, Opcode::SaveState).Inputs(0).SrcVregs({0});
31                 INST(2, Opcode::NullCheck).ref().Inputs(0, 1);
32                 INST(5, Opcode::SaveState).NoVregs();
33                 INST(3, opcode).v0id().Inputs({{DataType::REFERENCE, 2}, {DataType::NO_TYPE, 5}});
34                 INST(4, Opcode::ReturnVoid).v0id();
35             }
36         }
37         MethodProperties props(GetGraph());
38         EXPECT_TRUE(props.GetHasCalls());
39         EXPECT_TRUE(props.GetHasRuntimeCalls());
40         EXPECT_TRUE(props.GetHasRequireState());
41         EXPECT_FALSE(props.GetHasSafepoints());
42         EXPECT_TRUE(props.GetCanThrow());  // due to null check
43     }
44 };
45 
TEST_F(MethodPropertiesTest,EmptyBlock)46 TEST_F(MethodPropertiesTest, EmptyBlock)
47 {
48     GetGraph()->CreateStartBlock();
49     MethodProperties props(GetGraph());
50     EXPECT_FALSE(props.GetHasCalls());
51     EXPECT_FALSE(props.GetHasRuntimeCalls());
52     EXPECT_FALSE(props.GetHasRequireState());
53     EXPECT_FALSE(props.GetHasSafepoints());
54     EXPECT_FALSE(props.GetCanThrow());
55 }
56 
TEST_F(MethodPropertiesTest,SimpleMethod)57 TEST_F(MethodPropertiesTest, SimpleMethod)
58 {
59     GRAPH(GetGraph())
60     {
61         PARAMETER(0, 0).u32();
62         PARAMETER(1, 1).u32();
63         BASIC_BLOCK(2, -1)
64         {
65             INST(2, Opcode::Add).u32().Inputs(0, 1);
66             INST(3, Opcode::Return).u32().Inputs(2);
67         }
68     }
69     MethodProperties props(GetGraph());
70     EXPECT_FALSE(props.GetHasCalls());
71     EXPECT_FALSE(props.GetHasRuntimeCalls());
72     EXPECT_FALSE(props.GetHasRequireState());
73     EXPECT_FALSE(props.GetHasSafepoints());
74     EXPECT_FALSE(props.GetCanThrow());
75 }
76 
TEST_F(MethodPropertiesTest,SafePoint)77 TEST_F(MethodPropertiesTest, SafePoint)
78 {
79     GRAPH(GetGraph())
80     {
81         PARAMETER(0, 0).u32();
82         PARAMETER(1, 1).u32();
83         BASIC_BLOCK(2, -1)
84         {
85             INST(2, Opcode::Add).u32().Inputs(0, 1);
86             INST(3, Opcode::SafePoint).Inputs(2).SrcVregs({0});
87             INST(4, Opcode::Return).u32().Inputs(2);
88         }
89     }
90     MethodProperties props(GetGraph());
91     EXPECT_FALSE(props.GetHasCalls());
92     EXPECT_TRUE(props.GetHasRuntimeCalls());
93     EXPECT_FALSE(props.GetHasRequireState());
94     EXPECT_TRUE(props.GetHasSafepoints());
95     EXPECT_FALSE(props.GetCanThrow());
96 }
97 
TEST_F(MethodPropertiesTest,StaticCall)98 TEST_F(MethodPropertiesTest, StaticCall)
99 {
100     CheckCall(Opcode::CallStatic);
101 }
102 
TEST_F(MethodPropertiesTest,VirtualCall)103 TEST_F(MethodPropertiesTest, VirtualCall)
104 {
105     CheckCall(Opcode::CallVirtual);
106 }
107 
TEST_F(MethodPropertiesTest,Intrinsic)108 TEST_F(MethodPropertiesTest, Intrinsic)
109 {
110     CheckCall(Opcode::Intrinsic);
111 }
112 
TEST_F(MethodPropertiesTest,Builtin)113 TEST_F(MethodPropertiesTest, Builtin)
114 {
115     GRAPH(GetGraph())
116     {
117         PARAMETER(0, 0).f64();
118         BASIC_BLOCK(2, -1)
119         {
120             INST(1, Opcode::Builtin).b().Inputs({{DataType::FLOAT64, 0}});
121             INST(2, Opcode::Return).b().Inputs(1);
122         }
123     }
124     MethodProperties props(GetGraph());
125     EXPECT_TRUE(props.GetHasCalls());
126     EXPECT_FALSE(props.GetHasRuntimeCalls());
127     EXPECT_FALSE(props.GetHasRequireState());
128     EXPECT_FALSE(props.GetHasSafepoints());
129     EXPECT_FALSE(props.GetCanThrow());
130 }
131 
TEST_F(MethodPropertiesTest,SaveState)132 TEST_F(MethodPropertiesTest, SaveState)
133 {
134     GRAPH(GetGraph())
135     {
136         BASIC_BLOCK(2, -1)
137         {
138             INST(0, Opcode::SaveState).NoVregs();
139             INST(1, Opcode::LoadString).ref().Inputs(0).TypeId(42);
140             INST(2, Opcode::Return).ref().Inputs(1);
141         }
142     }
143     MethodProperties props(GetGraph());
144     EXPECT_FALSE(props.GetHasCalls());
145     EXPECT_TRUE(props.GetHasRuntimeCalls());
146     EXPECT_TRUE(props.GetHasRequireState());
147     EXPECT_FALSE(props.GetHasSafepoints());
148     EXPECT_TRUE(props.GetCanThrow());
149 }
150 }  // namespace panda::compiler
151