1d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray/* 2d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray * Copyright (C) 2014 The Android Open Source Project 3d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray * 4d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray * Licensed under the Apache License, Version 2.0 (the "License"); 5d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray * you may not use this file except in compliance with the License. 6d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray * You may obtain a copy of the License at 7d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray * 8d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray * http://www.apache.org/licenses/LICENSE-2.0 9d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray * 10d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray * Unless required by applicable law or agreed to in writing, software 11d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray * distributed under the License is distributed on an "AS IS" BASIS, 12d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray * See the License for the specific language governing permissions and 14d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray * limitations under the License. 15d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray */ 16d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 17b666f4805c8ae707ea6fd7f6c7f375e0b000dba8Mathieu Chartier#include "base/arena_allocator.h" 18d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray#include "builder.h" 19d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray#include "gvn.h" 20d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray#include "nodes.h" 21d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray#include "optimizing_unit_test.h" 22827eedbfa882496407375f22b08243a38a5bd53bNicolas Geoffray#include "side_effects_analysis.h" 23d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 2468289a531484d26214e09f1eadd9833531a3bc3cAlex Lightnamespace art { 25d9510dfc32349eeb4f2145c801f7ba1d5bccfb12David Brazdil 264833f5a1990c76bc2be89504225fb13cca22bedfDavid Brazdilclass GVNTest : public CommonCompilerTest {}; 274833f5a1990c76bc2be89504225fb13cca22bedfDavid Brazdil 284833f5a1990c76bc2be89504225fb13cca22bedfDavid BrazdilTEST_F(GVNTest, LocalFieldElimination) { 29d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ArenaPool pool; 30d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ArenaAllocator allocator(&pool); 319865bde5d822f56c4732214c2005dfcaa41f94cfMathieu Chartier ScopedNullHandle<mirror::DexCache> dex_cache; 32d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 330a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray HGraph* graph = CreateGraph(&allocator); 34d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray HBasicBlock* entry = new (&allocator) HBasicBlock(graph); 35d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->AddBlock(entry); 36d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->SetEntryBlock(entry); 37e6e3beaf2d35d18a79f5e7b60a21e75fac9fd15dCalin Juravle HInstruction* parameter = new (&allocator) HParameterValue(graph->GetDexFile(), 38e6e3beaf2d35d18a79f5e7b60a21e75fac9fd15dCalin Juravle 0, 39e6e3beaf2d35d18a79f5e7b60a21e75fac9fd15dCalin Juravle 0, 40e6e3beaf2d35d18a79f5e7b60a21e75fac9fd15dCalin Juravle Primitive::kPrimNot); 41d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray entry->AddInstruction(parameter); 42d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 43d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray HBasicBlock* block = new (&allocator) HBasicBlock(graph); 44d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->AddBlock(block); 45d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray entry->AddSuccessor(block); 46d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 47104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez block->AddInstruction(new (&allocator) HInstanceFieldGet(parameter, 48104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez Primitive::kPrimNot, 49104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez MemberOffset(42), 50104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez false, 51104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez kUnknownFieldIndex, 528df69d42a9e3ccd9456ff72fac8dbd1999f98755Mingyao Yang kUnknownClassDefIndex, 53736b560f2d2c89b63dc895888c671b5519afa4c8Mathieu Chartier graph->GetDexFile(), 54154746b84b407cfd166b45e039b62e6a06dc3f39Calin Juravle dex_cache, 55154746b84b407cfd166b45e039b62e6a06dc3f39Calin Juravle 0)); 56104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez block->AddInstruction(new (&allocator) HInstanceFieldGet(parameter, 57104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez Primitive::kPrimNot, 58104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez MemberOffset(42), 59104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez false, 60104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez kUnknownFieldIndex, 618df69d42a9e3ccd9456ff72fac8dbd1999f98755Mingyao Yang kUnknownClassDefIndex, 62736b560f2d2c89b63dc895888c671b5519afa4c8Mathieu Chartier graph->GetDexFile(), 63154746b84b407cfd166b45e039b62e6a06dc3f39Calin Juravle dex_cache, 64154746b84b407cfd166b45e039b62e6a06dc3f39Calin Juravle 0)); 65d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray HInstruction* to_remove = block->GetLastInstruction(); 66104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez block->AddInstruction(new (&allocator) HInstanceFieldGet(parameter, 67104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez Primitive::kPrimNot, 68104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez MemberOffset(43), 69104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez false, 70104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez kUnknownFieldIndex, 718df69d42a9e3ccd9456ff72fac8dbd1999f98755Mingyao Yang kUnknownClassDefIndex, 72736b560f2d2c89b63dc895888c671b5519afa4c8Mathieu Chartier graph->GetDexFile(), 73154746b84b407cfd166b45e039b62e6a06dc3f39Calin Juravle dex_cache, 74154746b84b407cfd166b45e039b62e6a06dc3f39Calin Juravle 0)); 75d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray HInstruction* different_offset = block->GetLastInstruction(); 76d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray // Kill the value. 77104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez block->AddInstruction(new (&allocator) HInstanceFieldSet(parameter, 78104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez parameter, 79104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez Primitive::kPrimNot, 80104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez MemberOffset(42), 81104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez false, 82104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez kUnknownFieldIndex, 838df69d42a9e3ccd9456ff72fac8dbd1999f98755Mingyao Yang kUnknownClassDefIndex, 84736b560f2d2c89b63dc895888c671b5519afa4c8Mathieu Chartier graph->GetDexFile(), 85154746b84b407cfd166b45e039b62e6a06dc3f39Calin Juravle dex_cache, 86154746b84b407cfd166b45e039b62e6a06dc3f39Calin Juravle 0)); 87104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez block->AddInstruction(new (&allocator) HInstanceFieldGet(parameter, 88104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez Primitive::kPrimNot, 89104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez MemberOffset(42), 90104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez false, 91104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez kUnknownFieldIndex, 928df69d42a9e3ccd9456ff72fac8dbd1999f98755Mingyao Yang kUnknownClassDefIndex, 93736b560f2d2c89b63dc895888c671b5519afa4c8Mathieu Chartier graph->GetDexFile(), 94154746b84b407cfd166b45e039b62e6a06dc3f39Calin Juravle dex_cache, 95154746b84b407cfd166b45e039b62e6a06dc3f39Calin Juravle 0)); 96d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray HInstruction* use_after_kill = block->GetLastInstruction(); 97d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray block->AddInstruction(new (&allocator) HExit()); 98d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 99d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ASSERT_EQ(to_remove->GetBlock(), block); 100d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ASSERT_EQ(different_offset->GetBlock(), block); 101d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ASSERT_EQ(use_after_kill->GetBlock(), block); 102d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 103badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil graph->BuildDominatorTree(); 104e6f171514c9c499bd0a137aff6bd8a7a79d2682aNicolas Geoffray SideEffectsAnalysis side_effects(graph); 105e6f171514c9c499bd0a137aff6bd8a7a79d2682aNicolas Geoffray side_effects.Run(); 106827eedbfa882496407375f22b08243a38a5bd53bNicolas Geoffray GVNOptimization(graph, side_effects).Run(); 107d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 108d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ASSERT_TRUE(to_remove->GetBlock() == nullptr); 109d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ASSERT_EQ(different_offset->GetBlock(), block); 110d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ASSERT_EQ(use_after_kill->GetBlock(), block); 111d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray} 112d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 1134833f5a1990c76bc2be89504225fb13cca22bedfDavid BrazdilTEST_F(GVNTest, GlobalFieldElimination) { 114d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ArenaPool pool; 115d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ArenaAllocator allocator(&pool); 1169865bde5d822f56c4732214c2005dfcaa41f94cfMathieu Chartier ScopedNullHandle<mirror::DexCache> dex_cache; 117d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 1180a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray HGraph* graph = CreateGraph(&allocator); 119d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray HBasicBlock* entry = new (&allocator) HBasicBlock(graph); 120d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->AddBlock(entry); 121d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->SetEntryBlock(entry); 122e6e3beaf2d35d18a79f5e7b60a21e75fac9fd15dCalin Juravle HInstruction* parameter = new (&allocator) HParameterValue(graph->GetDexFile(), 123e6e3beaf2d35d18a79f5e7b60a21e75fac9fd15dCalin Juravle 0, 124e6e3beaf2d35d18a79f5e7b60a21e75fac9fd15dCalin Juravle 0, 125e6e3beaf2d35d18a79f5e7b60a21e75fac9fd15dCalin Juravle Primitive::kPrimNot); 126d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray entry->AddInstruction(parameter); 127d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 128d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray HBasicBlock* block = new (&allocator) HBasicBlock(graph); 129d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->AddBlock(block); 130d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray entry->AddSuccessor(block); 131104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez block->AddInstruction(new (&allocator) HInstanceFieldGet(parameter, 132104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez Primitive::kPrimBoolean, 133104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez MemberOffset(42), 134104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez false, 135104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez kUnknownFieldIndex, 1368df69d42a9e3ccd9456ff72fac8dbd1999f98755Mingyao Yang kUnknownClassDefIndex, 137736b560f2d2c89b63dc895888c671b5519afa4c8Mathieu Chartier graph->GetDexFile(), 138154746b84b407cfd166b45e039b62e6a06dc3f39Calin Juravle dex_cache, 139154746b84b407cfd166b45e039b62e6a06dc3f39Calin Juravle 0)); 140d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 141d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray block->AddInstruction(new (&allocator) HIf(block->GetLastInstruction())); 142d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray HBasicBlock* then = new (&allocator) HBasicBlock(graph); 143d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray HBasicBlock* else_ = new (&allocator) HBasicBlock(graph); 144d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray HBasicBlock* join = new (&allocator) HBasicBlock(graph); 145d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->AddBlock(then); 146d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->AddBlock(else_); 147d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->AddBlock(join); 148d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 149d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray block->AddSuccessor(then); 150d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray block->AddSuccessor(else_); 151d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray then->AddSuccessor(join); 152d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray else_->AddSuccessor(join); 153d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 154104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez then->AddInstruction(new (&allocator) HInstanceFieldGet(parameter, 155104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez Primitive::kPrimBoolean, 156104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez MemberOffset(42), 157104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez false, 158104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez kUnknownFieldIndex, 1598df69d42a9e3ccd9456ff72fac8dbd1999f98755Mingyao Yang kUnknownClassDefIndex, 160736b560f2d2c89b63dc895888c671b5519afa4c8Mathieu Chartier graph->GetDexFile(), 161154746b84b407cfd166b45e039b62e6a06dc3f39Calin Juravle dex_cache, 162154746b84b407cfd166b45e039b62e6a06dc3f39Calin Juravle 0)); 163d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray then->AddInstruction(new (&allocator) HGoto()); 164104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez else_->AddInstruction(new (&allocator) HInstanceFieldGet(parameter, 165104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez Primitive::kPrimBoolean, 166104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez MemberOffset(42), 167104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez false, 168104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez kUnknownFieldIndex, 1698df69d42a9e3ccd9456ff72fac8dbd1999f98755Mingyao Yang kUnknownClassDefIndex, 170736b560f2d2c89b63dc895888c671b5519afa4c8Mathieu Chartier graph->GetDexFile(), 171154746b84b407cfd166b45e039b62e6a06dc3f39Calin Juravle dex_cache, 172154746b84b407cfd166b45e039b62e6a06dc3f39Calin Juravle 0)); 173d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray else_->AddInstruction(new (&allocator) HGoto()); 174104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez join->AddInstruction(new (&allocator) HInstanceFieldGet(parameter, 175104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez Primitive::kPrimBoolean, 176104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez MemberOffset(42), 177104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez false, 178104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez kUnknownFieldIndex, 1798df69d42a9e3ccd9456ff72fac8dbd1999f98755Mingyao Yang kUnknownClassDefIndex, 180736b560f2d2c89b63dc895888c671b5519afa4c8Mathieu Chartier graph->GetDexFile(), 181154746b84b407cfd166b45e039b62e6a06dc3f39Calin Juravle dex_cache, 182154746b84b407cfd166b45e039b62e6a06dc3f39Calin Juravle 0)); 183d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray join->AddInstruction(new (&allocator) HExit()); 184d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 185badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil graph->BuildDominatorTree(); 186e6f171514c9c499bd0a137aff6bd8a7a79d2682aNicolas Geoffray SideEffectsAnalysis side_effects(graph); 187e6f171514c9c499bd0a137aff6bd8a7a79d2682aNicolas Geoffray side_effects.Run(); 188827eedbfa882496407375f22b08243a38a5bd53bNicolas Geoffray GVNOptimization(graph, side_effects).Run(); 189d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 190d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray // Check that all field get instructions have been GVN'ed. 191d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ASSERT_TRUE(then->GetFirstInstruction()->IsGoto()); 192d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ASSERT_TRUE(else_->GetFirstInstruction()->IsGoto()); 193d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ASSERT_TRUE(join->GetFirstInstruction()->IsExit()); 194d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray} 195d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 1964833f5a1990c76bc2be89504225fb13cca22bedfDavid BrazdilTEST_F(GVNTest, LoopFieldElimination) { 197d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ArenaPool pool; 198d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ArenaAllocator allocator(&pool); 1999865bde5d822f56c4732214c2005dfcaa41f94cfMathieu Chartier ScopedNullHandle<mirror::DexCache> dex_cache; 200d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 2010a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray HGraph* graph = CreateGraph(&allocator); 202d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray HBasicBlock* entry = new (&allocator) HBasicBlock(graph); 203d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->AddBlock(entry); 204d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->SetEntryBlock(entry); 205d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 206e6e3beaf2d35d18a79f5e7b60a21e75fac9fd15dCalin Juravle HInstruction* parameter = new (&allocator) HParameterValue(graph->GetDexFile(), 207e6e3beaf2d35d18a79f5e7b60a21e75fac9fd15dCalin Juravle 0, 208e6e3beaf2d35d18a79f5e7b60a21e75fac9fd15dCalin Juravle 0, 209e6e3beaf2d35d18a79f5e7b60a21e75fac9fd15dCalin Juravle Primitive::kPrimNot); 210d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray entry->AddInstruction(parameter); 211d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 212d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray HBasicBlock* block = new (&allocator) HBasicBlock(graph); 213d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->AddBlock(block); 214d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray entry->AddSuccessor(block); 215104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez block->AddInstruction(new (&allocator) HInstanceFieldGet(parameter, 216104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez Primitive::kPrimBoolean, 217104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez MemberOffset(42), 218104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez false, 219104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez kUnknownFieldIndex, 2208df69d42a9e3ccd9456ff72fac8dbd1999f98755Mingyao Yang kUnknownClassDefIndex, 221736b560f2d2c89b63dc895888c671b5519afa4c8Mathieu Chartier graph->GetDexFile(), 222154746b84b407cfd166b45e039b62e6a06dc3f39Calin Juravle dex_cache, 223154746b84b407cfd166b45e039b62e6a06dc3f39Calin Juravle 0)); 224d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray block->AddInstruction(new (&allocator) HGoto()); 225d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 226d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray HBasicBlock* loop_header = new (&allocator) HBasicBlock(graph); 227d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray HBasicBlock* loop_body = new (&allocator) HBasicBlock(graph); 228d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray HBasicBlock* exit = new (&allocator) HBasicBlock(graph); 229d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 230d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->AddBlock(loop_header); 231d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->AddBlock(loop_body); 232d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->AddBlock(exit); 233d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray block->AddSuccessor(loop_header); 234d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray loop_header->AddSuccessor(loop_body); 235d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray loop_header->AddSuccessor(exit); 236d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray loop_body->AddSuccessor(loop_header); 237d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 238104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez loop_header->AddInstruction(new (&allocator) HInstanceFieldGet(parameter, 239104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez Primitive::kPrimBoolean, 240104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez MemberOffset(42), 241104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez false, 242104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez kUnknownFieldIndex, 2438df69d42a9e3ccd9456ff72fac8dbd1999f98755Mingyao Yang kUnknownClassDefIndex, 244736b560f2d2c89b63dc895888c671b5519afa4c8Mathieu Chartier graph->GetDexFile(), 245154746b84b407cfd166b45e039b62e6a06dc3f39Calin Juravle dex_cache, 246154746b84b407cfd166b45e039b62e6a06dc3f39Calin Juravle 0)); 247d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray HInstruction* field_get_in_loop_header = loop_header->GetLastInstruction(); 248d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray loop_header->AddInstruction(new (&allocator) HIf(block->GetLastInstruction())); 249d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 250d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray // Kill inside the loop body to prevent field gets inside the loop header 251d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray // and the body to be GVN'ed. 252104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez loop_body->AddInstruction(new (&allocator) HInstanceFieldSet(parameter, 253104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez parameter, 254854a02b1b488327f80c544ca1119b386b8715c26Aart Bik Primitive::kPrimBoolean, 255104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez MemberOffset(42), 256104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez false, 257104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez kUnknownFieldIndex, 2588df69d42a9e3ccd9456ff72fac8dbd1999f98755Mingyao Yang kUnknownClassDefIndex, 259736b560f2d2c89b63dc895888c671b5519afa4c8Mathieu Chartier graph->GetDexFile(), 260154746b84b407cfd166b45e039b62e6a06dc3f39Calin Juravle dex_cache, 261154746b84b407cfd166b45e039b62e6a06dc3f39Calin Juravle 0)); 262d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray HInstruction* field_set = loop_body->GetLastInstruction(); 263104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez loop_body->AddInstruction(new (&allocator) HInstanceFieldGet(parameter, 264104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez Primitive::kPrimBoolean, 265104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez MemberOffset(42), 266104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez false, 267104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez kUnknownFieldIndex, 2688df69d42a9e3ccd9456ff72fac8dbd1999f98755Mingyao Yang kUnknownClassDefIndex, 269736b560f2d2c89b63dc895888c671b5519afa4c8Mathieu Chartier graph->GetDexFile(), 270154746b84b407cfd166b45e039b62e6a06dc3f39Calin Juravle dex_cache, 271154746b84b407cfd166b45e039b62e6a06dc3f39Calin Juravle 0)); 272d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray HInstruction* field_get_in_loop_body = loop_body->GetLastInstruction(); 273d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray loop_body->AddInstruction(new (&allocator) HGoto()); 274d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 275104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez exit->AddInstruction(new (&allocator) HInstanceFieldGet(parameter, 276104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez Primitive::kPrimBoolean, 277104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez MemberOffset(42), 278104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez false, 279104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez kUnknownFieldIndex, 2808df69d42a9e3ccd9456ff72fac8dbd1999f98755Mingyao Yang kUnknownClassDefIndex, 281736b560f2d2c89b63dc895888c671b5519afa4c8Mathieu Chartier graph->GetDexFile(), 282154746b84b407cfd166b45e039b62e6a06dc3f39Calin Juravle dex_cache, 283154746b84b407cfd166b45e039b62e6a06dc3f39Calin Juravle 0)); 284d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray HInstruction* field_get_in_exit = exit->GetLastInstruction(); 285d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray exit->AddInstruction(new (&allocator) HExit()); 286d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 287d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ASSERT_EQ(field_get_in_loop_header->GetBlock(), loop_header); 288d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ASSERT_EQ(field_get_in_loop_body->GetBlock(), loop_body); 289d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ASSERT_EQ(field_get_in_exit->GetBlock(), exit); 290d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 291badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil graph->BuildDominatorTree(); 292e6f171514c9c499bd0a137aff6bd8a7a79d2682aNicolas Geoffray { 293e6f171514c9c499bd0a137aff6bd8a7a79d2682aNicolas Geoffray SideEffectsAnalysis side_effects(graph); 294e6f171514c9c499bd0a137aff6bd8a7a79d2682aNicolas Geoffray side_effects.Run(); 295827eedbfa882496407375f22b08243a38a5bd53bNicolas Geoffray GVNOptimization(graph, side_effects).Run(); 296e6f171514c9c499bd0a137aff6bd8a7a79d2682aNicolas Geoffray } 297d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 298d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray // Check that all field get instructions are still there. 299d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ASSERT_EQ(field_get_in_loop_header->GetBlock(), loop_header); 300d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ASSERT_EQ(field_get_in_loop_body->GetBlock(), loop_body); 301d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray // The exit block is dominated by the loop header, whose field get 302d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray // does not get killed by the loop flags. 303d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ASSERT_TRUE(field_get_in_exit->GetBlock() == nullptr); 304d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 305d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray // Now remove the field set, and check that all field get instructions have been GVN'ed. 306d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray loop_body->RemoveInstruction(field_set); 307e6f171514c9c499bd0a137aff6bd8a7a79d2682aNicolas Geoffray { 308e6f171514c9c499bd0a137aff6bd8a7a79d2682aNicolas Geoffray SideEffectsAnalysis side_effects(graph); 309e6f171514c9c499bd0a137aff6bd8a7a79d2682aNicolas Geoffray side_effects.Run(); 310827eedbfa882496407375f22b08243a38a5bd53bNicolas Geoffray GVNOptimization(graph, side_effects).Run(); 311e6f171514c9c499bd0a137aff6bd8a7a79d2682aNicolas Geoffray } 312d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 313d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ASSERT_TRUE(field_get_in_loop_header->GetBlock() == nullptr); 314d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ASSERT_TRUE(field_get_in_loop_body->GetBlock() == nullptr); 315d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ASSERT_TRUE(field_get_in_exit->GetBlock() == nullptr); 316d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray} 317d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 318d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray// Test that inner loops affect the side effects of the outer loop. 3194833f5a1990c76bc2be89504225fb13cca22bedfDavid BrazdilTEST_F(GVNTest, LoopSideEffects) { 320d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ArenaPool pool; 321d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ArenaAllocator allocator(&pool); 3229865bde5d822f56c4732214c2005dfcaa41f94cfMathieu Chartier ScopedNullHandle<mirror::DexCache> dex_cache; 323d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 32478e3ef6bc5f8aa149f2f8bf0c78ce854c2f910faAlexandre Rames static const SideEffects kCanTriggerGC = SideEffects::CanTriggerGC(); 32578e3ef6bc5f8aa149f2f8bf0c78ce854c2f910faAlexandre Rames 3260a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray HGraph* graph = CreateGraph(&allocator); 327d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray HBasicBlock* entry = new (&allocator) HBasicBlock(graph); 328d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->AddBlock(entry); 329d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->SetEntryBlock(entry); 330d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 331d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray HBasicBlock* outer_loop_header = new (&allocator) HBasicBlock(graph); 332d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray HBasicBlock* outer_loop_body = new (&allocator) HBasicBlock(graph); 333d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray HBasicBlock* outer_loop_exit = new (&allocator) HBasicBlock(graph); 334d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray HBasicBlock* inner_loop_header = new (&allocator) HBasicBlock(graph); 335d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray HBasicBlock* inner_loop_body = new (&allocator) HBasicBlock(graph); 336d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray HBasicBlock* inner_loop_exit = new (&allocator) HBasicBlock(graph); 337d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 338d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->AddBlock(outer_loop_header); 339d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->AddBlock(outer_loop_body); 340d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->AddBlock(outer_loop_exit); 341d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->AddBlock(inner_loop_header); 342d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->AddBlock(inner_loop_body); 343d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->AddBlock(inner_loop_exit); 344d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 345d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray entry->AddSuccessor(outer_loop_header); 346d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray outer_loop_header->AddSuccessor(outer_loop_body); 347d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray outer_loop_header->AddSuccessor(outer_loop_exit); 348d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray outer_loop_body->AddSuccessor(inner_loop_header); 349d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray inner_loop_header->AddSuccessor(inner_loop_body); 350d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray inner_loop_header->AddSuccessor(inner_loop_exit); 351d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray inner_loop_body->AddSuccessor(inner_loop_header); 352d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray inner_loop_exit->AddSuccessor(outer_loop_header); 353d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 354e6e3beaf2d35d18a79f5e7b60a21e75fac9fd15dCalin Juravle HInstruction* parameter = new (&allocator) HParameterValue(graph->GetDexFile(), 355e6e3beaf2d35d18a79f5e7b60a21e75fac9fd15dCalin Juravle 0, 356e6e3beaf2d35d18a79f5e7b60a21e75fac9fd15dCalin Juravle 0, 357e6e3beaf2d35d18a79f5e7b60a21e75fac9fd15dCalin Juravle Primitive::kPrimBoolean); 358d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray entry->AddInstruction(parameter); 359d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray entry->AddInstruction(new (&allocator) HGoto()); 360dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil outer_loop_header->AddInstruction(new (&allocator) HSuspendCheck()); 361d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray outer_loop_header->AddInstruction(new (&allocator) HIf(parameter)); 362d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray outer_loop_body->AddInstruction(new (&allocator) HGoto()); 363dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil inner_loop_header->AddInstruction(new (&allocator) HSuspendCheck()); 364d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray inner_loop_header->AddInstruction(new (&allocator) HIf(parameter)); 365d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray inner_loop_body->AddInstruction(new (&allocator) HGoto()); 366d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray inner_loop_exit->AddInstruction(new (&allocator) HGoto()); 367d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray outer_loop_exit->AddInstruction(new (&allocator) HExit()); 368d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 369badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil graph->BuildDominatorTree(); 370d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 371d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ASSERT_TRUE(inner_loop_header->GetLoopInformation()->IsIn( 372d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray *outer_loop_header->GetLoopInformation())); 373d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 37478e3ef6bc5f8aa149f2f8bf0c78ce854c2f910faAlexandre Rames // Check that the only side effect of loops is to potentially trigger GC. 375d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray { 376d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray // Make one block with a side effect. 377104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez entry->AddInstruction(new (&allocator) HInstanceFieldSet(parameter, 378104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez parameter, 379104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez Primitive::kPrimNot, 380104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez MemberOffset(42), 381104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez false, 382104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez kUnknownFieldIndex, 3838df69d42a9e3ccd9456ff72fac8dbd1999f98755Mingyao Yang kUnknownClassDefIndex, 384736b560f2d2c89b63dc895888c671b5519afa4c8Mathieu Chartier graph->GetDexFile(), 385154746b84b407cfd166b45e039b62e6a06dc3f39Calin Juravle dex_cache, 386154746b84b407cfd166b45e039b62e6a06dc3f39Calin Juravle 0)); 387d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 388e6f171514c9c499bd0a137aff6bd8a7a79d2682aNicolas Geoffray SideEffectsAnalysis side_effects(graph); 389e6f171514c9c499bd0a137aff6bd8a7a79d2682aNicolas Geoffray side_effects.Run(); 390d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 391854a02b1b488327f80c544ca1119b386b8715c26Aart Bik ASSERT_TRUE(side_effects.GetBlockEffects(entry).DoesAnyWrite()); 392854a02b1b488327f80c544ca1119b386b8715c26Aart Bik ASSERT_FALSE(side_effects.GetBlockEffects(outer_loop_body).DoesAnyWrite()); 393854a02b1b488327f80c544ca1119b386b8715c26Aart Bik ASSERT_FALSE(side_effects.GetLoopEffects(outer_loop_header).DoesAnyWrite()); 394854a02b1b488327f80c544ca1119b386b8715c26Aart Bik ASSERT_FALSE(side_effects.GetLoopEffects(inner_loop_header).DoesAnyWrite()); 39578e3ef6bc5f8aa149f2f8bf0c78ce854c2f910faAlexandre Rames ASSERT_TRUE(side_effects.GetLoopEffects(outer_loop_header).Equals(kCanTriggerGC)); 39678e3ef6bc5f8aa149f2f8bf0c78ce854c2f910faAlexandre Rames ASSERT_TRUE(side_effects.GetLoopEffects(inner_loop_header).Equals(kCanTriggerGC)); 397d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray } 398d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 399d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray // Check that the side effects of the outer loop does not affect the inner loop. 400d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray { 401d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray outer_loop_body->InsertInstructionBefore( 402104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez new (&allocator) HInstanceFieldSet(parameter, 403104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez parameter, 404104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez Primitive::kPrimNot, 405104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez MemberOffset(42), 406104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez false, 407104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez kUnknownFieldIndex, 4088df69d42a9e3ccd9456ff72fac8dbd1999f98755Mingyao Yang kUnknownClassDefIndex, 409736b560f2d2c89b63dc895888c671b5519afa4c8Mathieu Chartier graph->GetDexFile(), 410154746b84b407cfd166b45e039b62e6a06dc3f39Calin Juravle dex_cache, 411154746b84b407cfd166b45e039b62e6a06dc3f39Calin Juravle 0), 412d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray outer_loop_body->GetLastInstruction()); 413d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 414e6f171514c9c499bd0a137aff6bd8a7a79d2682aNicolas Geoffray SideEffectsAnalysis side_effects(graph); 415e6f171514c9c499bd0a137aff6bd8a7a79d2682aNicolas Geoffray side_effects.Run(); 416d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 417854a02b1b488327f80c544ca1119b386b8715c26Aart Bik ASSERT_TRUE(side_effects.GetBlockEffects(entry).DoesAnyWrite()); 418854a02b1b488327f80c544ca1119b386b8715c26Aart Bik ASSERT_TRUE(side_effects.GetBlockEffects(outer_loop_body).DoesAnyWrite()); 419854a02b1b488327f80c544ca1119b386b8715c26Aart Bik ASSERT_TRUE(side_effects.GetLoopEffects(outer_loop_header).DoesAnyWrite()); 420854a02b1b488327f80c544ca1119b386b8715c26Aart Bik ASSERT_FALSE(side_effects.GetLoopEffects(inner_loop_header).DoesAnyWrite()); 42178e3ef6bc5f8aa149f2f8bf0c78ce854c2f910faAlexandre Rames ASSERT_TRUE(side_effects.GetLoopEffects(inner_loop_header).Equals(kCanTriggerGC)); 422d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray } 423d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 424d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray // Check that the side effects of the inner loop affects the outer loop. 425d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray { 426d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray outer_loop_body->RemoveInstruction(outer_loop_body->GetFirstInstruction()); 427d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray inner_loop_body->InsertInstructionBefore( 428104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez new (&allocator) HInstanceFieldSet(parameter, 429104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez parameter, 430104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez Primitive::kPrimNot, 431104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez MemberOffset(42), 432104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez false, 433104fd8a3f30ddcf07831250571aa2a233cd5c04dGuillaume "Vermeille" Sanchez kUnknownFieldIndex, 4348df69d42a9e3ccd9456ff72fac8dbd1999f98755Mingyao Yang kUnknownClassDefIndex, 435736b560f2d2c89b63dc895888c671b5519afa4c8Mathieu Chartier graph->GetDexFile(), 436154746b84b407cfd166b45e039b62e6a06dc3f39Calin Juravle dex_cache, 437154746b84b407cfd166b45e039b62e6a06dc3f39Calin Juravle 0), 438d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray inner_loop_body->GetLastInstruction()); 439d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 440e6f171514c9c499bd0a137aff6bd8a7a79d2682aNicolas Geoffray SideEffectsAnalysis side_effects(graph); 441e6f171514c9c499bd0a137aff6bd8a7a79d2682aNicolas Geoffray side_effects.Run(); 442d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 443854a02b1b488327f80c544ca1119b386b8715c26Aart Bik ASSERT_TRUE(side_effects.GetBlockEffects(entry).DoesAnyWrite()); 444854a02b1b488327f80c544ca1119b386b8715c26Aart Bik ASSERT_FALSE(side_effects.GetBlockEffects(outer_loop_body).DoesAnyWrite()); 445854a02b1b488327f80c544ca1119b386b8715c26Aart Bik ASSERT_TRUE(side_effects.GetLoopEffects(outer_loop_header).DoesAnyWrite()); 446854a02b1b488327f80c544ca1119b386b8715c26Aart Bik ASSERT_TRUE(side_effects.GetLoopEffects(inner_loop_header).DoesAnyWrite()); 447d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray } 448d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray} 449d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray} // namespace art 450