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 178cf9cb386cd9286d67e879f1ee501ec00d72a4e1Andreas Gampe#include "gvn.h" 188cf9cb386cd9286d67e879f1ee501ec00d72a4e1Andreas Gampe 19b666f4805c8ae707ea6fd7f6c7f375e0b000dba8Mathieu Chartier#include "base/arena_allocator.h" 20d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray#include "builder.h" 21d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray#include "nodes.h" 22d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray#include "optimizing_unit_test.h" 23827eedbfa882496407375f22b08243a38a5bd53bNicolas Geoffray#include "side_effects_analysis.h" 24d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 2568289a531484d26214e09f1eadd9833531a3bc3cAlex Lightnamespace art { 26d9510dfc32349eeb4f2145c801f7ba1d5bccfb12David Brazdil 27ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Markoclass GVNTest : public OptimizingUnitTest {}; 284833f5a1990c76bc2be89504225fb13cca22bedfDavid Brazdil 294833f5a1990c76bc2be89504225fb13cca22bedfDavid BrazdilTEST_F(GVNTest, LocalFieldElimination) { 30ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HGraph* graph = CreateGraph(); 31ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HBasicBlock* entry = new (GetAllocator()) HBasicBlock(graph); 32d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->AddBlock(entry); 33d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->SetEntryBlock(entry); 34ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HInstruction* parameter = new (GetAllocator()) HParameterValue(graph->GetDexFile(), 35ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko dex::TypeIndex(0), 36ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko 0, 37ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko DataType::Type::kReference); 38d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray entry->AddInstruction(parameter); 39d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 40ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HBasicBlock* block = new (GetAllocator()) HBasicBlock(graph); 41d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->AddBlock(block); 42d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray entry->AddSuccessor(block); 43d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 44ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko block->AddInstruction(new (GetAllocator()) HInstanceFieldGet(parameter, 45ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko nullptr, 46ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko DataType::Type::kReference, 47ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko MemberOffset(42), 48ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko false, 49ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko kUnknownFieldIndex, 50ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko kUnknownClassDefIndex, 51ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko graph->GetDexFile(), 52ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko 0)); 53ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko block->AddInstruction(new (GetAllocator()) HInstanceFieldGet(parameter, 54ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko nullptr, 55ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko DataType::Type::kReference, 56ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko MemberOffset(42), 57ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko false, 58ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko kUnknownFieldIndex, 59ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko kUnknownClassDefIndex, 60ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko graph->GetDexFile(), 61ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko 0)); 62d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray HInstruction* to_remove = block->GetLastInstruction(); 63ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko block->AddInstruction(new (GetAllocator()) HInstanceFieldGet(parameter, 64ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko nullptr, 65ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko DataType::Type::kReference, 66ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko MemberOffset(43), 67ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko false, 68ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko kUnknownFieldIndex, 69ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko kUnknownClassDefIndex, 70ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko graph->GetDexFile(), 71ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko 0)); 72d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray HInstruction* different_offset = block->GetLastInstruction(); 73d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray // Kill the value. 74ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko block->AddInstruction(new (GetAllocator()) HInstanceFieldSet(parameter, 75ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko parameter, 76ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko nullptr, 77ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko DataType::Type::kReference, 78ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko MemberOffset(42), 79ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko false, 80ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko kUnknownFieldIndex, 81ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko kUnknownClassDefIndex, 82ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko graph->GetDexFile(), 83ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko 0)); 84ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko block->AddInstruction(new (GetAllocator()) HInstanceFieldGet(parameter, 85ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko nullptr, 86ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko DataType::Type::kReference, 87ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko MemberOffset(42), 88ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko false, 89ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko kUnknownFieldIndex, 90ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko kUnknownClassDefIndex, 91ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko graph->GetDexFile(), 92ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko 0)); 93d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray HInstruction* use_after_kill = block->GetLastInstruction(); 94ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko block->AddInstruction(new (GetAllocator()) HExit()); 95d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 96d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ASSERT_EQ(to_remove->GetBlock(), block); 97d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ASSERT_EQ(different_offset->GetBlock(), block); 98d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ASSERT_EQ(use_after_kill->GetBlock(), block); 99d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 100badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil graph->BuildDominatorTree(); 101e6f171514c9c499bd0a137aff6bd8a7a79d2682aNicolas Geoffray SideEffectsAnalysis side_effects(graph); 102e6f171514c9c499bd0a137aff6bd8a7a79d2682aNicolas Geoffray side_effects.Run(); 103827eedbfa882496407375f22b08243a38a5bd53bNicolas Geoffray GVNOptimization(graph, side_effects).Run(); 104d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 105d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ASSERT_TRUE(to_remove->GetBlock() == nullptr); 106d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ASSERT_EQ(different_offset->GetBlock(), block); 107d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ASSERT_EQ(use_after_kill->GetBlock(), block); 108d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray} 109d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 1104833f5a1990c76bc2be89504225fb13cca22bedfDavid BrazdilTEST_F(GVNTest, GlobalFieldElimination) { 111ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HGraph* graph = CreateGraph(); 112ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HBasicBlock* entry = new (GetAllocator()) HBasicBlock(graph); 113d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->AddBlock(entry); 114d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->SetEntryBlock(entry); 115ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HInstruction* parameter = new (GetAllocator()) HParameterValue(graph->GetDexFile(), 116ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko dex::TypeIndex(0), 117ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko 0, 118ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko DataType::Type::kReference); 119d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray entry->AddInstruction(parameter); 120d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 121ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HBasicBlock* block = new (GetAllocator()) HBasicBlock(graph); 122d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->AddBlock(block); 123d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray entry->AddSuccessor(block); 124ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko block->AddInstruction(new (GetAllocator()) HInstanceFieldGet(parameter, 125ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko nullptr, 126ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko DataType::Type::kBool, 127ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko MemberOffset(42), 128ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko false, 129ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko kUnknownFieldIndex, 130ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko kUnknownClassDefIndex, 131ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko graph->GetDexFile(), 132ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko 0)); 133ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko 134ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko block->AddInstruction(new (GetAllocator()) HIf(block->GetLastInstruction())); 135ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HBasicBlock* then = new (GetAllocator()) HBasicBlock(graph); 136ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HBasicBlock* else_ = new (GetAllocator()) HBasicBlock(graph); 137ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HBasicBlock* join = new (GetAllocator()) HBasicBlock(graph); 138d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->AddBlock(then); 139d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->AddBlock(else_); 140d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->AddBlock(join); 141d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 142d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray block->AddSuccessor(then); 143d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray block->AddSuccessor(else_); 144d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray then->AddSuccessor(join); 145d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray else_->AddSuccessor(join); 146d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 147ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko then->AddInstruction(new (GetAllocator()) HInstanceFieldGet(parameter, 148ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko nullptr, 149ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko DataType::Type::kBool, 150ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko MemberOffset(42), 151ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko false, 152ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko kUnknownFieldIndex, 153ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko kUnknownClassDefIndex, 154ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko graph->GetDexFile(), 155ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko 0)); 156ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko then->AddInstruction(new (GetAllocator()) HGoto()); 157ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko else_->AddInstruction(new (GetAllocator()) HInstanceFieldGet(parameter, 158ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko nullptr, 159ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko DataType::Type::kBool, 160ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko MemberOffset(42), 161ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko false, 162ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko kUnknownFieldIndex, 163ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko kUnknownClassDefIndex, 164ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko graph->GetDexFile(), 165ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko 0)); 166ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko else_->AddInstruction(new (GetAllocator()) HGoto()); 167ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko join->AddInstruction(new (GetAllocator()) HInstanceFieldGet(parameter, 168ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko nullptr, 169ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko DataType::Type::kBool, 170ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko MemberOffset(42), 171ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko false, 172ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko kUnknownFieldIndex, 173ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko kUnknownClassDefIndex, 174ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko graph->GetDexFile(), 175ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko 0)); 176ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko join->AddInstruction(new (GetAllocator()) HExit()); 177d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 178badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil graph->BuildDominatorTree(); 179e6f171514c9c499bd0a137aff6bd8a7a79d2682aNicolas Geoffray SideEffectsAnalysis side_effects(graph); 180e6f171514c9c499bd0a137aff6bd8a7a79d2682aNicolas Geoffray side_effects.Run(); 181827eedbfa882496407375f22b08243a38a5bd53bNicolas Geoffray GVNOptimization(graph, side_effects).Run(); 182d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 183d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray // Check that all field get instructions have been GVN'ed. 184d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ASSERT_TRUE(then->GetFirstInstruction()->IsGoto()); 185d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ASSERT_TRUE(else_->GetFirstInstruction()->IsGoto()); 186d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ASSERT_TRUE(join->GetFirstInstruction()->IsExit()); 187d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray} 188d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 1894833f5a1990c76bc2be89504225fb13cca22bedfDavid BrazdilTEST_F(GVNTest, LoopFieldElimination) { 190ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HGraph* graph = CreateGraph(); 191ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HBasicBlock* entry = new (GetAllocator()) HBasicBlock(graph); 192d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->AddBlock(entry); 193d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->SetEntryBlock(entry); 194d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 195ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HInstruction* parameter = new (GetAllocator()) HParameterValue(graph->GetDexFile(), 196ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko dex::TypeIndex(0), 197ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko 0, 198ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko DataType::Type::kReference); 199d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray entry->AddInstruction(parameter); 200d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 201ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HBasicBlock* block = new (GetAllocator()) HBasicBlock(graph); 202d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->AddBlock(block); 203d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray entry->AddSuccessor(block); 204ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko block->AddInstruction(new (GetAllocator()) HInstanceFieldGet(parameter, 205ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko nullptr, 206ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko DataType::Type::kBool, 207ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko MemberOffset(42), 208ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko false, 209ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko kUnknownFieldIndex, 210ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko kUnknownClassDefIndex, 211ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko graph->GetDexFile(), 212ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko 0)); 213ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko block->AddInstruction(new (GetAllocator()) HGoto()); 214ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko 215ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HBasicBlock* loop_header = new (GetAllocator()) HBasicBlock(graph); 216ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HBasicBlock* loop_body = new (GetAllocator()) HBasicBlock(graph); 217ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HBasicBlock* exit = new (GetAllocator()) HBasicBlock(graph); 218d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 219d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->AddBlock(loop_header); 220d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->AddBlock(loop_body); 221d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->AddBlock(exit); 222d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray block->AddSuccessor(loop_header); 223d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray loop_header->AddSuccessor(loop_body); 224d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray loop_header->AddSuccessor(exit); 225d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray loop_body->AddSuccessor(loop_header); 226d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 227ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko loop_header->AddInstruction(new (GetAllocator()) HInstanceFieldGet(parameter, 228ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko nullptr, 229ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko DataType::Type::kBool, 230ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko MemberOffset(42), 231ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko false, 232ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko kUnknownFieldIndex, 233ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko kUnknownClassDefIndex, 234ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko graph->GetDexFile(), 235ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko 0)); 236d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray HInstruction* field_get_in_loop_header = loop_header->GetLastInstruction(); 237ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko loop_header->AddInstruction(new (GetAllocator()) HIf(block->GetLastInstruction())); 238d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 239d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray // Kill inside the loop body to prevent field gets inside the loop header 240d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray // and the body to be GVN'ed. 241ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko loop_body->AddInstruction(new (GetAllocator()) HInstanceFieldSet(parameter, 242ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko parameter, 243ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko nullptr, 244ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko DataType::Type::kBool, 245ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko MemberOffset(42), 246ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko false, 247ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko kUnknownFieldIndex, 248ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko kUnknownClassDefIndex, 249ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko graph->GetDexFile(), 250ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko 0)); 251d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray HInstruction* field_set = loop_body->GetLastInstruction(); 252ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko loop_body->AddInstruction(new (GetAllocator()) HInstanceFieldGet(parameter, 253ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko nullptr, 254ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko DataType::Type::kBool, 255ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko MemberOffset(42), 256ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko false, 257ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko kUnknownFieldIndex, 258ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko kUnknownClassDefIndex, 259ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko graph->GetDexFile(), 260ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko 0)); 261d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray HInstruction* field_get_in_loop_body = loop_body->GetLastInstruction(); 262ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko loop_body->AddInstruction(new (GetAllocator()) HGoto()); 263ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko 264ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko exit->AddInstruction(new (GetAllocator()) HInstanceFieldGet(parameter, 265ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko nullptr, 266ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko DataType::Type::kBool, 267ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko MemberOffset(42), 268ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko false, 269ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko kUnknownFieldIndex, 270ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko kUnknownClassDefIndex, 271ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko graph->GetDexFile(), 272ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko 0)); 273d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray HInstruction* field_get_in_exit = exit->GetLastInstruction(); 274ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko exit->AddInstruction(new (GetAllocator()) HExit()); 275d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 276d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ASSERT_EQ(field_get_in_loop_header->GetBlock(), loop_header); 277d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ASSERT_EQ(field_get_in_loop_body->GetBlock(), loop_body); 278d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ASSERT_EQ(field_get_in_exit->GetBlock(), exit); 279d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 280badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil graph->BuildDominatorTree(); 281e6f171514c9c499bd0a137aff6bd8a7a79d2682aNicolas Geoffray { 282e6f171514c9c499bd0a137aff6bd8a7a79d2682aNicolas Geoffray SideEffectsAnalysis side_effects(graph); 283e6f171514c9c499bd0a137aff6bd8a7a79d2682aNicolas Geoffray side_effects.Run(); 284827eedbfa882496407375f22b08243a38a5bd53bNicolas Geoffray GVNOptimization(graph, side_effects).Run(); 285e6f171514c9c499bd0a137aff6bd8a7a79d2682aNicolas Geoffray } 286d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 287d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray // Check that all field get instructions are still there. 288d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ASSERT_EQ(field_get_in_loop_header->GetBlock(), loop_header); 289d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ASSERT_EQ(field_get_in_loop_body->GetBlock(), loop_body); 290d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray // The exit block is dominated by the loop header, whose field get 291d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray // does not get killed by the loop flags. 292d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ASSERT_TRUE(field_get_in_exit->GetBlock() == nullptr); 293d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 294d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray // Now remove the field set, and check that all field get instructions have been GVN'ed. 295d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray loop_body->RemoveInstruction(field_set); 296e6f171514c9c499bd0a137aff6bd8a7a79d2682aNicolas Geoffray { 297e6f171514c9c499bd0a137aff6bd8a7a79d2682aNicolas Geoffray SideEffectsAnalysis side_effects(graph); 298e6f171514c9c499bd0a137aff6bd8a7a79d2682aNicolas Geoffray side_effects.Run(); 299827eedbfa882496407375f22b08243a38a5bd53bNicolas Geoffray GVNOptimization(graph, side_effects).Run(); 300e6f171514c9c499bd0a137aff6bd8a7a79d2682aNicolas Geoffray } 301d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 302d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ASSERT_TRUE(field_get_in_loop_header->GetBlock() == nullptr); 303d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ASSERT_TRUE(field_get_in_loop_body->GetBlock() == nullptr); 304d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ASSERT_TRUE(field_get_in_exit->GetBlock() == nullptr); 305d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray} 306d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 307d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray// Test that inner loops affect the side effects of the outer loop. 3084833f5a1990c76bc2be89504225fb13cca22bedfDavid BrazdilTEST_F(GVNTest, LoopSideEffects) { 30978e3ef6bc5f8aa149f2f8bf0c78ce854c2f910faAlexandre Rames static const SideEffects kCanTriggerGC = SideEffects::CanTriggerGC(); 31078e3ef6bc5f8aa149f2f8bf0c78ce854c2f910faAlexandre Rames 311ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HGraph* graph = CreateGraph(); 312ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HBasicBlock* entry = new (GetAllocator()) HBasicBlock(graph); 313d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->AddBlock(entry); 314d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->SetEntryBlock(entry); 315d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 316ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HBasicBlock* outer_loop_header = new (GetAllocator()) HBasicBlock(graph); 317ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HBasicBlock* outer_loop_body = new (GetAllocator()) HBasicBlock(graph); 318ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HBasicBlock* outer_loop_exit = new (GetAllocator()) HBasicBlock(graph); 319ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HBasicBlock* inner_loop_header = new (GetAllocator()) HBasicBlock(graph); 320ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HBasicBlock* inner_loop_body = new (GetAllocator()) HBasicBlock(graph); 321ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HBasicBlock* inner_loop_exit = new (GetAllocator()) HBasicBlock(graph); 322d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 323d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->AddBlock(outer_loop_header); 324d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->AddBlock(outer_loop_body); 325d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->AddBlock(outer_loop_exit); 326d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->AddBlock(inner_loop_header); 327d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->AddBlock(inner_loop_body); 328d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray graph->AddBlock(inner_loop_exit); 329d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 330d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray entry->AddSuccessor(outer_loop_header); 331d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray outer_loop_header->AddSuccessor(outer_loop_body); 332d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray outer_loop_header->AddSuccessor(outer_loop_exit); 333d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray outer_loop_body->AddSuccessor(inner_loop_header); 334d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray inner_loop_header->AddSuccessor(inner_loop_body); 335d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray inner_loop_header->AddSuccessor(inner_loop_exit); 336d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray inner_loop_body->AddSuccessor(inner_loop_header); 337d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray inner_loop_exit->AddSuccessor(outer_loop_header); 338d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 339ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HInstruction* parameter = new (GetAllocator()) HParameterValue(graph->GetDexFile(), 340ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko dex::TypeIndex(0), 341ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko 0, 342ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko DataType::Type::kBool); 343d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray entry->AddInstruction(parameter); 344ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko entry->AddInstruction(new (GetAllocator()) HGoto()); 345ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko outer_loop_header->AddInstruction(new (GetAllocator()) HSuspendCheck()); 346ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko outer_loop_header->AddInstruction(new (GetAllocator()) HIf(parameter)); 347ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko outer_loop_body->AddInstruction(new (GetAllocator()) HGoto()); 348ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko inner_loop_header->AddInstruction(new (GetAllocator()) HSuspendCheck()); 349ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko inner_loop_header->AddInstruction(new (GetAllocator()) HIf(parameter)); 350ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko inner_loop_body->AddInstruction(new (GetAllocator()) HGoto()); 351ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko inner_loop_exit->AddInstruction(new (GetAllocator()) HGoto()); 352ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko outer_loop_exit->AddInstruction(new (GetAllocator()) HExit()); 353d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 354badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil graph->BuildDominatorTree(); 355d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 356d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray ASSERT_TRUE(inner_loop_header->GetLoopInformation()->IsIn( 357d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray *outer_loop_header->GetLoopInformation())); 358d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 35978e3ef6bc5f8aa149f2f8bf0c78ce854c2f910faAlexandre Rames // Check that the only side effect of loops is to potentially trigger GC. 360d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray { 361d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray // Make one block with a side effect. 362ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko entry->AddInstruction(new (GetAllocator()) HInstanceFieldSet(parameter, 363ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko parameter, 364ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko nullptr, 365ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko DataType::Type::kReference, 366ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko MemberOffset(42), 367ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko false, 368ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko kUnknownFieldIndex, 369ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko kUnknownClassDefIndex, 370ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko graph->GetDexFile(), 371ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko 0)); 372d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 373e6f171514c9c499bd0a137aff6bd8a7a79d2682aNicolas Geoffray SideEffectsAnalysis side_effects(graph); 374e6f171514c9c499bd0a137aff6bd8a7a79d2682aNicolas Geoffray side_effects.Run(); 375d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 376854a02b1b488327f80c544ca1119b386b8715c26Aart Bik ASSERT_TRUE(side_effects.GetBlockEffects(entry).DoesAnyWrite()); 377854a02b1b488327f80c544ca1119b386b8715c26Aart Bik ASSERT_FALSE(side_effects.GetBlockEffects(outer_loop_body).DoesAnyWrite()); 378854a02b1b488327f80c544ca1119b386b8715c26Aart Bik ASSERT_FALSE(side_effects.GetLoopEffects(outer_loop_header).DoesAnyWrite()); 379854a02b1b488327f80c544ca1119b386b8715c26Aart Bik ASSERT_FALSE(side_effects.GetLoopEffects(inner_loop_header).DoesAnyWrite()); 38078e3ef6bc5f8aa149f2f8bf0c78ce854c2f910faAlexandre Rames ASSERT_TRUE(side_effects.GetLoopEffects(outer_loop_header).Equals(kCanTriggerGC)); 38178e3ef6bc5f8aa149f2f8bf0c78ce854c2f910faAlexandre Rames ASSERT_TRUE(side_effects.GetLoopEffects(inner_loop_header).Equals(kCanTriggerGC)); 382d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray } 383d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 384d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray // Check that the side effects of the outer loop does not affect the inner loop. 385d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray { 386d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray outer_loop_body->InsertInstructionBefore( 387ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko new (GetAllocator()) HInstanceFieldSet(parameter, 388ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko parameter, 389ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko nullptr, 390ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko DataType::Type::kReference, 391ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko MemberOffset(42), 392ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko false, 393ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko kUnknownFieldIndex, 394ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko kUnknownClassDefIndex, 395ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko graph->GetDexFile(), 396ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko 0), 397d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray outer_loop_body->GetLastInstruction()); 398d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 399e6f171514c9c499bd0a137aff6bd8a7a79d2682aNicolas Geoffray SideEffectsAnalysis side_effects(graph); 400e6f171514c9c499bd0a137aff6bd8a7a79d2682aNicolas Geoffray side_effects.Run(); 401d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 402854a02b1b488327f80c544ca1119b386b8715c26Aart Bik ASSERT_TRUE(side_effects.GetBlockEffects(entry).DoesAnyWrite()); 403854a02b1b488327f80c544ca1119b386b8715c26Aart Bik ASSERT_TRUE(side_effects.GetBlockEffects(outer_loop_body).DoesAnyWrite()); 404854a02b1b488327f80c544ca1119b386b8715c26Aart Bik ASSERT_TRUE(side_effects.GetLoopEffects(outer_loop_header).DoesAnyWrite()); 405854a02b1b488327f80c544ca1119b386b8715c26Aart Bik ASSERT_FALSE(side_effects.GetLoopEffects(inner_loop_header).DoesAnyWrite()); 40678e3ef6bc5f8aa149f2f8bf0c78ce854c2f910faAlexandre Rames ASSERT_TRUE(side_effects.GetLoopEffects(inner_loop_header).Equals(kCanTriggerGC)); 407d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray } 408d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 409d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray // Check that the side effects of the inner loop affects the outer loop. 410d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray { 411d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray outer_loop_body->RemoveInstruction(outer_loop_body->GetFirstInstruction()); 412d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray inner_loop_body->InsertInstructionBefore( 413ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko new (GetAllocator()) HInstanceFieldSet(parameter, 414ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko parameter, 415ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko nullptr, 416ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko DataType::Type::kReference, 417ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko MemberOffset(42), 418ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko false, 419ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko kUnknownFieldIndex, 420ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko kUnknownClassDefIndex, 421ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko graph->GetDexFile(), 422ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko 0), 423d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray inner_loop_body->GetLastInstruction()); 424d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 425e6f171514c9c499bd0a137aff6bd8a7a79d2682aNicolas Geoffray SideEffectsAnalysis side_effects(graph); 426e6f171514c9c499bd0a137aff6bd8a7a79d2682aNicolas Geoffray side_effects.Run(); 427d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray 428854a02b1b488327f80c544ca1119b386b8715c26Aart Bik ASSERT_TRUE(side_effects.GetBlockEffects(entry).DoesAnyWrite()); 429854a02b1b488327f80c544ca1119b386b8715c26Aart Bik ASSERT_FALSE(side_effects.GetBlockEffects(outer_loop_body).DoesAnyWrite()); 430854a02b1b488327f80c544ca1119b386b8715c26Aart Bik ASSERT_TRUE(side_effects.GetLoopEffects(outer_loop_header).DoesAnyWrite()); 431854a02b1b488327f80c544ca1119b386b8715c26Aart Bik ASSERT_TRUE(side_effects.GetLoopEffects(inner_loop_header).DoesAnyWrite()); 432d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray } 433d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray} 434d31cf3d55a0847c018c4eaa2b349b8eea509de64Nicolas Geoffray} // namespace art 435