blob: 813f7cec1cf92ff8c5b6b39ce9b6e7517f079f35 [file] [log] [blame]
Aart Bik854a02b2015-07-14 16:07:00 -07001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not read 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 "gtest/gtest.h"
18#include "nodes.h"
19#include "primitive.h"
20
21namespace art {
22
23/**
24 * Tests for the SideEffects class.
25 */
26
27//
28// Helper methods.
29//
30
31void testWriteAndReadSanity(SideEffects write, SideEffects read) {
32 EXPECT_FALSE(write.DoesNothing());
33 EXPECT_FALSE(read.DoesNothing());
34
35 EXPECT_TRUE(write.DoesAnyWrite());
36 EXPECT_FALSE(write.DoesAnyRead());
37 EXPECT_FALSE(read.DoesAnyWrite());
38 EXPECT_TRUE(read.DoesAnyRead());
39
40 // All-dependences.
41 SideEffects all = SideEffects::All();
42 EXPECT_TRUE(all.MayDependOn(write));
43 EXPECT_FALSE(write.MayDependOn(all));
44 EXPECT_FALSE(all.MayDependOn(read));
45 EXPECT_TRUE(read.MayDependOn(all));
46
47 // None-dependences.
48 SideEffects none = SideEffects::None();
49 EXPECT_FALSE(none.MayDependOn(write));
50 EXPECT_FALSE(write.MayDependOn(none));
51 EXPECT_FALSE(none.MayDependOn(read));
52 EXPECT_FALSE(read.MayDependOn(none));
53}
54
55void testWriteAndReadDependence(SideEffects write, SideEffects read) {
56 testWriteAndReadSanity(write, read);
57
58 // Dependence only in one direction.
59 EXPECT_FALSE(write.MayDependOn(read));
60 EXPECT_TRUE(read.MayDependOn(write));
61}
62
63void testNoWriteAndReadDependence(SideEffects write, SideEffects read) {
64 testWriteAndReadSanity(write, read);
65
66 // No dependence in any direction.
67 EXPECT_FALSE(write.MayDependOn(read));
68 EXPECT_FALSE(read.MayDependOn(write));
69}
70
71//
72// Actual tests.
73//
74
75TEST(SideEffectsTest, All) {
76 SideEffects all = SideEffects::All();
77 EXPECT_TRUE(all.DoesAnyWrite());
78 EXPECT_TRUE(all.DoesAnyRead());
79 EXPECT_FALSE(all.DoesNothing());
80 EXPECT_TRUE(all.DoesAll());
81}
82
83TEST(SideEffectsTest, None) {
84 SideEffects none = SideEffects::None();
85 EXPECT_FALSE(none.DoesAnyWrite());
86 EXPECT_FALSE(none.DoesAnyRead());
87 EXPECT_TRUE(none.DoesNothing());
88 EXPECT_FALSE(none.DoesAll());
89}
90
91TEST(SideEffectsTest, DependencesAndNoDependences) {
92 // Apply test to each individual primitive type.
93 for (Primitive::Type type = Primitive::kPrimNot;
94 type < Primitive::kPrimVoid;
95 type = Primitive::Type(type + 1)) {
96 // Same primitive type and access type: proper write/read dep.
97 testWriteAndReadDependence(
98 SideEffects::FieldWriteOfType(type),
99 SideEffects::FieldReadOfType(type));
100 testWriteAndReadDependence(
101 SideEffects::ArrayWriteOfType(type),
102 SideEffects::ArrayReadOfType(type));
103 // Same primitive type but different access type: no write/read dep.
104 testNoWriteAndReadDependence(
105 SideEffects::FieldWriteOfType(type),
106 SideEffects::ArrayReadOfType(type));
107 testNoWriteAndReadDependence(
108 SideEffects::ArrayWriteOfType(type),
109 SideEffects::FieldReadOfType(type));
110 }
111}
112
113TEST(SideEffectsTest, NoDependences) {
114 // Different primitive type, same access type: no write/read dep.
115 testNoWriteAndReadDependence(
116 SideEffects::FieldWriteOfType(Primitive::kPrimInt),
117 SideEffects::FieldReadOfType(Primitive::kPrimDouble));
118 testNoWriteAndReadDependence(
119 SideEffects::ArrayWriteOfType(Primitive::kPrimInt),
120 SideEffects::ArrayReadOfType(Primitive::kPrimDouble));
121 // Everything different: no write/read dep.
122 testNoWriteAndReadDependence(
123 SideEffects::FieldWriteOfType(Primitive::kPrimInt),
124 SideEffects::ArrayReadOfType(Primitive::kPrimDouble));
125 testNoWriteAndReadDependence(
126 SideEffects::ArrayWriteOfType(Primitive::kPrimInt),
127 SideEffects::FieldReadOfType(Primitive::kPrimDouble));
128}
129
130TEST(SideEffectsTest, SameWidthTypes) {
131 // Type I/F.
132 testWriteAndReadDependence(
133 SideEffects::FieldWriteOfType(Primitive::kPrimInt),
134 SideEffects::FieldReadOfType(Primitive::kPrimFloat));
135 testWriteAndReadDependence(
136 SideEffects::ArrayWriteOfType(Primitive::kPrimInt),
137 SideEffects::ArrayReadOfType(Primitive::kPrimFloat));
138 // Type L/D.
139 testWriteAndReadDependence(
140 SideEffects::FieldWriteOfType(Primitive::kPrimLong),
141 SideEffects::FieldReadOfType(Primitive::kPrimDouble));
142 testWriteAndReadDependence(
143 SideEffects::ArrayWriteOfType(Primitive::kPrimLong),
144 SideEffects::ArrayReadOfType(Primitive::kPrimDouble));
145}
146
147TEST(SideEffectsTest, AllWritesAndReads) {
148 SideEffects s = SideEffects::None();
149 // Keep taking the union of different writes and reads.
150 for (Primitive::Type type = Primitive::kPrimNot;
151 type < Primitive::kPrimVoid;
152 type = Primitive::Type(type + 1)) {
153 s = s.Union(SideEffects::FieldWriteOfType(type));
154 s = s.Union(SideEffects::ArrayWriteOfType(type));
155 s = s.Union(SideEffects::FieldReadOfType(type));
156 s = s.Union(SideEffects::ArrayReadOfType(type));
157 }
158 EXPECT_TRUE(s.DoesAll());
159}
160
161TEST(SideEffectsTest, BitStrings) {
162 EXPECT_STREQ(
163 "|||||",
164 SideEffects::None().ToString().c_str());
165 EXPECT_STREQ(
166 "|DFJISCBZL|DFJISCBZL|DFJISCBZL|DFJISCBZL|",
167 SideEffects::All().ToString().c_str());
168 EXPECT_STREQ(
169 "||||L|",
170 SideEffects::FieldWriteOfType(Primitive::kPrimNot).ToString().c_str());
171 EXPECT_STREQ(
172 "|||Z||",
173 SideEffects::ArrayWriteOfType(Primitive::kPrimBoolean).ToString().c_str());
174 EXPECT_STREQ(
175 "||B|||",
176 SideEffects::FieldReadOfType(Primitive::kPrimByte).ToString().c_str());
177 EXPECT_STREQ(
178 "|DJ||||", // note: DJ alias
179 SideEffects::ArrayReadOfType(Primitive::kPrimDouble).ToString().c_str());
180 SideEffects s = SideEffects::None();
181 s = s.Union(SideEffects::FieldWriteOfType(Primitive::kPrimChar));
182 s = s.Union(SideEffects::FieldWriteOfType(Primitive::kPrimLong));
183 s = s.Union(SideEffects::ArrayWriteOfType(Primitive::kPrimShort));
184 s = s.Union(SideEffects::FieldReadOfType(Primitive::kPrimInt));
185 s = s.Union(SideEffects::ArrayReadOfType(Primitive::kPrimFloat));
186 s = s.Union(SideEffects::ArrayReadOfType(Primitive::kPrimDouble));
187 EXPECT_STREQ(
188 "|DFJI|FI|S|DJC|", // note: DJ/FI alias.
189 s.ToString().c_str());
190}
191
192} // namespace art