Home | History | Annotate | Download | only in optimizing
      1 /*
      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 
     19 #include "data_type.h"
     20 #include "nodes.h"
     21 
     22 namespace art {
     23 
     24 // Only runtime types other than void are allowed.
     25 static const DataType::Type kTestTypes[] = {
     26     DataType::Type::kReference,
     27     DataType::Type::kBool,
     28     DataType::Type::kInt8,
     29     DataType::Type::kUint16,
     30     DataType::Type::kInt16,
     31     DataType::Type::kInt32,
     32     DataType::Type::kInt64,
     33     DataType::Type::kFloat32,
     34     DataType::Type::kFloat64,
     35 };
     36 
     37 /**
     38  * Tests for the SideEffects class.
     39  */
     40 
     41 //
     42 // Helper methods.
     43 //
     44 
     45 void testWriteAndReadSanity(SideEffects write, SideEffects read) {
     46   EXPECT_FALSE(write.DoesNothing());
     47   EXPECT_FALSE(read.DoesNothing());
     48 
     49   EXPECT_TRUE(write.DoesAnyWrite());
     50   EXPECT_FALSE(write.DoesAnyRead());
     51   EXPECT_FALSE(read.DoesAnyWrite());
     52   EXPECT_TRUE(read.DoesAnyRead());
     53 
     54   // All-dependences.
     55   SideEffects all = SideEffects::All();
     56   EXPECT_TRUE(all.MayDependOn(write));
     57   EXPECT_FALSE(write.MayDependOn(all));
     58   EXPECT_FALSE(all.MayDependOn(read));
     59   EXPECT_TRUE(read.MayDependOn(all));
     60 
     61   // None-dependences.
     62   SideEffects none = SideEffects::None();
     63   EXPECT_FALSE(none.MayDependOn(write));
     64   EXPECT_FALSE(write.MayDependOn(none));
     65   EXPECT_FALSE(none.MayDependOn(read));
     66   EXPECT_FALSE(read.MayDependOn(none));
     67 }
     68 
     69 void testWriteAndReadDependence(SideEffects write, SideEffects read) {
     70   testWriteAndReadSanity(write, read);
     71 
     72   // Dependence only in one direction.
     73   EXPECT_FALSE(write.MayDependOn(read));
     74   EXPECT_TRUE(read.MayDependOn(write));
     75 }
     76 
     77 void testNoWriteAndReadDependence(SideEffects write, SideEffects read) {
     78   testWriteAndReadSanity(write, read);
     79 
     80   // No dependence in any direction.
     81   EXPECT_FALSE(write.MayDependOn(read));
     82   EXPECT_FALSE(read.MayDependOn(write));
     83 }
     84 
     85 //
     86 // Actual tests.
     87 //
     88 
     89 TEST(SideEffectsTest, All) {
     90   SideEffects all = SideEffects::All();
     91   EXPECT_TRUE(all.DoesAnyWrite());
     92   EXPECT_TRUE(all.DoesAnyRead());
     93   EXPECT_FALSE(all.DoesNothing());
     94   EXPECT_TRUE(all.DoesAllReadWrite());
     95 }
     96 
     97 TEST(SideEffectsTest, None) {
     98   SideEffects none = SideEffects::None();
     99   EXPECT_FALSE(none.DoesAnyWrite());
    100   EXPECT_FALSE(none.DoesAnyRead());
    101   EXPECT_TRUE(none.DoesNothing());
    102   EXPECT_FALSE(none.DoesAllReadWrite());
    103 }
    104 
    105 TEST(SideEffectsTest, DependencesAndNoDependences) {
    106   // Apply test to each individual data type.
    107   for (DataType::Type type : kTestTypes) {
    108     // Same data type and access type: proper write/read dep.
    109     testWriteAndReadDependence(
    110         SideEffects::FieldWriteOfType(type, false),
    111         SideEffects::FieldReadOfType(type, false));
    112     testWriteAndReadDependence(
    113         SideEffects::ArrayWriteOfType(type),
    114         SideEffects::ArrayReadOfType(type));
    115     // Same data type but different access type: no write/read dep.
    116     testNoWriteAndReadDependence(
    117         SideEffects::FieldWriteOfType(type, false),
    118         SideEffects::ArrayReadOfType(type));
    119     testNoWriteAndReadDependence(
    120         SideEffects::ArrayWriteOfType(type),
    121         SideEffects::FieldReadOfType(type, false));
    122   }
    123 }
    124 
    125 TEST(SideEffectsTest, NoDependences) {
    126   // Different data type, same access type: no write/read dep.
    127   testNoWriteAndReadDependence(
    128       SideEffects::FieldWriteOfType(DataType::Type::kInt32, false),
    129       SideEffects::FieldReadOfType(DataType::Type::kFloat64, false));
    130   testNoWriteAndReadDependence(
    131       SideEffects::ArrayWriteOfType(DataType::Type::kInt32),
    132       SideEffects::ArrayReadOfType(DataType::Type::kFloat64));
    133   // Everything different: no write/read dep.
    134   testNoWriteAndReadDependence(
    135       SideEffects::FieldWriteOfType(DataType::Type::kInt32, false),
    136       SideEffects::ArrayReadOfType(DataType::Type::kFloat64));
    137   testNoWriteAndReadDependence(
    138       SideEffects::ArrayWriteOfType(DataType::Type::kInt32),
    139       SideEffects::FieldReadOfType(DataType::Type::kFloat64, false));
    140 }
    141 
    142 TEST(SideEffectsTest, VolatileDependences) {
    143   SideEffects volatile_write =
    144       SideEffects::FieldWriteOfType(DataType::Type::kInt32, /* is_volatile */ true);
    145   SideEffects any_write =
    146       SideEffects::FieldWriteOfType(DataType::Type::kInt32, /* is_volatile */ false);
    147   SideEffects volatile_read =
    148       SideEffects::FieldReadOfType(DataType::Type::kInt8, /* is_volatile */ true);
    149   SideEffects any_read =
    150       SideEffects::FieldReadOfType(DataType::Type::kInt8, /* is_volatile */ false);
    151 
    152   EXPECT_FALSE(volatile_write.MayDependOn(any_read));
    153   EXPECT_TRUE(any_read.MayDependOn(volatile_write));
    154   EXPECT_TRUE(volatile_write.MayDependOn(any_write));
    155   EXPECT_FALSE(any_write.MayDependOn(volatile_write));
    156 
    157   EXPECT_FALSE(volatile_read.MayDependOn(any_read));
    158   EXPECT_TRUE(any_read.MayDependOn(volatile_read));
    159   EXPECT_TRUE(volatile_read.MayDependOn(any_write));
    160   EXPECT_FALSE(any_write.MayDependOn(volatile_read));
    161 }
    162 
    163 TEST(SideEffectsTest, SameWidthTypesNoAlias) {
    164   // Type I/F.
    165   testNoWriteAndReadDependence(
    166       SideEffects::FieldWriteOfType(DataType::Type::kInt32, /* is_volatile */ false),
    167       SideEffects::FieldReadOfType(DataType::Type::kFloat32, /* is_volatile */ false));
    168   testNoWriteAndReadDependence(
    169       SideEffects::ArrayWriteOfType(DataType::Type::kInt32),
    170       SideEffects::ArrayReadOfType(DataType::Type::kFloat32));
    171   // Type L/D.
    172   testNoWriteAndReadDependence(
    173       SideEffects::FieldWriteOfType(DataType::Type::kInt64, /* is_volatile */ false),
    174       SideEffects::FieldReadOfType(DataType::Type::kFloat64, /* is_volatile */ false));
    175   testNoWriteAndReadDependence(
    176       SideEffects::ArrayWriteOfType(DataType::Type::kInt64),
    177       SideEffects::ArrayReadOfType(DataType::Type::kFloat64));
    178 }
    179 
    180 TEST(SideEffectsTest, AllWritesAndReads) {
    181   SideEffects s = SideEffects::None();
    182   // Keep taking the union of different writes and reads.
    183   for (DataType::Type type : kTestTypes) {
    184     s = s.Union(SideEffects::FieldWriteOfType(type, /* is_volatile */ false));
    185     s = s.Union(SideEffects::ArrayWriteOfType(type));
    186     s = s.Union(SideEffects::FieldReadOfType(type, /* is_volatile */ false));
    187     s = s.Union(SideEffects::ArrayReadOfType(type));
    188   }
    189   EXPECT_TRUE(s.DoesAllReadWrite());
    190 }
    191 
    192 TEST(SideEffectsTest, GC) {
    193   SideEffects can_trigger_gc = SideEffects::CanTriggerGC();
    194   SideEffects depends_on_gc = SideEffects::DependsOnGC();
    195   SideEffects all_changes = SideEffects::AllChanges();
    196   SideEffects all_dependencies = SideEffects::AllDependencies();
    197 
    198   EXPECT_TRUE(depends_on_gc.MayDependOn(can_trigger_gc));
    199   EXPECT_TRUE(depends_on_gc.Union(can_trigger_gc).MayDependOn(can_trigger_gc));
    200   EXPECT_FALSE(can_trigger_gc.MayDependOn(depends_on_gc));
    201 
    202   EXPECT_TRUE(depends_on_gc.MayDependOn(all_changes));
    203   EXPECT_TRUE(depends_on_gc.Union(can_trigger_gc).MayDependOn(all_changes));
    204   EXPECT_FALSE(can_trigger_gc.MayDependOn(all_changes));
    205 
    206   EXPECT_TRUE(all_changes.Includes(can_trigger_gc));
    207   EXPECT_FALSE(all_changes.Includes(depends_on_gc));
    208   EXPECT_TRUE(all_dependencies.Includes(depends_on_gc));
    209   EXPECT_FALSE(all_dependencies.Includes(can_trigger_gc));
    210 }
    211 
    212 TEST(SideEffectsTest, BitStrings) {
    213   EXPECT_STREQ(
    214       "|||||||",
    215       SideEffects::None().ToString().c_str());
    216   EXPECT_STREQ(
    217       "|GC|DFJISCBZL|DFJISCBZL|GC|DFJISCBZL|DFJISCBZL|",
    218       SideEffects::All().ToString().c_str());
    219   EXPECT_STREQ(
    220       "|||||DFJISCBZL|DFJISCBZL|",
    221       SideEffects::AllWrites().ToString().c_str());
    222   EXPECT_STREQ(
    223       "||DFJISCBZL|DFJISCBZL||||",
    224       SideEffects::AllReads().ToString().c_str());
    225   EXPECT_STREQ(
    226       "||||||L|",
    227       SideEffects::FieldWriteOfType(DataType::Type::kReference, false).ToString().c_str());
    228   EXPECT_STREQ(
    229       "||DFJISCBZL|DFJISCBZL||DFJISCBZL|DFJISCBZL|",
    230       SideEffects::FieldWriteOfType(DataType::Type::kReference, true).ToString().c_str());
    231   EXPECT_STREQ(
    232       "|||||Z||",
    233       SideEffects::ArrayWriteOfType(DataType::Type::kBool).ToString().c_str());
    234   EXPECT_STREQ(
    235       "|||||C||",
    236       SideEffects::ArrayWriteOfType(DataType::Type::kUint16).ToString().c_str());
    237   EXPECT_STREQ(
    238       "|||||S||",
    239       SideEffects::ArrayWriteOfType(DataType::Type::kInt16).ToString().c_str());
    240   EXPECT_STREQ(
    241       "|||B||||",
    242       SideEffects::FieldReadOfType(DataType::Type::kInt8, false).ToString().c_str());
    243   EXPECT_STREQ(
    244       "||D|||||",
    245       SideEffects::ArrayReadOfType(DataType::Type::kFloat64).ToString().c_str());
    246   EXPECT_STREQ(
    247       "||J|||||",
    248       SideEffects::ArrayReadOfType(DataType::Type::kInt64).ToString().c_str());
    249   EXPECT_STREQ(
    250       "||F|||||",
    251       SideEffects::ArrayReadOfType(DataType::Type::kFloat32).ToString().c_str());
    252   EXPECT_STREQ(
    253       "||I|||||",
    254       SideEffects::ArrayReadOfType(DataType::Type::kInt32).ToString().c_str());
    255   SideEffects s = SideEffects::None();
    256   s = s.Union(SideEffects::FieldWriteOfType(DataType::Type::kUint16, /* is_volatile */ false));
    257   s = s.Union(SideEffects::FieldWriteOfType(DataType::Type::kInt64, /* is_volatile */ false));
    258   s = s.Union(SideEffects::ArrayWriteOfType(DataType::Type::kInt16));
    259   s = s.Union(SideEffects::FieldReadOfType(DataType::Type::kInt32, /* is_volatile */ false));
    260   s = s.Union(SideEffects::ArrayReadOfType(DataType::Type::kFloat32));
    261   s = s.Union(SideEffects::ArrayReadOfType(DataType::Type::kFloat64));
    262   EXPECT_STREQ("||DF|I||S|JC|", s.ToString().c_str());
    263 }
    264 
    265 }  // namespace art
    266