1724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray/* 2724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray * Copyright (C) 2014 The Android Open Source Project 3724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray * 4724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray * Licensed under the Apache License, Version 2.0 (the "License"); 5724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray * you may not use this file except in compliance with the License. 6724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray * You may obtain a copy of the License at 7724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray * 8724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray * http://www.apache.org/licenses/LICENSE-2.0 9724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray * 10724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray * Unless required by applicable law or agreed to in writing, software 11724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray * distributed under the License is distributed on an "AS IS" BASIS, 12724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray * See the License for the specific language governing permissions and 14724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray * limitations under the License. 15724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray */ 16724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray 17724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray#include "nodes.h" 188cf9cb386cd9286d67e879f1ee501ec00d72a4e1Andreas Gampe 198cf9cb386cd9286d67e879f1ee501ec00d72a4e1Andreas Gampe#include "base/arena_allocator.h" 200a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray#include "optimizing_unit_test.h" 21724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray 22724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray#include "gtest/gtest.h" 23724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray 24724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffraynamespace art { 25724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray 26ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Markoclass NodeTest : public OptimizingUnitTest {}; 27ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko 28724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray/** 29724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray * Test that removing instruction from the graph removes itself from user lists 30724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray * and environment lists. 31724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray */ 32ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir MarkoTEST_F(NodeTest, RemoveInstruction) { 33ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HGraph* graph = CreateGraph(); 34ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HBasicBlock* entry = new (GetAllocator()) HBasicBlock(graph); 35724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray graph->AddBlock(entry); 36724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray graph->SetEntryBlock(entry); 37ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HInstruction* parameter = new (GetAllocator()) HParameterValue( 380ebe0d83138bba1996e9c8007969b5381d972b32Vladimir Marko graph->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kReference); 39724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray entry->AddInstruction(parameter); 40ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko entry->AddInstruction(new (GetAllocator()) HGoto()); 41724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray 42ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HBasicBlock* first_block = new (GetAllocator()) HBasicBlock(graph); 43724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray graph->AddBlock(first_block); 44724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray entry->AddSuccessor(first_block); 45ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HInstruction* null_check = new (GetAllocator()) HNullCheck(parameter, 0); 46724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray first_block->AddInstruction(null_check); 47ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko first_block->AddInstruction(new (GetAllocator()) HReturnVoid()); 48724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray 49ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HBasicBlock* exit_block = new (GetAllocator()) HBasicBlock(graph); 50724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray graph->AddBlock(exit_block); 51724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray first_block->AddSuccessor(exit_block); 52ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko exit_block->AddInstruction(new (GetAllocator()) HExit()); 53724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray 54ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HEnvironment* environment = new (GetAllocator()) HEnvironment( 55ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko GetAllocator(), 1, graph->GetArtMethod(), 0, null_check); 563dcd58cd54a922b864494fb7fff4a7f7a8562db9Nicolas Geoffray null_check->SetRawEnvironment(environment); 57724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray environment->SetRawEnvAt(0, parameter); 58724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray parameter->AddEnvUseAt(null_check->GetEnvironment(), 0); 59724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray 60724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray ASSERT_TRUE(parameter->HasEnvironmentUses()); 61724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray ASSERT_TRUE(parameter->HasUses()); 62724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray 63724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray first_block->RemoveInstruction(null_check); 64724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray 65724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray ASSERT_FALSE(parameter->HasEnvironmentUses()); 66724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray ASSERT_FALSE(parameter->HasUses()); 67724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray} 68724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray 69191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray/** 70191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray * Test that inserting an instruction in the graph updates user lists. 71191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray */ 72ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir MarkoTEST_F(NodeTest, InsertInstruction) { 73ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HGraph* graph = CreateGraph(); 74ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HBasicBlock* entry = new (GetAllocator()) HBasicBlock(graph); 75191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray graph->AddBlock(entry); 76191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray graph->SetEntryBlock(entry); 77ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HInstruction* parameter1 = new (GetAllocator()) HParameterValue( 780ebe0d83138bba1996e9c8007969b5381d972b32Vladimir Marko graph->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kReference); 79ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HInstruction* parameter2 = new (GetAllocator()) HParameterValue( 800ebe0d83138bba1996e9c8007969b5381d972b32Vladimir Marko graph->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kReference); 81191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray entry->AddInstruction(parameter1); 82191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray entry->AddInstruction(parameter2); 83ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko entry->AddInstruction(new (GetAllocator()) HExit()); 84191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray 85191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray ASSERT_FALSE(parameter1->HasUses()); 86191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray 87ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HInstruction* to_insert = new (GetAllocator()) HNullCheck(parameter1, 0); 88191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray entry->InsertInstructionBefore(to_insert, parameter2); 89191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray 90191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray ASSERT_TRUE(parameter1->HasUses()); 9146817b876ab00d6b78905b80ed12b4344c522b6cVladimir Marko ASSERT_TRUE(parameter1->GetUses().HasExactlyOneElement()); 92191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray} 93191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray 94191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray/** 95191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray * Test that adding an instruction in the graph updates user lists. 96191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray */ 97ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir MarkoTEST_F(NodeTest, AddInstruction) { 98ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HGraph* graph = CreateGraph(); 99ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HBasicBlock* entry = new (GetAllocator()) HBasicBlock(graph); 100191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray graph->AddBlock(entry); 101191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray graph->SetEntryBlock(entry); 102ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HInstruction* parameter = new (GetAllocator()) HParameterValue( 1030ebe0d83138bba1996e9c8007969b5381d972b32Vladimir Marko graph->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kReference); 104191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray entry->AddInstruction(parameter); 105191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray 106191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray ASSERT_FALSE(parameter->HasUses()); 107191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray 108ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HInstruction* to_add = new (GetAllocator()) HNullCheck(parameter, 0); 109191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray entry->AddInstruction(to_add); 110191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray 111191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray ASSERT_TRUE(parameter->HasUses()); 11246817b876ab00d6b78905b80ed12b4344c522b6cVladimir Marko ASSERT_TRUE(parameter->GetUses().HasExactlyOneElement()); 113191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray} 114191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray 115ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir MarkoTEST_F(NodeTest, ParentEnvironment) { 116ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HGraph* graph = CreateGraph(); 117ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HBasicBlock* entry = new (GetAllocator()) HBasicBlock(graph); 1180a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray graph->AddBlock(entry); 1190a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray graph->SetEntryBlock(entry); 120ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HInstruction* parameter1 = new (GetAllocator()) HParameterValue( 1210ebe0d83138bba1996e9c8007969b5381d972b32Vladimir Marko graph->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kReference); 122ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HInstruction* with_environment = new (GetAllocator()) HNullCheck(parameter1, 0); 1230a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray entry->AddInstruction(parameter1); 1240a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray entry->AddInstruction(with_environment); 125ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko entry->AddInstruction(new (GetAllocator()) HExit()); 1260a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray 1270a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray ASSERT_TRUE(parameter1->HasUses()); 12846817b876ab00d6b78905b80ed12b4344c522b6cVladimir Marko ASSERT_TRUE(parameter1->GetUses().HasExactlyOneElement()); 1290a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray 130ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HEnvironment* environment = new (GetAllocator()) HEnvironment( 131ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko GetAllocator(), 1, graph->GetArtMethod(), 0, with_environment); 13269d310e0317e2fce97bf8c9c133c5c2c0332e61dVladimir Marko HInstruction* const array[] = { parameter1 }; 1330a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray 13469d310e0317e2fce97bf8c9c133c5c2c0332e61dVladimir Marko environment->CopyFrom(ArrayRef<HInstruction* const>(array)); 1350a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray with_environment->SetRawEnvironment(environment); 1360a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray 1370a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray ASSERT_TRUE(parameter1->HasEnvironmentUses()); 13846817b876ab00d6b78905b80ed12b4344c522b6cVladimir Marko ASSERT_TRUE(parameter1->GetEnvUses().HasExactlyOneElement()); 1390a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray 140ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HEnvironment* parent1 = new (GetAllocator()) HEnvironment( 141ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko GetAllocator(), 1, graph->GetArtMethod(), 0, nullptr); 14269d310e0317e2fce97bf8c9c133c5c2c0332e61dVladimir Marko parent1->CopyFrom(ArrayRef<HInstruction* const>(array)); 1430a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray 1440a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray ASSERT_EQ(parameter1->GetEnvUses().SizeSlow(), 2u); 1450a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray 146ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko HEnvironment* parent2 = new (GetAllocator()) HEnvironment( 147ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko GetAllocator(), 1, graph->GetArtMethod(), 0, nullptr); 14869d310e0317e2fce97bf8c9c133c5c2c0332e61dVladimir Marko parent2->CopyFrom(ArrayRef<HInstruction* const>(array)); 149ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko parent1->SetAndCopyParentChain(GetAllocator(), parent2); 1500a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray 1510a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray // One use for parent2, and one other use for the new parent of parent1. 1520a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray ASSERT_EQ(parameter1->GetEnvUses().SizeSlow(), 4u); 1530a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray 1540a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray // We have copied the parent chain. So we now have two more uses. 155ca6fff898afcb62491458ae8bcd428bfb3043da1Vladimir Marko environment->SetAndCopyParentChain(GetAllocator(), parent1); 1560a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray ASSERT_EQ(parameter1->GetEnvUses().SizeSlow(), 6u); 1570a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray} 1580a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray 159724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray} // namespace art 160