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 17b666f4805c8ae707ea6fd7f6c7f375e0b000dba8Mathieu Chartier#include "base/arena_allocator.h" 18724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray#include "nodes.h" 190a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray#include "optimizing_unit_test.h" 20724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray 21724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray#include "gtest/gtest.h" 22724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray 23724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffraynamespace art { 24724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray 25724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray/** 26724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray * Test that removing instruction from the graph removes itself from user lists 27724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray * and environment lists. 28724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray */ 29724c96326dea6ec33287a0076279c136abb0208aNicolas GeoffrayTEST(Node, RemoveInstruction) { 30724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray ArenaPool pool; 31724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray ArenaAllocator allocator(&pool); 32724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray 330a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray HGraph* graph = CreateGraph(&allocator); 34724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray HBasicBlock* entry = new (&allocator) HBasicBlock(graph); 35724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray graph->AddBlock(entry); 36724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray graph->SetEntryBlock(entry); 37e6e3beaf2d35d18a79f5e7b60a21e75fac9fd15dCalin Juravle HInstruction* parameter = new (&allocator) HParameterValue( 38e6e3beaf2d35d18a79f5e7b60a21e75fac9fd15dCalin Juravle graph->GetDexFile(), 0, 0, Primitive::kPrimNot); 39724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray entry->AddInstruction(parameter); 40724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray entry->AddInstruction(new (&allocator) HGoto()); 41724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray 42724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray HBasicBlock* first_block = new (&allocator) HBasicBlock(graph); 43724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray graph->AddBlock(first_block); 44724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray entry->AddSuccessor(first_block); 45724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray HInstruction* null_check = new (&allocator) HNullCheck(parameter, 0); 46724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray first_block->AddInstruction(null_check); 47724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray first_block->AddInstruction(new (&allocator) HReturnVoid()); 48724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray 49724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray HBasicBlock* exit_block = new (&allocator) HBasicBlock(graph); 50724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray graph->AddBlock(exit_block); 51724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray first_block->AddSuccessor(exit_block); 52724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray exit_block->AddInstruction(new (&allocator) HExit()); 53724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray 540a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray HEnvironment* environment = new (&allocator) HEnvironment( 55d23eeef3492b53102eb8093524cf37e2b4c296dbNicolas Geoffray &allocator, 1, graph->GetDexFile(), graph->GetMethodIdx(), 0, kStatic, 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 */ 72191c4b1372aef7c0272f8fa3985b55513029e728Nicolas GeoffrayTEST(Node, InsertInstruction) { 73191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray ArenaPool pool; 74191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray ArenaAllocator allocator(&pool); 75191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray 760a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray HGraph* graph = CreateGraph(&allocator); 77191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray HBasicBlock* entry = new (&allocator) HBasicBlock(graph); 78191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray graph->AddBlock(entry); 79191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray graph->SetEntryBlock(entry); 80e6e3beaf2d35d18a79f5e7b60a21e75fac9fd15dCalin Juravle HInstruction* parameter1 = new (&allocator) HParameterValue( 81e6e3beaf2d35d18a79f5e7b60a21e75fac9fd15dCalin Juravle graph->GetDexFile(), 0, 0, Primitive::kPrimNot); 82e6e3beaf2d35d18a79f5e7b60a21e75fac9fd15dCalin Juravle HInstruction* parameter2 = new (&allocator) HParameterValue( 83e6e3beaf2d35d18a79f5e7b60a21e75fac9fd15dCalin Juravle graph->GetDexFile(), 0, 0, Primitive::kPrimNot); 84191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray entry->AddInstruction(parameter1); 85191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray entry->AddInstruction(parameter2); 86191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray entry->AddInstruction(new (&allocator) HExit()); 87191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray 88191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray ASSERT_FALSE(parameter1->HasUses()); 89191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray 90191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray HInstruction* to_insert = new (&allocator) HNullCheck(parameter1, 0); 91191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray entry->InsertInstructionBefore(to_insert, parameter2); 92191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray 93191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray ASSERT_TRUE(parameter1->HasUses()); 94d59f3b1b7f5c1ab9f0731ff9dc60611e8d9a6edeVladimir Marko ASSERT_TRUE(parameter1->GetUses().HasExactlyOneElement()); 95191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray} 96191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray 97191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray/** 98191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray * Test that adding an instruction in the graph updates user lists. 99191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray */ 100191c4b1372aef7c0272f8fa3985b55513029e728Nicolas GeoffrayTEST(Node, AddInstruction) { 101191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray ArenaPool pool; 102191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray ArenaAllocator allocator(&pool); 103191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray 1040a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray HGraph* graph = CreateGraph(&allocator); 105191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray HBasicBlock* entry = new (&allocator) HBasicBlock(graph); 106191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray graph->AddBlock(entry); 107191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray graph->SetEntryBlock(entry); 108e6e3beaf2d35d18a79f5e7b60a21e75fac9fd15dCalin Juravle HInstruction* parameter = new (&allocator) HParameterValue( 109e6e3beaf2d35d18a79f5e7b60a21e75fac9fd15dCalin Juravle graph->GetDexFile(), 0, 0, Primitive::kPrimNot); 110191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray entry->AddInstruction(parameter); 111191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray 112191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray ASSERT_FALSE(parameter->HasUses()); 113191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray 114191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray HInstruction* to_add = new (&allocator) HNullCheck(parameter, 0); 115191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray entry->AddInstruction(to_add); 116191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray 117191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray ASSERT_TRUE(parameter->HasUses()); 118d59f3b1b7f5c1ab9f0731ff9dc60611e8d9a6edeVladimir Marko ASSERT_TRUE(parameter->GetUses().HasExactlyOneElement()); 119191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray} 120191c4b1372aef7c0272f8fa3985b55513029e728Nicolas Geoffray 1210a23d74dc2751440822960eab218be4cb8843647Nicolas GeoffrayTEST(Node, ParentEnvironment) { 1220a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray ArenaPool pool; 1230a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray ArenaAllocator allocator(&pool); 1240a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray 1250a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray HGraph* graph = CreateGraph(&allocator); 1260a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray HBasicBlock* entry = new (&allocator) HBasicBlock(graph); 1270a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray graph->AddBlock(entry); 1280a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray graph->SetEntryBlock(entry); 129e6e3beaf2d35d18a79f5e7b60a21e75fac9fd15dCalin Juravle HInstruction* parameter1 = new (&allocator) HParameterValue( 130e6e3beaf2d35d18a79f5e7b60a21e75fac9fd15dCalin Juravle graph->GetDexFile(), 0, 0, Primitive::kPrimNot); 1310a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray HInstruction* with_environment = new (&allocator) HNullCheck(parameter1, 0); 1320a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray entry->AddInstruction(parameter1); 1330a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray entry->AddInstruction(with_environment); 1340a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray entry->AddInstruction(new (&allocator) HExit()); 1350a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray 1360a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray ASSERT_TRUE(parameter1->HasUses()); 137d59f3b1b7f5c1ab9f0731ff9dc60611e8d9a6edeVladimir Marko ASSERT_TRUE(parameter1->GetUses().HasExactlyOneElement()); 1380a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray 1390a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray HEnvironment* environment = new (&allocator) HEnvironment( 140d23eeef3492b53102eb8093524cf37e2b4c296dbNicolas Geoffray &allocator, 1, graph->GetDexFile(), graph->GetMethodIdx(), 0, kStatic, with_environment); 14171bf8090663d02869cafafdd530976f7f2a9db7fVladimir Marko ArenaVector<HInstruction*> array(allocator.Adapter()); 14271bf8090663d02869cafafdd530976f7f2a9db7fVladimir Marko array.push_back(parameter1); 1430a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray 1440a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray environment->CopyFrom(array); 1450a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray with_environment->SetRawEnvironment(environment); 1460a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray 1470a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray ASSERT_TRUE(parameter1->HasEnvironmentUses()); 148d59f3b1b7f5c1ab9f0731ff9dc60611e8d9a6edeVladimir Marko ASSERT_TRUE(parameter1->GetEnvUses().HasExactlyOneElement()); 1490a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray 1500a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray HEnvironment* parent1 = new (&allocator) HEnvironment( 151d23eeef3492b53102eb8093524cf37e2b4c296dbNicolas Geoffray &allocator, 1, graph->GetDexFile(), graph->GetMethodIdx(), 0, kStatic, nullptr); 1520a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray parent1->CopyFrom(array); 1530a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray 1540a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray ASSERT_EQ(parameter1->GetEnvUses().SizeSlow(), 2u); 1550a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray 1560a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray HEnvironment* parent2 = new (&allocator) HEnvironment( 157d23eeef3492b53102eb8093524cf37e2b4c296dbNicolas Geoffray &allocator, 1, graph->GetDexFile(), graph->GetMethodIdx(), 0, kStatic, nullptr); 1580a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray parent2->CopyFrom(array); 1590a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray parent1->SetAndCopyParentChain(&allocator, parent2); 1600a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray 1610a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray // One use for parent2, and one other use for the new parent of parent1. 1620a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray ASSERT_EQ(parameter1->GetEnvUses().SizeSlow(), 4u); 1630a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray 1640a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray // We have copied the parent chain. So we now have two more uses. 1650a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray environment->SetAndCopyParentChain(&allocator, parent1); 1660a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray ASSERT_EQ(parameter1->GetEnvUses().SizeSlow(), 6u); 1670a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray} 1680a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray 169724c96326dea6ec33287a0076279c136abb0208aNicolas Geoffray} // namespace art 170