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