blob: 1c0de37ca27d11a7a316bcddfe6f8d4178bd1263 [file] [log] [blame]
Vladimir Marko95a05972014-05-30 10:01:32 +01001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "compiler_internals.h"
18#include "dataflow_iterator.h"
19#include "dataflow_iterator-inl.h"
20#include "global_value_numbering.h"
21#include "local_value_numbering.h"
22#include "gtest/gtest.h"
23
24namespace art {
25
26class GlobalValueNumberingTest : public testing::Test {
27 protected:
28 struct IFieldDef {
29 uint16_t field_idx;
30 uintptr_t declaring_dex_file;
31 uint16_t declaring_field_idx;
32 bool is_volatile;
33 };
34
35 struct SFieldDef {
36 uint16_t field_idx;
37 uintptr_t declaring_dex_file;
38 uint16_t declaring_field_idx;
39 bool is_volatile;
40 };
41
42 struct BBDef {
43 static constexpr size_t kMaxSuccessors = 4;
44 static constexpr size_t kMaxPredecessors = 4;
45
46 BBType type;
47 size_t num_successors;
48 BasicBlockId successors[kMaxPredecessors];
49 size_t num_predecessors;
50 BasicBlockId predecessors[kMaxPredecessors];
51 };
52
53 struct MIRDef {
54 static constexpr size_t kMaxSsaDefs = 2;
55 static constexpr size_t kMaxSsaUses = 4;
56
57 BasicBlockId bbid;
58 Instruction::Code opcode;
59 int64_t value;
60 uint32_t field_info;
61 size_t num_uses;
62 int32_t uses[kMaxSsaUses];
63 size_t num_defs;
64 int32_t defs[kMaxSsaDefs];
65 };
66
67#define DEF_SUCC0() \
68 0u, { }
69#define DEF_SUCC1(s1) \
70 1u, { s1 }
71#define DEF_SUCC2(s1, s2) \
72 2u, { s1, s2 }
73#define DEF_SUCC3(s1, s2, s3) \
74 3u, { s1, s2, s3 }
75#define DEF_SUCC4(s1, s2, s3, s4) \
76 4u, { s1, s2, s3, s4 }
77#define DEF_PRED0() \
78 0u, { }
79#define DEF_PRED1(p1) \
80 1u, { p1 }
81#define DEF_PRED2(p1, p2) \
82 2u, { p1, p2 }
83#define DEF_PRED3(p1, p2, p3) \
84 3u, { p1, p2, p3 }
85#define DEF_PRED4(p1, p2, p3, p4) \
86 4u, { p1, p2, p3, p4 }
87#define DEF_BB(type, succ, pred) \
88 { type, succ, pred }
89
90#define DEF_CONST(bb, opcode, reg, value) \
91 { bb, opcode, value, 0u, 0, { }, 1, { reg } }
92#define DEF_CONST_WIDE(bb, opcode, reg, value) \
93 { bb, opcode, value, 0u, 0, { }, 2, { reg, reg + 1 } }
94#define DEF_CONST_STRING(bb, opcode, reg, index) \
95 { bb, opcode, index, 0u, 0, { }, 1, { reg } }
96#define DEF_IGET(bb, opcode, reg, obj, field_info) \
97 { bb, opcode, 0u, field_info, 1, { obj }, 1, { reg } }
98#define DEF_IGET_WIDE(bb, opcode, reg, obj, field_info) \
99 { bb, opcode, 0u, field_info, 1, { obj }, 2, { reg, reg + 1 } }
100#define DEF_IPUT(bb, opcode, reg, obj, field_info) \
101 { bb, opcode, 0u, field_info, 2, { reg, obj }, 0, { } }
102#define DEF_IPUT_WIDE(bb, opcode, reg, obj, field_info) \
103 { bb, opcode, 0u, field_info, 3, { reg, reg + 1, obj }, 0, { } }
104#define DEF_SGET(bb, opcode, reg, field_info) \
105 { bb, opcode, 0u, field_info, 0, { }, 1, { reg } }
106#define DEF_SGET_WIDE(bb, opcode, reg, field_info) \
107 { bb, opcode, 0u, field_info, 0, { }, 2, { reg, reg + 1 } }
108#define DEF_SPUT(bb, opcode, reg, field_info) \
109 { bb, opcode, 0u, field_info, 1, { reg }, 0, { } }
110#define DEF_SPUT_WIDE(bb, opcode, reg, field_info) \
111 { bb, opcode, 0u, field_info, 2, { reg, reg + 1 }, 0, { } }
112#define DEF_AGET(bb, opcode, reg, obj, idx) \
113 { bb, opcode, 0u, 0u, 2, { obj, idx }, 1, { reg } }
114#define DEF_AGET_WIDE(bb, opcode, reg, obj, idx) \
115 { bb, opcode, 0u, 0u, 2, { obj, idx }, 2, { reg, reg + 1 } }
116#define DEF_APUT(bb, opcode, reg, obj, idx) \
117 { bb, opcode, 0u, 0u, 3, { reg, obj, idx }, 0, { } }
118#define DEF_APUT_WIDE(bb, opcode, reg, obj, idx) \
119 { bb, opcode, 0u, 0u, 4, { reg, reg + 1, obj, idx }, 0, { } }
120#define DEF_INVOKE1(bb, opcode, reg) \
121 { bb, opcode, 0u, 0u, 1, { reg }, 0, { } }
122#define DEF_UNIQUE_REF(bb, opcode, reg) \
123 { bb, opcode, 0u, 0u, 0, { }, 1, { reg } } // CONST_CLASS, CONST_STRING, NEW_ARRAY, ...
124#define DEF_IFZ(bb, opcode, reg) \
125 { bb, opcode, 0u, 0u, 1, { reg }, 0, { } }
126#define DEF_MOVE(bb, opcode, reg, src) \
127 { bb, opcode, 0u, 0u, 1, { src }, 1, { reg } }
128#define DEF_PHI2(bb, reg, src1, src2) \
129 { bb, static_cast<Instruction::Code>(kMirOpPhi), 0, 0u, 2u, { src1, src2 }, 1, { reg } }
130
131 void DoPrepareIFields(const IFieldDef* defs, size_t count) {
132 cu_.mir_graph->ifield_lowering_infos_.Reset();
133 cu_.mir_graph->ifield_lowering_infos_.Resize(count);
134 for (size_t i = 0u; i != count; ++i) {
135 const IFieldDef* def = &defs[i];
136 MirIFieldLoweringInfo field_info(def->field_idx);
137 if (def->declaring_dex_file != 0u) {
138 field_info.declaring_dex_file_ = reinterpret_cast<const DexFile*>(def->declaring_dex_file);
139 field_info.declaring_field_idx_ = def->declaring_field_idx;
140 field_info.flags_ = 0u | // Without kFlagIsStatic.
141 (def->is_volatile ? MirIFieldLoweringInfo::kFlagIsVolatile : 0u);
142 }
143 cu_.mir_graph->ifield_lowering_infos_.Insert(field_info);
144 }
145 }
146
147 template <size_t count>
148 void PrepareIFields(const IFieldDef (&defs)[count]) {
149 DoPrepareIFields(defs, count);
150 }
151
152 void DoPrepareSFields(const SFieldDef* defs, size_t count) {
153 cu_.mir_graph->sfield_lowering_infos_.Reset();
154 cu_.mir_graph->sfield_lowering_infos_.Resize(count);
155 for (size_t i = 0u; i != count; ++i) {
156 const SFieldDef* def = &defs[i];
157 MirSFieldLoweringInfo field_info(def->field_idx);
158 // Mark even unresolved fields as initialized.
159 field_info.flags_ = MirSFieldLoweringInfo::kFlagIsStatic |
160 MirSFieldLoweringInfo::kFlagIsInitialized;
161 if (def->declaring_dex_file != 0u) {
162 field_info.declaring_dex_file_ = reinterpret_cast<const DexFile*>(def->declaring_dex_file);
163 field_info.declaring_field_idx_ = def->declaring_field_idx;
164 field_info.flags_ |= (def->is_volatile ? MirSFieldLoweringInfo::kFlagIsVolatile : 0u);
165 }
166 cu_.mir_graph->sfield_lowering_infos_.Insert(field_info);
167 }
168 }
169
170 template <size_t count>
171 void PrepareSFields(const SFieldDef (&defs)[count]) {
172 DoPrepareSFields(defs, count);
173 }
174
175 void DoPrepareBasicBlocks(const BBDef* defs, size_t count) {
176 cu_.mir_graph->block_id_map_.clear();
177 cu_.mir_graph->block_list_.Reset();
178 ASSERT_LT(3u, count); // null, entry, exit and at least one bytecode block.
179 ASSERT_EQ(kNullBlock, defs[0].type);
180 ASSERT_EQ(kEntryBlock, defs[1].type);
181 ASSERT_EQ(kExitBlock, defs[2].type);
182 for (size_t i = 0u; i != count; ++i) {
183 const BBDef* def = &defs[i];
184 BasicBlock* bb = cu_.mir_graph->NewMemBB(def->type, i);
185 cu_.mir_graph->block_list_.Insert(bb);
186 if (def->num_successors <= 2) {
187 bb->successor_block_list_type = kNotUsed;
188 bb->successor_blocks = nullptr;
189 bb->fall_through = (def->num_successors >= 1) ? def->successors[0] : 0u;
190 bb->taken = (def->num_successors >= 2) ? def->successors[1] : 0u;
191 } else {
192 bb->successor_block_list_type = kPackedSwitch;
193 bb->fall_through = 0u;
194 bb->taken = 0u;
195 bb->successor_blocks = new (&cu_.arena) GrowableArray<SuccessorBlockInfo*>(
196 &cu_.arena, def->num_successors, kGrowableArraySuccessorBlocks);
197 for (size_t j = 0u; j != def->num_successors; ++j) {
198 SuccessorBlockInfo* successor_block_info =
199 static_cast<SuccessorBlockInfo*>(cu_.arena.Alloc(sizeof(SuccessorBlockInfo),
200 kArenaAllocSuccessor));
201 successor_block_info->block = j;
202 successor_block_info->key = 0u; // Not used by class init check elimination.
203 bb->successor_blocks->Insert(successor_block_info);
204 }
205 }
206 bb->predecessors = new (&cu_.arena) GrowableArray<BasicBlockId>(
207 &cu_.arena, def->num_predecessors, kGrowableArrayPredecessors);
208 for (size_t j = 0u; j != def->num_predecessors; ++j) {
209 ASSERT_NE(0u, def->predecessors[j]);
210 bb->predecessors->Insert(def->predecessors[j]);
211 }
212 if (def->type == kDalvikByteCode || def->type == kEntryBlock || def->type == kExitBlock) {
213 bb->data_flow_info = static_cast<BasicBlockDataFlow*>(
214 cu_.arena.Alloc(sizeof(BasicBlockDataFlow), kArenaAllocDFInfo));
Vladimir Markob19955d2014-07-29 12:04:10 +0100215 bb->data_flow_info->live_in_v = live_in_v_;
Vladimir Marko95a05972014-05-30 10:01:32 +0100216 }
217 }
218 cu_.mir_graph->num_blocks_ = count;
219 ASSERT_EQ(count, cu_.mir_graph->block_list_.Size());
220 cu_.mir_graph->entry_block_ = cu_.mir_graph->block_list_.Get(1);
221 ASSERT_EQ(kEntryBlock, cu_.mir_graph->entry_block_->block_type);
222 cu_.mir_graph->exit_block_ = cu_.mir_graph->block_list_.Get(2);
223 ASSERT_EQ(kExitBlock, cu_.mir_graph->exit_block_->block_type);
224 }
225
226 template <size_t count>
227 void PrepareBasicBlocks(const BBDef (&defs)[count]) {
228 DoPrepareBasicBlocks(defs, count);
229 }
230
231 void DoPrepareMIRs(const MIRDef* defs, size_t count) {
232 mir_count_ = count;
233 mirs_ = reinterpret_cast<MIR*>(cu_.arena.Alloc(sizeof(MIR) * count, kArenaAllocMIR));
234 ssa_reps_.resize(count);
235 for (size_t i = 0u; i != count; ++i) {
236 const MIRDef* def = &defs[i];
237 MIR* mir = &mirs_[i];
238 ASSERT_LT(def->bbid, cu_.mir_graph->block_list_.Size());
239 BasicBlock* bb = cu_.mir_graph->block_list_.Get(def->bbid);
240 bb->AppendMIR(mir);
241 mir->dalvikInsn.opcode = def->opcode;
242 mir->dalvikInsn.vB = static_cast<int32_t>(def->value);
243 mir->dalvikInsn.vB_wide = def->value;
244 if (def->opcode >= Instruction::IGET && def->opcode <= Instruction::IPUT_SHORT) {
245 ASSERT_LT(def->field_info, cu_.mir_graph->ifield_lowering_infos_.Size());
246 mir->meta.ifield_lowering_info = def->field_info;
247 } else if (def->opcode >= Instruction::SGET && def->opcode <= Instruction::SPUT_SHORT) {
248 ASSERT_LT(def->field_info, cu_.mir_graph->sfield_lowering_infos_.Size());
249 mir->meta.sfield_lowering_info = def->field_info;
250 } else if (def->opcode == static_cast<Instruction::Code>(kMirOpPhi)) {
251 mir->meta.phi_incoming = static_cast<BasicBlockId*>(
252 allocator_->Alloc(def->num_uses * sizeof(BasicBlockId), kArenaAllocDFInfo));
253 for (size_t i = 0; i != def->num_uses; ++i) {
254 mir->meta.phi_incoming[i] = bb->predecessors->Get(i);
255 }
256 }
257 mir->ssa_rep = &ssa_reps_[i];
258 mir->ssa_rep->num_uses = def->num_uses;
259 mir->ssa_rep->uses = const_cast<int32_t*>(def->uses); // Not modified by LVN.
260 mir->ssa_rep->fp_use = nullptr; // Not used by LVN.
261 mir->ssa_rep->num_defs = def->num_defs;
262 mir->ssa_rep->defs = const_cast<int32_t*>(def->defs); // Not modified by LVN.
263 mir->ssa_rep->fp_def = nullptr; // Not used by LVN.
264 mir->dalvikInsn.opcode = def->opcode;
265 mir->offset = i; // LVN uses offset only for debug output
266 mir->optimization_flags = 0u;
267 }
268 mirs_[count - 1u].next = nullptr;
Razvan A Lupusoru8d0d03e2014-06-06 17:04:52 -0700269 DexFile::CodeItem* code_item = static_cast<DexFile::CodeItem*>(
270 cu_.arena.Alloc(sizeof(DexFile::CodeItem), kArenaAllocMisc));
271 code_item->insns_size_in_code_units_ = 2u * count;
272 cu_.mir_graph->current_code_item_ = cu_.code_item = code_item;
Vladimir Marko95a05972014-05-30 10:01:32 +0100273 }
274
275 template <size_t count>
276 void PrepareMIRs(const MIRDef (&defs)[count]) {
277 DoPrepareMIRs(defs, count);
278 }
279
280 void PerformGVN() {
Vladimir Marko55fff042014-07-10 12:42:52 +0100281 DoPerformGVN<LoopRepeatingTopologicalSortIterator>();
Vladimir Marko95a05972014-05-30 10:01:32 +0100282 }
283
284 void PerformPreOrderDfsGVN() {
Vladimir Marko95a05972014-05-30 10:01:32 +0100285 DoPerformGVN<RepeatingPreOrderDfsIterator>();
286 }
287
288 template <typename IteratorType>
289 void DoPerformGVN() {
Vladimir Marko55fff042014-07-10 12:42:52 +0100290 cu_.mir_graph->SSATransformationStart();
291 cu_.mir_graph->ComputeDFSOrders();
292 cu_.mir_graph->ComputeDominators();
293 cu_.mir_graph->ComputeTopologicalSortOrder();
294 cu_.mir_graph->SSATransformationEnd();
Vladimir Marko95a05972014-05-30 10:01:32 +0100295 ASSERT_TRUE(gvn_ == nullptr);
296 gvn_.reset(new (allocator_.get()) GlobalValueNumbering(&cu_, allocator_.get()));
297 ASSERT_FALSE(gvn_->CanModify());
298 value_names_.resize(mir_count_, 0xffffu);
299 IteratorType iterator(cu_.mir_graph.get());
300 bool change = false;
301 for (BasicBlock* bb = iterator.Next(change); bb != nullptr; bb = iterator.Next(change)) {
302 LocalValueNumbering* lvn = gvn_->PrepareBasicBlock(bb);
303 if (lvn != nullptr) {
304 for (MIR* mir = bb->first_mir_insn; mir != nullptr; mir = mir->next) {
305 value_names_[mir - mirs_] = lvn->GetValueNumber(mir);
306 }
307 }
308 change = (lvn != nullptr) && gvn_->FinishBasicBlock(bb);
309 ASSERT_TRUE(gvn_->Good());
310 }
311 }
312
313 void PerformGVNCodeModifications() {
314 ASSERT_TRUE(gvn_ != nullptr);
315 ASSERT_TRUE(gvn_->Good());
316 ASSERT_FALSE(gvn_->CanModify());
317 gvn_->AllowModifications();
Vladimir Marko55fff042014-07-10 12:42:52 +0100318 TopologicalSortIterator iterator(cu_.mir_graph.get());
Vladimir Marko95a05972014-05-30 10:01:32 +0100319 for (BasicBlock* bb = iterator.Next(); bb != nullptr; bb = iterator.Next()) {
320 LocalValueNumbering* lvn = gvn_->PrepareBasicBlock(bb);
321 if (lvn != nullptr) {
322 for (MIR* mir = bb->first_mir_insn; mir != nullptr; mir = mir->next) {
323 uint16_t value_name = lvn->GetValueNumber(mir);
324 ASSERT_EQ(value_name, value_names_[mir - mirs_]);
325 }
326 }
327 bool change = (lvn != nullptr) && gvn_->FinishBasicBlock(bb);
328 ASSERT_FALSE(change);
329 ASSERT_TRUE(gvn_->Good());
330 }
331 }
332
333 GlobalValueNumberingTest()
334 : pool_(),
335 cu_(&pool_),
336 mir_count_(0u),
337 mirs_(nullptr),
338 ssa_reps_(),
339 allocator_(),
340 gvn_(),
Vladimir Markob19955d2014-07-29 12:04:10 +0100341 value_names_(),
342 live_in_v_(new (&cu_.arena) ArenaBitVector(&cu_.arena, kMaxSsaRegs, false, kBitMapMisc)) {
Vladimir Marko95a05972014-05-30 10:01:32 +0100343 cu_.mir_graph.reset(new MIRGraph(&cu_, &cu_.arena));
344 cu_.access_flags = kAccStatic; // Don't let "this" interfere with this test.
345 allocator_.reset(ScopedArenaAllocator::Create(&cu_.arena_stack));
Vladimir Markob19955d2014-07-29 12:04:10 +0100346 // Bind all possible sregs to live vregs for test purposes.
347 live_in_v_->SetInitialBits(kMaxSsaRegs);
348 cu_.mir_graph->ssa_base_vregs_ = new (&cu_.arena) GrowableArray<int>(&cu_.arena, kMaxSsaRegs);
349 cu_.mir_graph->ssa_subscripts_ = new (&cu_.arena) GrowableArray<int>(&cu_.arena, kMaxSsaRegs);
350 for (unsigned int i = 0; i < kMaxSsaRegs; i++) {
351 cu_.mir_graph->ssa_base_vregs_->Insert(i);
352 cu_.mir_graph->ssa_subscripts_->Insert(0);
353 }
Vladimir Marko95a05972014-05-30 10:01:32 +0100354 }
355
Vladimir Markob19955d2014-07-29 12:04:10 +0100356 static constexpr size_t kMaxSsaRegs = 16384u;
357
Vladimir Marko95a05972014-05-30 10:01:32 +0100358 ArenaPool pool_;
359 CompilationUnit cu_;
360 size_t mir_count_;
361 MIR* mirs_;
362 std::vector<SSARepresentation> ssa_reps_;
363 std::unique_ptr<ScopedArenaAllocator> allocator_;
364 std::unique_ptr<GlobalValueNumbering> gvn_;
365 std::vector<uint16_t> value_names_;
Vladimir Markob19955d2014-07-29 12:04:10 +0100366 ArenaBitVector* live_in_v_;
Vladimir Marko95a05972014-05-30 10:01:32 +0100367};
368
369class GlobalValueNumberingTestDiamond : public GlobalValueNumberingTest {
370 public:
371 GlobalValueNumberingTestDiamond();
372
373 private:
374 static const BBDef kDiamondBbs[];
375};
376
377const GlobalValueNumberingTest::BBDef GlobalValueNumberingTestDiamond::kDiamondBbs[] = {
378 DEF_BB(kNullBlock, DEF_SUCC0(), DEF_PRED0()),
379 DEF_BB(kEntryBlock, DEF_SUCC1(3), DEF_PRED0()),
380 DEF_BB(kExitBlock, DEF_SUCC0(), DEF_PRED1(6)),
381 DEF_BB(kDalvikByteCode, DEF_SUCC2(4, 5), DEF_PRED1(1)), // Block #3, top of the diamond.
382 DEF_BB(kDalvikByteCode, DEF_SUCC1(6), DEF_PRED1(3)), // Block #4, left side.
383 DEF_BB(kDalvikByteCode, DEF_SUCC1(6), DEF_PRED1(3)), // Block #5, right side.
384 DEF_BB(kDalvikByteCode, DEF_SUCC1(2), DEF_PRED2(4, 5)), // Block #6, bottom.
385};
386
387GlobalValueNumberingTestDiamond::GlobalValueNumberingTestDiamond()
388 : GlobalValueNumberingTest() {
389 PrepareBasicBlocks(kDiamondBbs);
390}
391
392class GlobalValueNumberingTestLoop : public GlobalValueNumberingTest {
393 public:
394 GlobalValueNumberingTestLoop();
395
396 private:
397 static const BBDef kLoopBbs[];
398};
399
400const GlobalValueNumberingTest::BBDef GlobalValueNumberingTestLoop::kLoopBbs[] = {
401 DEF_BB(kNullBlock, DEF_SUCC0(), DEF_PRED0()),
402 DEF_BB(kEntryBlock, DEF_SUCC1(3), DEF_PRED0()),
403 DEF_BB(kExitBlock, DEF_SUCC0(), DEF_PRED1(5)),
404 DEF_BB(kDalvikByteCode, DEF_SUCC1(4), DEF_PRED1(1)),
405 DEF_BB(kDalvikByteCode, DEF_SUCC2(5, 4), DEF_PRED2(3, 4)), // "taken" loops to self.
406 DEF_BB(kDalvikByteCode, DEF_SUCC1(2), DEF_PRED1(4)),
407};
408
409GlobalValueNumberingTestLoop::GlobalValueNumberingTestLoop()
410 : GlobalValueNumberingTest() {
411 PrepareBasicBlocks(kLoopBbs);
412}
413
414class GlobalValueNumberingTestCatch : public GlobalValueNumberingTest {
415 public:
416 GlobalValueNumberingTestCatch();
417
418 private:
419 static const BBDef kCatchBbs[];
420};
421
422const GlobalValueNumberingTest::BBDef GlobalValueNumberingTestCatch::kCatchBbs[] = {
423 DEF_BB(kNullBlock, DEF_SUCC0(), DEF_PRED0()),
424 DEF_BB(kEntryBlock, DEF_SUCC1(3), DEF_PRED0()),
425 DEF_BB(kExitBlock, DEF_SUCC0(), DEF_PRED1(6)),
426 DEF_BB(kDalvikByteCode, DEF_SUCC1(4), DEF_PRED1(1)), // The top.
427 DEF_BB(kDalvikByteCode, DEF_SUCC1(6), DEF_PRED1(3)), // The throwing insn.
428 DEF_BB(kDalvikByteCode, DEF_SUCC1(6), DEF_PRED1(3)), // Catch handler.
429 DEF_BB(kDalvikByteCode, DEF_SUCC1(2), DEF_PRED2(4, 5)), // The merged block.
430};
431
432GlobalValueNumberingTestCatch::GlobalValueNumberingTestCatch()
433 : GlobalValueNumberingTest() {
434 PrepareBasicBlocks(kCatchBbs);
435 // Mark catch handler.
436 BasicBlock* catch_handler = cu_.mir_graph->GetBasicBlock(5u);
437 catch_handler->catch_entry = true;
438 // Add successor block info to the check block.
439 BasicBlock* check_bb = cu_.mir_graph->GetBasicBlock(3u);
440 check_bb->successor_block_list_type = kCatch;
441 check_bb->successor_blocks = new (&cu_.arena) GrowableArray<SuccessorBlockInfo*>(
442 &cu_.arena, 2, kGrowableArraySuccessorBlocks);
443 SuccessorBlockInfo* successor_block_info = reinterpret_cast<SuccessorBlockInfo*>
444 (cu_.arena.Alloc(sizeof(SuccessorBlockInfo), kArenaAllocSuccessor));
445 successor_block_info->block = catch_handler->id;
446 check_bb->successor_blocks->Insert(successor_block_info);
447}
448
449class GlobalValueNumberingTestTwoConsecutiveLoops : public GlobalValueNumberingTest {
450 public:
451 GlobalValueNumberingTestTwoConsecutiveLoops();
452
453 private:
454 static const BBDef kTwoConsecutiveLoopsBbs[];
455};
456
457const GlobalValueNumberingTest::BBDef
458GlobalValueNumberingTestTwoConsecutiveLoops::kTwoConsecutiveLoopsBbs[] = {
459 DEF_BB(kNullBlock, DEF_SUCC0(), DEF_PRED0()),
460 DEF_BB(kEntryBlock, DEF_SUCC1(3), DEF_PRED0()),
461 DEF_BB(kExitBlock, DEF_SUCC0(), DEF_PRED1(9)),
462 DEF_BB(kDalvikByteCode, DEF_SUCC1(4), DEF_PRED1(1)),
463 DEF_BB(kDalvikByteCode, DEF_SUCC2(5, 6), DEF_PRED2(3, 5)), // "taken" skips over the loop.
464 DEF_BB(kDalvikByteCode, DEF_SUCC1(4), DEF_PRED1(4)),
465 DEF_BB(kDalvikByteCode, DEF_SUCC1(7), DEF_PRED1(4)),
466 DEF_BB(kDalvikByteCode, DEF_SUCC2(8, 9), DEF_PRED2(6, 8)), // "taken" skips over the loop.
467 DEF_BB(kDalvikByteCode, DEF_SUCC1(7), DEF_PRED1(7)),
468 DEF_BB(kDalvikByteCode, DEF_SUCC1(2), DEF_PRED1(7)),
469};
470
471GlobalValueNumberingTestTwoConsecutiveLoops::GlobalValueNumberingTestTwoConsecutiveLoops()
472 : GlobalValueNumberingTest() {
473 PrepareBasicBlocks(kTwoConsecutiveLoopsBbs);
474}
475
476class GlobalValueNumberingTestTwoNestedLoops : public GlobalValueNumberingTest {
477 public:
478 GlobalValueNumberingTestTwoNestedLoops();
479
480 private:
481 static const BBDef kTwoNestedLoopsBbs[];
482};
483
484const GlobalValueNumberingTest::BBDef
485GlobalValueNumberingTestTwoNestedLoops::kTwoNestedLoopsBbs[] = {
486 DEF_BB(kNullBlock, DEF_SUCC0(), DEF_PRED0()),
487 DEF_BB(kEntryBlock, DEF_SUCC1(3), DEF_PRED0()),
488 DEF_BB(kExitBlock, DEF_SUCC0(), DEF_PRED1(8)),
489 DEF_BB(kDalvikByteCode, DEF_SUCC1(4), DEF_PRED1(1)),
490 DEF_BB(kDalvikByteCode, DEF_SUCC2(5, 8), DEF_PRED2(3, 7)), // "taken" skips over the loop.
491 DEF_BB(kDalvikByteCode, DEF_SUCC2(6, 7), DEF_PRED2(4, 6)), // "taken" skips over the loop.
492 DEF_BB(kDalvikByteCode, DEF_SUCC1(5), DEF_PRED1(5)),
493 DEF_BB(kDalvikByteCode, DEF_SUCC1(4), DEF_PRED1(5)),
494 DEF_BB(kDalvikByteCode, DEF_SUCC1(2), DEF_PRED1(4)),
495};
496
497GlobalValueNumberingTestTwoNestedLoops::GlobalValueNumberingTestTwoNestedLoops()
498 : GlobalValueNumberingTest() {
499 PrepareBasicBlocks(kTwoNestedLoopsBbs);
500}
501
502TEST_F(GlobalValueNumberingTestDiamond, NonAliasingIFields) {
503 static const IFieldDef ifields[] = {
504 { 0u, 1u, 0u, false }, // Int.
505 { 1u, 1u, 1u, false }, // Int.
506 { 2u, 1u, 2u, false }, // Int.
507 { 3u, 1u, 3u, false }, // Int.
508 { 4u, 1u, 4u, false }, // Short.
509 { 5u, 1u, 5u, false }, // Char.
510 { 6u, 0u, 0u, false }, // Unresolved, Short.
511 { 7u, 1u, 7u, false }, // Int.
512 { 8u, 0u, 0u, false }, // Unresolved, Int.
513 { 9u, 1u, 9u, false }, // Int.
514 { 10u, 1u, 10u, false }, // Int.
515 { 11u, 1u, 11u, false }, // Int.
516 };
517 static const MIRDef mirs[] = {
518 // NOTE: MIRs here are ordered by unique tests. They will be put into appropriate blocks.
519 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 100u),
520 DEF_IGET(3, Instruction::IGET, 1u, 100u, 0u),
521 DEF_IGET(6, Instruction::IGET, 2u, 100u, 0u), // Same as at the top.
522
523 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 200u),
524 DEF_IGET(4, Instruction::IGET, 4u, 200u, 1u),
525 DEF_IGET(6, Instruction::IGET, 5u, 200u, 1u), // Same as at the left side.
526
527 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 300u),
528 DEF_IGET(3, Instruction::IGET, 7u, 300u, 2u),
529 DEF_CONST(5, Instruction::CONST, 8u, 1000),
530 DEF_IPUT(5, Instruction::IPUT, 8u, 300u, 2u),
531 DEF_IGET(6, Instruction::IGET, 10u, 300u, 2u), // Differs from the top and the CONST.
532
533 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 400u),
534 DEF_IGET(3, Instruction::IGET, 12u, 400u, 3u),
535 DEF_CONST(3, Instruction::CONST, 13u, 2000),
536 DEF_IPUT(4, Instruction::IPUT, 13u, 400u, 3u),
537 DEF_IPUT(5, Instruction::IPUT, 13u, 400u, 3u),
538 DEF_IGET(6, Instruction::IGET, 16u, 400u, 3u), // Differs from the top, equals the CONST.
539
540 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 500u),
541 DEF_IGET(3, Instruction::IGET_SHORT, 18u, 500u, 4u),
542 DEF_IGET(3, Instruction::IGET_CHAR, 19u, 500u, 5u),
543 DEF_IPUT(4, Instruction::IPUT_SHORT, 20u, 500u, 6u), // Clobbers field #4, not #5.
544 DEF_IGET(6, Instruction::IGET_SHORT, 21u, 500u, 4u), // Differs from the top.
545 DEF_IGET(6, Instruction::IGET_CHAR, 22u, 500u, 5u), // Same as the top.
546
547 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 600u),
548 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 601u),
549 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 602u),
550 DEF_IGET(3, Instruction::IGET, 26u, 600u, 7u),
551 DEF_IGET(3, Instruction::IGET, 27u, 601u, 7u),
552 DEF_IPUT(4, Instruction::IPUT, 28u, 602u, 8u), // Doesn't clobber field #7 for other refs.
553 DEF_IGET(6, Instruction::IGET, 29u, 600u, 7u), // Same as the top.
554 DEF_IGET(6, Instruction::IGET, 30u, 601u, 7u), // Same as the top.
555
556 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 700u),
557 DEF_CONST(4, Instruction::CONST, 32u, 3000),
558 DEF_IPUT(4, Instruction::IPUT, 32u, 700u, 9u),
559 DEF_IPUT(4, Instruction::IPUT, 32u, 700u, 10u),
560 DEF_CONST(5, Instruction::CONST, 35u, 3001),
561 DEF_IPUT(5, Instruction::IPUT, 35u, 700u, 9u),
562 DEF_IPUT(5, Instruction::IPUT, 35u, 700u, 10u),
563 DEF_IGET(6, Instruction::IGET, 38u, 700u, 9u),
564 DEF_IGET(6, Instruction::IGET, 39u, 700u, 10u), // Same value as read from field #9.
565
566 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 800u),
567 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 801u),
568 DEF_CONST(4, Instruction::CONST, 42u, 3000),
569 DEF_IPUT(4, Instruction::IPUT, 42u, 800u, 11u),
570 DEF_IPUT(4, Instruction::IPUT, 42u, 801u, 11u),
571 DEF_CONST(5, Instruction::CONST, 45u, 3001),
572 DEF_IPUT(5, Instruction::IPUT, 45u, 800u, 11u),
573 DEF_IPUT(5, Instruction::IPUT, 45u, 801u, 11u),
574 DEF_IGET(6, Instruction::IGET, 48u, 800u, 11u),
575 DEF_IGET(6, Instruction::IGET, 49u, 801u, 11u), // Same value as read from ref 46u.
576
577 // Invoke doesn't interfere with non-aliasing refs. There's one test above where a reference
578 // escapes in the left BB (we let a reference escape if we use it to store to an unresolved
579 // field) and the INVOKE in the right BB shouldn't interfere with that either.
580 DEF_INVOKE1(5, Instruction::INVOKE_STATIC, 48u),
581 };
582
583 PrepareIFields(ifields);
584 PrepareMIRs(mirs);
585 PerformGVN();
586 ASSERT_EQ(arraysize(mirs), value_names_.size());
587 EXPECT_EQ(value_names_[1], value_names_[2]);
588
589 EXPECT_EQ(value_names_[4], value_names_[5]);
590
591 EXPECT_NE(value_names_[7], value_names_[10]);
592 EXPECT_NE(value_names_[8], value_names_[10]);
593
594 EXPECT_NE(value_names_[12], value_names_[16]);
595 EXPECT_EQ(value_names_[13], value_names_[16]);
596
597 EXPECT_NE(value_names_[18], value_names_[21]);
598 EXPECT_EQ(value_names_[19], value_names_[22]);
599
600 EXPECT_EQ(value_names_[26], value_names_[29]);
601 EXPECT_EQ(value_names_[27], value_names_[30]);
602
603 EXPECT_EQ(value_names_[38], value_names_[39]);
604
605 EXPECT_EQ(value_names_[48], value_names_[49]);
606}
607
608TEST_F(GlobalValueNumberingTestDiamond, AliasingIFieldsSingleObject) {
609 static const IFieldDef ifields[] = {
610 { 0u, 1u, 0u, false }, // Int.
611 { 1u, 1u, 1u, false }, // Int.
612 { 2u, 1u, 2u, false }, // Int.
613 { 3u, 1u, 3u, false }, // Int.
614 { 4u, 1u, 4u, false }, // Short.
615 { 5u, 1u, 5u, false }, // Char.
616 { 6u, 0u, 0u, false }, // Unresolved, Short.
617 { 7u, 1u, 7u, false }, // Int.
618 { 8u, 1u, 8u, false }, // Int.
619 };
620 static const MIRDef mirs[] = {
621 // NOTE: MIRs here are ordered by unique tests. They will be put into appropriate blocks.
622 DEF_IGET(3, Instruction::IGET, 0u, 100u, 0u),
623 DEF_IGET(6, Instruction::IGET, 1u, 100u, 0u), // Same as at the top.
624
625 DEF_IGET(4, Instruction::IGET, 2u, 100u, 1u),
626 DEF_IGET(6, Instruction::IGET, 3u, 100u, 1u), // Same as at the left side.
627
628 DEF_IGET(3, Instruction::IGET, 4u, 100u, 2u),
629 DEF_CONST(5, Instruction::CONST, 5u, 1000),
630 DEF_IPUT(5, Instruction::IPUT, 5u, 100u, 2u),
631 DEF_IGET(6, Instruction::IGET, 7u, 100u, 2u), // Differs from the top and the CONST.
632
633 DEF_IGET(3, Instruction::IGET, 8u, 100u, 3u),
634 DEF_CONST(3, Instruction::CONST, 9u, 2000),
635 DEF_IPUT(4, Instruction::IPUT, 9u, 100u, 3u),
636 DEF_IPUT(5, Instruction::IPUT, 9u, 100u, 3u),
637 DEF_IGET(6, Instruction::IGET, 12u, 100u, 3u), // Differs from the top, equals the CONST.
638
639 DEF_IGET(3, Instruction::IGET_SHORT, 13u, 100u, 4u),
640 DEF_IGET(3, Instruction::IGET_CHAR, 14u, 100u, 5u),
641 DEF_IPUT(4, Instruction::IPUT_SHORT, 15u, 100u, 6u), // Clobbers field #4, not #5.
642 DEF_IGET(6, Instruction::IGET_SHORT, 16u, 100u, 4u), // Differs from the top.
643 DEF_IGET(6, Instruction::IGET_CHAR, 17u, 100u, 5u), // Same as the top.
644
645 DEF_CONST(4, Instruction::CONST, 18u, 3000),
646 DEF_IPUT(4, Instruction::IPUT, 18u, 100u, 7u),
647 DEF_IPUT(4, Instruction::IPUT, 18u, 100u, 8u),
648 DEF_CONST(5, Instruction::CONST, 21u, 3001),
649 DEF_IPUT(5, Instruction::IPUT, 21u, 100u, 7u),
650 DEF_IPUT(5, Instruction::IPUT, 21u, 100u, 8u),
651 DEF_IGET(6, Instruction::IGET, 24u, 100u, 7u),
652 DEF_IGET(6, Instruction::IGET, 25u, 100u, 8u), // Same value as read from field #7.
653 };
654
655 PrepareIFields(ifields);
656 PrepareMIRs(mirs);
657 PerformGVN();
658 ASSERT_EQ(arraysize(mirs), value_names_.size());
659 EXPECT_EQ(value_names_[0], value_names_[1]);
660
661 EXPECT_EQ(value_names_[2], value_names_[3]);
662
663 EXPECT_NE(value_names_[4], value_names_[7]);
664 EXPECT_NE(value_names_[5], value_names_[7]);
665
666 EXPECT_NE(value_names_[8], value_names_[12]);
667 EXPECT_EQ(value_names_[9], value_names_[12]);
668
669 EXPECT_NE(value_names_[13], value_names_[16]);
670 EXPECT_EQ(value_names_[14], value_names_[17]);
671
672 EXPECT_EQ(value_names_[24], value_names_[25]);
673}
674
675TEST_F(GlobalValueNumberingTestDiamond, AliasingIFieldsTwoObjects) {
676 static const IFieldDef ifields[] = {
677 { 0u, 1u, 0u, false }, // Int.
678 { 1u, 1u, 1u, false }, // Int.
679 { 2u, 1u, 2u, false }, // Int.
680 { 3u, 1u, 3u, false }, // Int.
681 { 4u, 1u, 4u, false }, // Short.
682 { 5u, 1u, 5u, false }, // Char.
683 { 6u, 0u, 0u, false }, // Unresolved, Short.
684 { 7u, 1u, 7u, false }, // Int.
685 { 8u, 1u, 8u, false }, // Int.
686 };
687 static const MIRDef mirs[] = {
688 // NOTE: MIRs here are ordered by unique tests. They will be put into appropriate blocks.
689 DEF_IGET(3, Instruction::IGET, 0u, 100u, 0u),
690 DEF_IPUT(4, Instruction::IPUT, 1u, 101u, 0u), // May alias with the IGET at the top.
691 DEF_IGET(6, Instruction::IGET, 2u, 100u, 0u), // Differs from the top.
692
693 DEF_IGET(3, Instruction::IGET, 3u, 100u, 1u),
694 DEF_IPUT(5, Instruction::IPUT, 3u, 101u, 1u), // If aliasing, stores the same value.
695 DEF_IGET(6, Instruction::IGET, 5u, 100u, 1u), // Same as the top.
696
697 DEF_IGET(3, Instruction::IGET, 6u, 100u, 2u),
698 DEF_CONST(5, Instruction::CONST, 7u, 1000),
699 DEF_IPUT(5, Instruction::IPUT, 7u, 101u, 2u),
700 DEF_IGET(6, Instruction::IGET, 9u, 100u, 2u), // Differs from the top and the CONST.
701
702 DEF_IGET(3, Instruction::IGET, 10u, 100u, 3u),
703 DEF_CONST(3, Instruction::CONST, 11u, 2000),
704 DEF_IPUT(4, Instruction::IPUT, 11u, 101u, 3u),
705 DEF_IPUT(5, Instruction::IPUT, 11u, 101u, 3u),
706 DEF_IGET(6, Instruction::IGET, 14u, 100u, 3u), // Differs from the top and the CONST.
707
708 DEF_IGET(3, Instruction::IGET_SHORT, 15u, 100u, 4u),
709 DEF_IGET(3, Instruction::IGET_CHAR, 16u, 100u, 5u),
710 DEF_IPUT(4, Instruction::IPUT_SHORT, 17u, 101u, 6u), // Clobbers field #4, not #5.
711 DEF_IGET(6, Instruction::IGET_SHORT, 18u, 100u, 4u), // Differs from the top.
712 DEF_IGET(6, Instruction::IGET_CHAR, 19u, 100u, 5u), // Same as the top.
713
714 DEF_CONST(4, Instruction::CONST, 20u, 3000),
715 DEF_IPUT(4, Instruction::IPUT, 20u, 100u, 7u),
716 DEF_IPUT(4, Instruction::IPUT, 20u, 101u, 8u),
717 DEF_CONST(5, Instruction::CONST, 23u, 3001),
718 DEF_IPUT(5, Instruction::IPUT, 23u, 100u, 7u),
719 DEF_IPUT(5, Instruction::IPUT, 23u, 101u, 8u),
720 DEF_IGET(6, Instruction::IGET, 26u, 100u, 7u),
721 DEF_IGET(6, Instruction::IGET, 27u, 101u, 8u), // Same value as read from field #7.
722 };
723
724 PrepareIFields(ifields);
725 PrepareMIRs(mirs);
726 PerformGVN();
727 ASSERT_EQ(arraysize(mirs), value_names_.size());
728 EXPECT_NE(value_names_[0], value_names_[2]);
729
730 EXPECT_EQ(value_names_[3], value_names_[5]);
731
732 EXPECT_NE(value_names_[6], value_names_[9]);
733 EXPECT_NE(value_names_[7], value_names_[9]);
734
735 EXPECT_NE(value_names_[10], value_names_[14]);
736 EXPECT_NE(value_names_[10], value_names_[14]);
737
738 EXPECT_NE(value_names_[15], value_names_[18]);
739 EXPECT_EQ(value_names_[16], value_names_[19]);
740
741 EXPECT_EQ(value_names_[26], value_names_[27]);
742}
743
744TEST_F(GlobalValueNumberingTestDiamond, SFields) {
745 static const SFieldDef sfields[] = {
746 { 0u, 1u, 0u, false }, // Int.
747 { 1u, 1u, 1u, false }, // Int.
748 { 2u, 1u, 2u, false }, // Int.
749 { 3u, 1u, 3u, false }, // Int.
750 { 4u, 1u, 4u, false }, // Short.
751 { 5u, 1u, 5u, false }, // Char.
752 { 6u, 0u, 0u, false }, // Unresolved, Short.
753 { 7u, 1u, 7u, false }, // Int.
754 { 8u, 1u, 8u, false }, // Int.
755 };
756 static const MIRDef mirs[] = {
757 // NOTE: MIRs here are ordered by unique tests. They will be put into appropriate blocks.
758 DEF_SGET(3, Instruction::SGET, 0u, 0u),
759 DEF_SGET(6, Instruction::SGET, 1u, 0u), // Same as at the top.
760
761 DEF_SGET(4, Instruction::SGET, 2u, 1u),
762 DEF_SGET(6, Instruction::SGET, 3u, 1u), // Same as at the left side.
763
764 DEF_SGET(3, Instruction::SGET, 4u, 2u),
765 DEF_CONST(5, Instruction::CONST, 5u, 100),
766 DEF_SPUT(5, Instruction::SPUT, 5u, 2u),
767 DEF_SGET(6, Instruction::SGET, 7u, 2u), // Differs from the top and the CONST.
768
769 DEF_SGET(3, Instruction::SGET, 8u, 3u),
770 DEF_CONST(3, Instruction::CONST, 9u, 200),
771 DEF_SPUT(4, Instruction::SPUT, 9u, 3u),
772 DEF_SPUT(5, Instruction::SPUT, 9u, 3u),
773 DEF_SGET(6, Instruction::SGET, 12u, 3u), // Differs from the top, equals the CONST.
774
775 DEF_SGET(3, Instruction::SGET_SHORT, 13u, 4u),
776 DEF_SGET(3, Instruction::SGET_CHAR, 14u, 5u),
777 DEF_SPUT(4, Instruction::SPUT_SHORT, 15u, 6u), // Clobbers field #4, not #5.
778 DEF_SGET(6, Instruction::SGET_SHORT, 16u, 4u), // Differs from the top.
779 DEF_SGET(6, Instruction::SGET_CHAR, 17u, 5u), // Same as the top.
780
781 DEF_CONST(4, Instruction::CONST, 18u, 300),
782 DEF_SPUT(4, Instruction::SPUT, 18u, 7u),
783 DEF_SPUT(4, Instruction::SPUT, 18u, 8u),
784 DEF_CONST(5, Instruction::CONST, 21u, 301),
785 DEF_SPUT(5, Instruction::SPUT, 21u, 7u),
786 DEF_SPUT(5, Instruction::SPUT, 21u, 8u),
787 DEF_SGET(6, Instruction::SGET, 24u, 7u),
788 DEF_SGET(6, Instruction::SGET, 25u, 8u), // Same value as read from field #7.
789 };
790
791 PrepareSFields(sfields);
792 PrepareMIRs(mirs);
793 PerformGVN();
794 ASSERT_EQ(arraysize(mirs), value_names_.size());
795 EXPECT_EQ(value_names_[0], value_names_[1]);
796
797 EXPECT_EQ(value_names_[2], value_names_[3]);
798
799 EXPECT_NE(value_names_[4], value_names_[7]);
800 EXPECT_NE(value_names_[5], value_names_[7]);
801
802 EXPECT_NE(value_names_[8], value_names_[12]);
803 EXPECT_EQ(value_names_[9], value_names_[12]);
804
805 EXPECT_NE(value_names_[13], value_names_[16]);
806 EXPECT_EQ(value_names_[14], value_names_[17]);
807
808 EXPECT_EQ(value_names_[24], value_names_[25]);
809}
810
811TEST_F(GlobalValueNumberingTestDiamond, NonAliasingArrays) {
812 static const MIRDef mirs[] = {
813 // NOTE: MIRs here are ordered by unique tests. They will be put into appropriate blocks.
814 DEF_UNIQUE_REF(3, Instruction::NEW_ARRAY, 100u),
815 DEF_AGET(3, Instruction::AGET, 1u, 100u, 101u),
816 DEF_AGET(6, Instruction::AGET, 2u, 100u, 101u), // Same as at the top.
817
818 DEF_UNIQUE_REF(3, Instruction::NEW_ARRAY, 200u),
819 DEF_IGET(4, Instruction::AGET, 4u, 200u, 201u),
820 DEF_IGET(6, Instruction::AGET, 5u, 200u, 201u), // Same as at the left side.
821
822 DEF_UNIQUE_REF(3, Instruction::NEW_ARRAY, 300u),
823 DEF_AGET(3, Instruction::AGET, 7u, 300u, 301u),
824 DEF_CONST(5, Instruction::CONST, 8u, 1000),
825 DEF_APUT(5, Instruction::APUT, 8u, 300u, 301u),
826 DEF_AGET(6, Instruction::AGET, 10u, 300u, 301u), // Differs from the top and the CONST.
827
828 DEF_UNIQUE_REF(3, Instruction::NEW_ARRAY, 400u),
829 DEF_AGET(3, Instruction::AGET, 12u, 400u, 401u),
830 DEF_CONST(3, Instruction::CONST, 13u, 2000),
831 DEF_APUT(4, Instruction::APUT, 13u, 400u, 401u),
832 DEF_APUT(5, Instruction::APUT, 13u, 400u, 401u),
833 DEF_AGET(6, Instruction::AGET, 16u, 400u, 401u), // Differs from the top, equals the CONST.
834
835 DEF_UNIQUE_REF(3, Instruction::NEW_ARRAY, 500u),
836 DEF_AGET(3, Instruction::AGET, 18u, 500u, 501u),
837 DEF_APUT(4, Instruction::APUT, 19u, 500u, 502u), // Clobbers value at index 501u.
838 DEF_AGET(6, Instruction::AGET, 20u, 500u, 501u), // Differs from the top.
839
840 DEF_UNIQUE_REF(3, Instruction::NEW_ARRAY, 600u),
841 DEF_CONST(4, Instruction::CONST, 22u, 3000),
842 DEF_APUT(4, Instruction::APUT, 22u, 600u, 601u),
843 DEF_APUT(4, Instruction::APUT, 22u, 600u, 602u),
844 DEF_CONST(5, Instruction::CONST, 25u, 3001),
845 DEF_APUT(5, Instruction::APUT, 25u, 600u, 601u),
846 DEF_APUT(5, Instruction::APUT, 25u, 600u, 602u),
847 DEF_AGET(6, Instruction::AGET, 28u, 600u, 601u),
848 DEF_AGET(6, Instruction::AGET, 29u, 600u, 602u), // Same value as read from index 601u.
849
850 DEF_UNIQUE_REF(3, Instruction::NEW_ARRAY, 700u),
851 DEF_UNIQUE_REF(3, Instruction::NEW_ARRAY, 701u),
852 DEF_AGET(3, Instruction::AGET, 32u, 700u, 702u),
853 DEF_APUT(4, Instruction::APUT, 33u, 701u, 702u), // Doesn't interfere with unrelated array.
854 DEF_AGET(6, Instruction::AGET, 34u, 700u, 702u), // Same value as at the top.
855 };
856
857 PrepareMIRs(mirs);
858 PerformGVN();
859 ASSERT_EQ(arraysize(mirs), value_names_.size());
860 EXPECT_EQ(value_names_[1], value_names_[2]);
861
862 EXPECT_EQ(value_names_[4], value_names_[5]);
863
864 EXPECT_NE(value_names_[7], value_names_[10]);
865 EXPECT_NE(value_names_[8], value_names_[10]);
866
867 EXPECT_NE(value_names_[12], value_names_[16]);
868 EXPECT_EQ(value_names_[13], value_names_[16]);
869
870 EXPECT_NE(value_names_[18], value_names_[20]);
871
872 EXPECT_NE(value_names_[28], value_names_[22]);
873 EXPECT_NE(value_names_[28], value_names_[25]);
874 EXPECT_EQ(value_names_[28], value_names_[29]);
875
876 EXPECT_EQ(value_names_[32], value_names_[34]);
877}
878
879TEST_F(GlobalValueNumberingTestDiamond, AliasingArrays) {
880 static const MIRDef mirs[] = {
881 // NOTE: MIRs here are ordered by unique tests. They will be put into appropriate blocks.
882 // NOTE: We're also testing that these tests really do not interfere with each other.
883
884 DEF_AGET(3, Instruction::AGET_BOOLEAN, 0u, 100u, 101u),
885 DEF_AGET(6, Instruction::AGET_BOOLEAN, 1u, 100u, 101u), // Same as at the top.
886
887 DEF_IGET(4, Instruction::AGET_OBJECT, 2u, 200u, 201u),
888 DEF_IGET(6, Instruction::AGET_OBJECT, 3u, 200u, 201u), // Same as at the left side.
889
890 DEF_AGET(3, Instruction::AGET_WIDE, 4u, 300u, 301u),
891 DEF_CONST(5, Instruction::CONST_WIDE, 5u, 1000),
892 DEF_APUT(5, Instruction::APUT_WIDE, 5u, 300u, 301u),
893 DEF_AGET(6, Instruction::AGET_WIDE, 7u, 300u, 301u), // Differs from the top and the CONST.
894
895 DEF_AGET(3, Instruction::AGET_SHORT, 8u, 400u, 401u),
896 DEF_CONST(3, Instruction::CONST, 9u, 2000),
897 DEF_APUT(4, Instruction::APUT_SHORT, 9u, 400u, 401u),
898 DEF_APUT(5, Instruction::APUT_SHORT, 9u, 400u, 401u),
899 DEF_AGET(6, Instruction::AGET_SHORT, 12u, 400u, 401u), // Differs from the top, == CONST.
900
901 DEF_AGET(3, Instruction::AGET_CHAR, 13u, 500u, 501u),
902 DEF_APUT(4, Instruction::APUT_CHAR, 14u, 500u, 502u), // Clobbers value at index 501u.
903 DEF_AGET(6, Instruction::AGET_CHAR, 15u, 500u, 501u), // Differs from the top.
904
905 DEF_AGET(3, Instruction::AGET_BYTE, 16u, 600u, 602u),
906 DEF_APUT(4, Instruction::APUT_BYTE, 17u, 601u, 602u), // Clobbers values in array 600u.
907 DEF_AGET(6, Instruction::AGET_BYTE, 18u, 600u, 602u), // Differs from the top.
908
909 DEF_CONST(4, Instruction::CONST, 19u, 3000),
910 DEF_APUT(4, Instruction::APUT, 19u, 700u, 701u),
911 DEF_APUT(4, Instruction::APUT, 19u, 700u, 702u),
912 DEF_CONST(5, Instruction::CONST, 22u, 3001),
913 DEF_APUT(5, Instruction::APUT, 22u, 700u, 701u),
914 DEF_APUT(5, Instruction::APUT, 22u, 700u, 702u),
915 DEF_AGET(6, Instruction::AGET, 25u, 700u, 701u),
916 DEF_AGET(6, Instruction::AGET, 26u, 700u, 702u), // Same value as read from index 601u.
917 };
918
919 PrepareMIRs(mirs);
920 PerformGVN();
921 ASSERT_EQ(arraysize(mirs), value_names_.size());
922 EXPECT_EQ(value_names_[0], value_names_[1]);
923
924 EXPECT_EQ(value_names_[2], value_names_[3]);
925
926 EXPECT_NE(value_names_[4], value_names_[7]);
927 EXPECT_NE(value_names_[5], value_names_[7]);
928
929 EXPECT_NE(value_names_[8], value_names_[12]);
930 EXPECT_EQ(value_names_[9], value_names_[12]);
931
932 EXPECT_NE(value_names_[13], value_names_[15]);
933
934 EXPECT_NE(value_names_[16], value_names_[18]);
935
936 EXPECT_NE(value_names_[25], value_names_[19]);
937 EXPECT_NE(value_names_[25], value_names_[22]);
938 EXPECT_EQ(value_names_[25], value_names_[26]);
939}
940
941TEST_F(GlobalValueNumberingTestDiamond, Phi) {
942 static const MIRDef mirs[] = {
943 DEF_CONST(3, Instruction::CONST, 0u, 1000),
944 DEF_CONST(4, Instruction::CONST, 1u, 2000),
945 DEF_CONST(5, Instruction::CONST, 2u, 3000),
946 DEF_MOVE(4, Instruction::MOVE, 3u, 0u),
947 DEF_MOVE(4, Instruction::MOVE, 4u, 1u),
948 DEF_MOVE(5, Instruction::MOVE, 5u, 0u),
949 DEF_MOVE(5, Instruction::MOVE, 6u, 2u),
950 DEF_PHI2(6, 7u, 3u, 5u), // Same as CONST 0u (1000).
951 DEF_PHI2(6, 8u, 3u, 0u), // Same as CONST 0u (1000).
952 DEF_PHI2(6, 9u, 0u, 5u), // Same as CONST 0u (1000).
953 DEF_PHI2(6, 10u, 4u, 5u), // Merge 1u (2000) and 0u (1000).
954 DEF_PHI2(6, 11u, 1u, 5u), // Merge 1u (2000) and 0u (1000).
955 DEF_PHI2(6, 12u, 4u, 0u), // Merge 1u (2000) and 0u (1000).
956 DEF_PHI2(6, 13u, 1u, 0u), // Merge 1u (2000) and 0u (1000).
957 DEF_PHI2(6, 14u, 3u, 6u), // Merge 0u (1000) and 2u (3000).
958 DEF_PHI2(6, 15u, 0u, 6u), // Merge 0u (1000) and 2u (3000).
959 DEF_PHI2(6, 16u, 3u, 2u), // Merge 0u (1000) and 2u (3000).
960 DEF_PHI2(6, 17u, 0u, 2u), // Merge 0u (1000) and 2u (3000).
961 DEF_PHI2(6, 18u, 4u, 6u), // Merge 1u (2000) and 2u (3000).
962 DEF_PHI2(6, 19u, 1u, 6u), // Merge 1u (2000) and 2u (3000).
963 DEF_PHI2(6, 20u, 4u, 2u), // Merge 1u (2000) and 2u (3000).
964 DEF_PHI2(6, 21u, 1u, 2u), // Merge 1u (2000) and 2u (3000).
965 };
966
967 PrepareMIRs(mirs);
968 PerformGVN();
969 ASSERT_EQ(arraysize(mirs), value_names_.size());
970 EXPECT_EQ(value_names_[0], value_names_[7]);
971 EXPECT_EQ(value_names_[0], value_names_[8]);
972 EXPECT_EQ(value_names_[0], value_names_[9]);
973 EXPECT_NE(value_names_[10], value_names_[0]);
974 EXPECT_NE(value_names_[10], value_names_[1]);
975 EXPECT_NE(value_names_[10], value_names_[2]);
976 EXPECT_EQ(value_names_[10], value_names_[11]);
977 EXPECT_EQ(value_names_[10], value_names_[12]);
978 EXPECT_EQ(value_names_[10], value_names_[13]);
979 EXPECT_NE(value_names_[14], value_names_[0]);
980 EXPECT_NE(value_names_[14], value_names_[1]);
981 EXPECT_NE(value_names_[14], value_names_[2]);
982 EXPECT_NE(value_names_[14], value_names_[10]);
983 EXPECT_EQ(value_names_[14], value_names_[15]);
984 EXPECT_EQ(value_names_[14], value_names_[16]);
985 EXPECT_EQ(value_names_[14], value_names_[17]);
986 EXPECT_NE(value_names_[18], value_names_[0]);
987 EXPECT_NE(value_names_[18], value_names_[1]);
988 EXPECT_NE(value_names_[18], value_names_[2]);
989 EXPECT_NE(value_names_[18], value_names_[10]);
990 EXPECT_NE(value_names_[18], value_names_[14]);
991 EXPECT_EQ(value_names_[18], value_names_[19]);
992 EXPECT_EQ(value_names_[18], value_names_[20]);
993 EXPECT_EQ(value_names_[18], value_names_[21]);
994}
995
996TEST_F(GlobalValueNumberingTestLoop, NonAliasingIFields) {
997 static const IFieldDef ifields[] = {
998 { 0u, 1u, 0u, false }, // Int.
999 { 1u, 1u, 1u, false }, // Int.
1000 { 2u, 1u, 2u, false }, // Int.
1001 { 3u, 1u, 3u, false }, // Int.
1002 { 4u, 1u, 4u, false }, // Int.
1003 { 5u, 1u, 5u, false }, // Short.
1004 { 6u, 1u, 6u, false }, // Char.
1005 { 7u, 0u, 0u, false }, // Unresolved, Short.
1006 { 8u, 1u, 8u, false }, // Int.
1007 { 9u, 0u, 0u, false }, // Unresolved, Int.
1008 { 10u, 1u, 10u, false }, // Int.
1009 { 11u, 1u, 11u, false }, // Int.
1010 };
1011 static const MIRDef mirs[] = {
1012 // NOTE: MIRs here are ordered by unique tests. They will be put into appropriate blocks.
1013 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 100u),
1014 DEF_IGET(3, Instruction::IGET, 1u, 100u, 0u),
1015 DEF_IGET(4, Instruction::IGET, 2u, 100u, 0u), // Same as at the top.
1016 DEF_IGET(5, Instruction::IGET, 3u, 100u, 0u), // Same as at the top.
1017
1018 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 200u),
1019 DEF_IGET(3, Instruction::IGET, 5u, 200u, 1u),
1020 DEF_IGET(4, Instruction::IGET, 6u, 200u, 1u), // Differs from top...
1021 DEF_IPUT(4, Instruction::IPUT, 7u, 200u, 1u), // Because of this IPUT.
1022 DEF_IGET(5, Instruction::IGET, 8u, 200u, 1u), // Differs from top and the loop IGET.
1023
1024 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 300u),
1025 DEF_IGET(3, Instruction::IGET, 10u, 300u, 2u),
1026 DEF_IPUT(4, Instruction::IPUT, 11u, 300u, 2u), // Because of this IPUT...
1027 DEF_IGET(4, Instruction::IGET, 12u, 300u, 2u), // Differs from top.
1028 DEF_IGET(5, Instruction::IGET, 13u, 300u, 2u), // Differs from top but same as the loop IGET.
1029
1030 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 400u),
1031 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 401u),
1032 DEF_CONST(3, Instruction::CONST, 16u, 3000),
1033 DEF_IPUT(3, Instruction::IPUT, 16u, 400u, 3u),
1034 DEF_IPUT(3, Instruction::IPUT, 16u, 400u, 4u),
1035 DEF_IPUT(3, Instruction::IPUT, 16u, 401u, 3u),
1036 DEF_IGET(4, Instruction::IGET, 20u, 400u, 3u), // Differs from 16u and 23u.
1037 DEF_IGET(4, Instruction::IGET, 21u, 400u, 4u), // Same as 20u.
1038 DEF_IGET(4, Instruction::IGET, 22u, 401u, 3u), // Same as 20u.
1039 DEF_CONST(4, Instruction::CONST, 23u, 4000),
1040 DEF_IPUT(4, Instruction::IPUT, 23u, 400u, 3u),
1041 DEF_IPUT(4, Instruction::IPUT, 23u, 400u, 4u),
1042 DEF_IPUT(4, Instruction::IPUT, 23u, 401u, 3u),
1043 DEF_IGET(5, Instruction::IGET, 27u, 400u, 3u), // Differs from 16u and 20u...
1044 DEF_IGET(5, Instruction::IGET, 28u, 400u, 4u), // and same as the CONST 23u
1045 DEF_IGET(5, Instruction::IGET, 29u, 400u, 4u), // and same as the CONST 23u.
1046
1047 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 500u),
1048 DEF_IGET(3, Instruction::IGET_SHORT, 31u, 500u, 5u),
1049 DEF_IGET(3, Instruction::IGET_CHAR, 32u, 500u, 6u),
1050 DEF_IPUT(4, Instruction::IPUT_SHORT, 33u, 500u, 7u), // Clobbers field #5, not #6.
1051 DEF_IGET(5, Instruction::IGET_SHORT, 34u, 500u, 5u), // Differs from the top.
1052 DEF_IGET(5, Instruction::IGET_CHAR, 35u, 500u, 6u), // Same as the top.
1053
1054 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 600u),
1055 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 601u),
1056 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 602u),
1057 DEF_IGET(3, Instruction::IGET, 39u, 600u, 8u),
1058 DEF_IGET(3, Instruction::IGET, 40u, 601u, 8u),
1059 DEF_IPUT(4, Instruction::IPUT, 41u, 602u, 9u), // Doesn't clobber field #8 for other refs.
1060 DEF_IGET(5, Instruction::IGET, 42u, 600u, 8u), // Same as the top.
1061 DEF_IGET(5, Instruction::IGET, 43u, 601u, 8u), // Same as the top.
1062
1063 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 700u),
1064 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 701u),
1065 DEF_CONST(3, Instruction::CONST, 46u, 3000),
1066 DEF_IPUT(3, Instruction::IPUT, 46u, 700u, 10u),
1067 DEF_IPUT(3, Instruction::IPUT, 46u, 700u, 11u),
1068 DEF_IPUT(3, Instruction::IPUT, 46u, 701u, 10u),
1069 DEF_IGET(4, Instruction::IGET, 50u, 700u, 10u), // Differs from the CONSTs 46u and 53u.
1070 DEF_IGET(4, Instruction::IGET, 51u, 700u, 11u), // Same as 50u.
1071 DEF_IGET(4, Instruction::IGET, 52u, 701u, 10u), // Same as 50u.
1072 DEF_CONST(4, Instruction::CONST, 53u, 3001),
1073 DEF_IPUT(4, Instruction::IPUT, 53u, 700u, 10u),
1074 DEF_IPUT(4, Instruction::IPUT, 53u, 700u, 11u),
1075 DEF_IPUT(4, Instruction::IPUT, 53u, 701u, 10u),
1076 DEF_IGET(5, Instruction::IGET, 57u, 700u, 10u), // Same as the CONST 53u.
1077 DEF_IGET(5, Instruction::IGET, 58u, 700u, 11u), // Same as the CONST 53u.
1078 DEF_IGET(5, Instruction::IGET, 59u, 701u, 10u), // Same as the CONST 53u.
1079 };
1080
1081 PrepareIFields(ifields);
1082 PrepareMIRs(mirs);
1083 PerformGVN();
1084 ASSERT_EQ(arraysize(mirs), value_names_.size());
1085 EXPECT_EQ(value_names_[1], value_names_[2]);
1086 EXPECT_EQ(value_names_[1], value_names_[3]);
1087
1088 EXPECT_NE(value_names_[5], value_names_[6]);
1089 EXPECT_NE(value_names_[5], value_names_[7]);
1090 EXPECT_NE(value_names_[6], value_names_[7]);
1091
1092 EXPECT_NE(value_names_[10], value_names_[12]);
1093 EXPECT_EQ(value_names_[12], value_names_[13]);
1094
1095 EXPECT_NE(value_names_[20], value_names_[16]);
1096 EXPECT_NE(value_names_[20], value_names_[23]);
1097 EXPECT_EQ(value_names_[20], value_names_[21]);
1098 EXPECT_EQ(value_names_[20], value_names_[22]);
1099 EXPECT_NE(value_names_[27], value_names_[16]);
1100 EXPECT_NE(value_names_[27], value_names_[20]);
1101 EXPECT_EQ(value_names_[27], value_names_[28]);
1102 EXPECT_EQ(value_names_[27], value_names_[29]);
1103
1104 EXPECT_NE(value_names_[31], value_names_[34]);
1105 EXPECT_EQ(value_names_[32], value_names_[35]);
1106
1107 EXPECT_EQ(value_names_[39], value_names_[42]);
1108 EXPECT_EQ(value_names_[40], value_names_[43]);
1109
1110 EXPECT_NE(value_names_[50], value_names_[46]);
1111 EXPECT_NE(value_names_[50], value_names_[53]);
1112 EXPECT_EQ(value_names_[50], value_names_[51]);
1113 EXPECT_EQ(value_names_[50], value_names_[52]);
1114 EXPECT_EQ(value_names_[57], value_names_[53]);
1115 EXPECT_EQ(value_names_[58], value_names_[53]);
1116 EXPECT_EQ(value_names_[59], value_names_[53]);
1117}
1118
1119TEST_F(GlobalValueNumberingTestLoop, AliasingIFieldsSingleObject) {
1120 static const IFieldDef ifields[] = {
1121 { 0u, 1u, 0u, false }, // Int.
1122 { 1u, 1u, 1u, false }, // Int.
1123 { 2u, 1u, 2u, false }, // Int.
1124 { 3u, 1u, 3u, false }, // Int.
1125 { 4u, 1u, 4u, false }, // Int.
1126 { 5u, 1u, 5u, false }, // Short.
1127 { 6u, 1u, 6u, false }, // Char.
1128 { 7u, 0u, 0u, false }, // Unresolved, Short.
1129 };
1130 static const MIRDef mirs[] = {
1131 // NOTE: MIRs here are ordered by unique tests. They will be put into appropriate blocks.
1132 DEF_IGET(3, Instruction::IGET, 0u, 100u, 0u),
1133 DEF_IGET(4, Instruction::IGET, 1u, 100u, 0u), // Same as at the top.
1134 DEF_IGET(5, Instruction::IGET, 2u, 100u, 0u), // Same as at the top.
1135
1136 DEF_IGET(3, Instruction::IGET, 3u, 100u, 1u),
1137 DEF_IGET(4, Instruction::IGET, 4u, 100u, 1u), // Differs from top...
1138 DEF_IPUT(4, Instruction::IPUT, 5u, 100u, 1u), // Because of this IPUT.
1139 DEF_IGET(5, Instruction::IGET, 6u, 100u, 1u), // Differs from top and the loop IGET.
1140
1141 DEF_IGET(3, Instruction::IGET, 7u, 100u, 2u),
1142 DEF_IPUT(4, Instruction::IPUT, 8u, 100u, 2u), // Because of this IPUT...
1143 DEF_IGET(4, Instruction::IGET, 9u, 100u, 2u), // Differs from top.
1144 DEF_IGET(5, Instruction::IGET, 10u, 100u, 2u), // Differs from top but same as the loop IGET.
1145
1146 DEF_CONST(3, Instruction::CONST, 11u, 3000),
1147 DEF_IPUT(3, Instruction::IPUT, 11u, 100u, 3u),
1148 DEF_IPUT(3, Instruction::IPUT, 11u, 100u, 4u),
1149 DEF_IGET(4, Instruction::IGET, 14u, 100u, 3u), // Differs from 11u and 16u.
1150 DEF_IGET(4, Instruction::IGET, 15u, 100u, 4u), // Same as 14u.
1151 DEF_CONST(4, Instruction::CONST, 16u, 4000),
1152 DEF_IPUT(4, Instruction::IPUT, 16u, 100u, 3u),
1153 DEF_IPUT(4, Instruction::IPUT, 16u, 100u, 4u),
1154 DEF_IGET(5, Instruction::IGET, 19u, 100u, 3u), // Differs from 11u and 14u...
1155 DEF_IGET(5, Instruction::IGET, 20u, 100u, 4u), // and same as the CONST 16u.
1156
1157 DEF_IGET(3, Instruction::IGET_SHORT, 21u, 100u, 5u),
1158 DEF_IGET(3, Instruction::IGET_CHAR, 22u, 100u, 6u),
1159 DEF_IPUT(4, Instruction::IPUT_SHORT, 23u, 100u, 7u), // Clobbers field #5, not #6.
1160 DEF_IGET(5, Instruction::IGET_SHORT, 24u, 100u, 5u), // Differs from the top.
1161 DEF_IGET(5, Instruction::IGET_CHAR, 25u, 100u, 6u), // Same as the top.
1162 };
1163
1164 PrepareIFields(ifields);
1165 PrepareMIRs(mirs);
1166 PerformGVN();
1167 ASSERT_EQ(arraysize(mirs), value_names_.size());
1168 EXPECT_EQ(value_names_[0], value_names_[1]);
1169 EXPECT_EQ(value_names_[0], value_names_[2]);
1170
1171 EXPECT_NE(value_names_[3], value_names_[4]);
1172 EXPECT_NE(value_names_[3], value_names_[6]);
1173 EXPECT_NE(value_names_[4], value_names_[6]);
1174
1175 EXPECT_NE(value_names_[7], value_names_[9]);
1176 EXPECT_EQ(value_names_[9], value_names_[10]);
1177
1178 EXPECT_NE(value_names_[14], value_names_[11]);
1179 EXPECT_NE(value_names_[14], value_names_[16]);
1180 EXPECT_EQ(value_names_[14], value_names_[15]);
1181 EXPECT_NE(value_names_[19], value_names_[11]);
1182 EXPECT_NE(value_names_[19], value_names_[14]);
1183 EXPECT_EQ(value_names_[19], value_names_[16]);
1184 EXPECT_EQ(value_names_[19], value_names_[20]);
1185
1186 EXPECT_NE(value_names_[21], value_names_[24]);
1187 EXPECT_EQ(value_names_[22], value_names_[25]);
1188}
1189
1190TEST_F(GlobalValueNumberingTestLoop, AliasingIFieldsTwoObjects) {
1191 static const IFieldDef ifields[] = {
1192 { 0u, 1u, 0u, false }, // Int.
1193 { 1u, 1u, 1u, false }, // Int.
1194 { 2u, 1u, 2u, false }, // Int.
1195 { 3u, 1u, 3u, false }, // Short.
1196 { 4u, 1u, 4u, false }, // Char.
1197 { 5u, 0u, 0u, false }, // Unresolved, Short.
1198 { 6u, 1u, 6u, false }, // Int.
1199 { 7u, 1u, 7u, false }, // Int.
1200 };
1201 static const MIRDef mirs[] = {
1202 // NOTE: MIRs here are ordered by unique tests. They will be put into appropriate blocks.
1203 DEF_IGET(3, Instruction::IGET, 0u, 100u, 0u),
1204 DEF_IPUT(4, Instruction::IPUT, 1u, 101u, 0u), // May alias with the IGET at the top.
1205 DEF_IGET(5, Instruction::IGET, 2u, 100u, 0u), // Differs from the top.
1206
1207 DEF_IGET(3, Instruction::IGET, 3u, 100u, 1u),
1208 DEF_IPUT(4, Instruction::IPUT, 3u, 101u, 1u), // If aliasing, stores the same value.
1209 DEF_IGET(5, Instruction::IGET, 5u, 100u, 1u), // Same as the top.
1210
1211 DEF_IGET(3, Instruction::IGET, 6u, 100u, 2u),
1212 DEF_CONST(4, Instruction::CONST, 7u, 1000),
1213 DEF_IPUT(4, Instruction::IPUT, 7u, 101u, 2u),
1214 DEF_IGET(5, Instruction::IGET, 9u, 100u, 2u), // Differs from the top and the CONST.
1215
1216 DEF_IGET(3, Instruction::IGET_SHORT, 10u, 100u, 3u),
1217 DEF_IGET(3, Instruction::IGET_CHAR, 11u, 100u, 4u),
1218 DEF_IPUT(4, Instruction::IPUT_SHORT, 12u, 101u, 5u), // Clobbers field #3, not #4.
1219 DEF_IGET(5, Instruction::IGET_SHORT, 13u, 100u, 3u), // Differs from the top.
1220 DEF_IGET(5, Instruction::IGET_CHAR, 14u, 100u, 4u), // Same as the top.
1221
1222 DEF_CONST(3, Instruction::CONST, 15u, 3000),
1223 DEF_IPUT(3, Instruction::IPUT, 15u, 100u, 6u),
1224 DEF_IPUT(3, Instruction::IPUT, 15u, 100u, 7u),
1225 DEF_IPUT(3, Instruction::IPUT, 15u, 101u, 6u),
1226 DEF_IGET(4, Instruction::IGET, 19u, 100u, 6u), // Differs from CONSTs 15u and 22u.
1227 DEF_IGET(4, Instruction::IGET, 20u, 100u, 7u), // Same value as 19u.
1228 DEF_IGET(4, Instruction::IGET, 21u, 101u, 6u), // Same value as read from field #7.
1229 DEF_CONST(4, Instruction::CONST, 22u, 3001),
1230 DEF_IPUT(4, Instruction::IPUT, 22u, 100u, 6u),
1231 DEF_IPUT(4, Instruction::IPUT, 22u, 100u, 7u),
1232 DEF_IPUT(4, Instruction::IPUT, 22u, 101u, 6u),
1233 DEF_IGET(5, Instruction::IGET, 26u, 100u, 6u), // Same as CONST 22u.
1234 DEF_IGET(5, Instruction::IGET, 27u, 100u, 7u), // Same as CONST 22u.
1235 DEF_IGET(5, Instruction::IGET, 28u, 101u, 6u), // Same as CONST 22u.
1236 };
1237
1238 PrepareIFields(ifields);
1239 PrepareMIRs(mirs);
1240 PerformGVN();
1241 ASSERT_EQ(arraysize(mirs), value_names_.size());
1242 EXPECT_NE(value_names_[0], value_names_[2]);
1243
1244 EXPECT_EQ(value_names_[3], value_names_[5]);
1245
1246 EXPECT_NE(value_names_[6], value_names_[9]);
1247 EXPECT_NE(value_names_[7], value_names_[9]);
1248
1249 EXPECT_NE(value_names_[10], value_names_[13]);
1250 EXPECT_EQ(value_names_[11], value_names_[14]);
1251
1252 EXPECT_NE(value_names_[19], value_names_[15]);
1253 EXPECT_NE(value_names_[19], value_names_[22]);
1254 EXPECT_EQ(value_names_[22], value_names_[26]);
1255 EXPECT_EQ(value_names_[22], value_names_[27]);
1256 EXPECT_EQ(value_names_[22], value_names_[28]);
1257}
1258
1259TEST_F(GlobalValueNumberingTestLoop, IFieldToBaseDependency) {
1260 static const IFieldDef ifields[] = {
1261 { 0u, 1u, 0u, false }, // Int.
1262 };
1263 static const MIRDef mirs[] = {
1264 // For the IGET that loads sreg 3u using base 2u, the following IPUT creates a dependency
1265 // from the field value to the base. However, this dependency does not result in an
1266 // infinite loop since the merge of the field value for base 0u gets assigned a value name
1267 // based only on the base 0u, not on the actual value, and breaks the dependency cycle.
1268 DEF_IGET(3, Instruction::IGET, 0u, 100u, 0u),
1269 DEF_IGET(3, Instruction::IGET, 1u, 0u, 0u),
1270 DEF_IGET(4, Instruction::IGET, 2u, 0u, 0u),
1271 DEF_IGET(4, Instruction::IGET, 3u, 2u, 0u),
1272 DEF_IPUT(4, Instruction::IPUT, 3u, 0u, 0u),
1273 DEF_IGET(5, Instruction::IGET, 5u, 0u, 0u),
1274 };
1275
1276 PrepareIFields(ifields);
1277 PrepareMIRs(mirs);
1278 PerformGVN();
1279 ASSERT_EQ(arraysize(mirs), value_names_.size());
1280 EXPECT_NE(value_names_[1], value_names_[2]);
1281 EXPECT_EQ(value_names_[3], value_names_[5]);
1282}
1283
1284TEST_F(GlobalValueNumberingTestLoop, SFields) {
1285 static const SFieldDef sfields[] = {
1286 { 0u, 1u, 0u, false }, // Int.
1287 { 1u, 1u, 1u, false }, // Int.
1288 { 2u, 1u, 2u, false }, // Int.
1289 };
1290 static const MIRDef mirs[] = {
1291 // NOTE: MIRs here are ordered by unique tests. They will be put into appropriate blocks.
1292 DEF_SGET(3, Instruction::SGET, 0u, 0u),
1293 DEF_SGET(4, Instruction::SGET, 1u, 0u), // Same as at the top.
1294 DEF_SGET(5, Instruction::SGET, 2u, 0u), // Same as at the top.
1295
1296 DEF_SGET(3, Instruction::SGET, 3u, 1u),
1297 DEF_SGET(4, Instruction::SGET, 4u, 1u), // Differs from top...
1298 DEF_SPUT(4, Instruction::SPUT, 5u, 1u), // Because of this SPUT.
1299 DEF_SGET(5, Instruction::SGET, 6u, 1u), // Differs from top and the loop SGET.
1300
1301 DEF_SGET(3, Instruction::SGET, 7u, 2u),
1302 DEF_SPUT(4, Instruction::SPUT, 8u, 2u), // Because of this SPUT...
1303 DEF_SGET(4, Instruction::SGET, 9u, 2u), // Differs from top.
1304 DEF_SGET(5, Instruction::SGET, 10u, 2u), // Differs from top but same as the loop SGET.
1305 };
1306
1307 PrepareSFields(sfields);
1308 PrepareMIRs(mirs);
1309 PerformGVN();
1310 ASSERT_EQ(arraysize(mirs), value_names_.size());
1311 EXPECT_EQ(value_names_[0], value_names_[1]);
1312 EXPECT_EQ(value_names_[0], value_names_[2]);
1313
1314 EXPECT_NE(value_names_[3], value_names_[4]);
1315 EXPECT_NE(value_names_[3], value_names_[6]);
1316 EXPECT_NE(value_names_[4], value_names_[5]);
1317
1318 EXPECT_NE(value_names_[7], value_names_[9]);
1319 EXPECT_EQ(value_names_[9], value_names_[10]);
1320}
1321
1322TEST_F(GlobalValueNumberingTestLoop, NonAliasingArrays) {
1323 static const MIRDef mirs[] = {
1324 // NOTE: MIRs here are ordered by unique tests. They will be put into appropriate blocks.
1325 DEF_UNIQUE_REF(3, Instruction::NEW_ARRAY, 100u),
1326 DEF_AGET(3, Instruction::AGET, 1u, 100u, 101u),
1327 DEF_AGET(4, Instruction::AGET, 2u, 100u, 101u), // Same as at the top.
1328 DEF_AGET(5, Instruction::AGET, 3u, 100u, 101u), // Same as at the top.
1329
1330 DEF_UNIQUE_REF(3, Instruction::NEW_ARRAY, 200u),
1331 DEF_AGET(3, Instruction::AGET, 5u, 200u, 201u),
1332 DEF_AGET(4, Instruction::AGET, 6u, 200u, 201u), // Differs from top...
1333 DEF_APUT(4, Instruction::APUT, 7u, 200u, 201u), // Because of this IPUT.
1334 DEF_AGET(5, Instruction::AGET, 8u, 200u, 201u), // Differs from top and the loop AGET.
1335
1336 DEF_UNIQUE_REF(3, Instruction::NEW_ARRAY, 300u),
1337 DEF_AGET(3, Instruction::AGET, 10u, 300u, 301u),
1338 DEF_APUT(4, Instruction::APUT, 11u, 300u, 301u), // Because of this IPUT...
1339 DEF_AGET(4, Instruction::AGET, 12u, 300u, 301u), // Differs from top.
1340 DEF_AGET(5, Instruction::AGET, 13u, 300u, 301u), // Differs from top but == the loop AGET.
1341
1342 DEF_UNIQUE_REF(3, Instruction::NEW_ARRAY, 400u),
1343 DEF_CONST(3, Instruction::CONST, 15u, 3000),
1344 DEF_APUT(3, Instruction::APUT, 15u, 400u, 401u),
1345 DEF_APUT(3, Instruction::APUT, 15u, 400u, 402u),
1346 DEF_AGET(4, Instruction::AGET, 18u, 400u, 401u), // Differs from 15u and 20u.
1347 DEF_AGET(4, Instruction::AGET, 19u, 400u, 402u), // Same as 18u.
1348 DEF_CONST(4, Instruction::CONST, 20u, 4000),
1349 DEF_APUT(4, Instruction::APUT, 20u, 400u, 401u),
1350 DEF_APUT(4, Instruction::APUT, 20u, 400u, 402u),
1351 DEF_AGET(5, Instruction::AGET, 23u, 400u, 401u), // Differs from 15u and 18u...
1352 DEF_AGET(5, Instruction::AGET, 24u, 400u, 402u), // and same as the CONST 20u.
1353
1354 DEF_UNIQUE_REF(3, Instruction::NEW_ARRAY, 500u),
1355 DEF_AGET(3, Instruction::AGET, 26u, 500u, 501u),
1356 DEF_APUT(4, Instruction::APUT, 27u, 500u, 502u), // Clobbers element at index 501u.
1357 DEF_AGET(5, Instruction::AGET, 28u, 500u, 501u), // Differs from the top.
1358 };
1359
1360 PrepareMIRs(mirs);
1361 PerformGVN();
1362 ASSERT_EQ(arraysize(mirs), value_names_.size());
1363 EXPECT_EQ(value_names_[1], value_names_[2]);
1364 EXPECT_EQ(value_names_[1], value_names_[3]);
1365
1366 EXPECT_NE(value_names_[5], value_names_[6]);
1367 EXPECT_NE(value_names_[5], value_names_[8]);
1368 EXPECT_NE(value_names_[6], value_names_[8]);
1369
1370 EXPECT_NE(value_names_[10], value_names_[12]);
1371 EXPECT_EQ(value_names_[12], value_names_[13]);
1372
1373 EXPECT_NE(value_names_[18], value_names_[15]);
1374 EXPECT_NE(value_names_[18], value_names_[20]);
1375 EXPECT_EQ(value_names_[18], value_names_[19]);
1376 EXPECT_NE(value_names_[23], value_names_[15]);
1377 EXPECT_NE(value_names_[23], value_names_[18]);
1378 EXPECT_EQ(value_names_[23], value_names_[20]);
1379 EXPECT_EQ(value_names_[23], value_names_[24]);
1380
1381 EXPECT_NE(value_names_[26], value_names_[28]);
1382}
1383
1384TEST_F(GlobalValueNumberingTestLoop, AliasingArrays) {
1385 static const MIRDef mirs[] = {
1386 // NOTE: MIRs here are ordered by unique tests. They will be put into appropriate blocks.
1387 DEF_AGET(3, Instruction::AGET_WIDE, 0u, 100u, 101u),
1388 DEF_AGET(4, Instruction::AGET_WIDE, 1u, 100u, 101u), // Same as at the top.
1389 DEF_AGET(5, Instruction::AGET_WIDE, 2u, 100u, 101u), // Same as at the top.
1390
1391 DEF_AGET(3, Instruction::AGET_BYTE, 3u, 200u, 201u),
1392 DEF_AGET(4, Instruction::AGET_BYTE, 4u, 200u, 201u), // Differs from top...
1393 DEF_APUT(4, Instruction::APUT_BYTE, 5u, 200u, 201u), // Because of this IPUT.
1394 DEF_AGET(5, Instruction::AGET_BYTE, 6u, 200u, 201u), // Differs from top and the loop AGET.
1395
1396 DEF_AGET(3, Instruction::AGET, 7u, 300u, 301u),
1397 DEF_APUT(4, Instruction::APUT, 8u, 300u, 301u), // Because of this IPUT...
1398 DEF_AGET(4, Instruction::AGET, 9u, 300u, 301u), // Differs from top.
1399 DEF_AGET(5, Instruction::AGET, 10u, 300u, 301u), // Differs from top but == the loop AGET.
1400
1401 DEF_CONST(3, Instruction::CONST, 11u, 3000),
1402 DEF_APUT(3, Instruction::APUT_CHAR, 11u, 400u, 401u),
1403 DEF_APUT(3, Instruction::APUT_CHAR, 11u, 400u, 402u),
1404 DEF_AGET(4, Instruction::AGET_CHAR, 14u, 400u, 401u), // Differs from 11u and 16u.
1405 DEF_AGET(4, Instruction::AGET_CHAR, 15u, 400u, 402u), // Same as 14u.
1406 DEF_CONST(4, Instruction::CONST, 16u, 4000),
1407 DEF_APUT(4, Instruction::APUT_CHAR, 16u, 400u, 401u),
1408 DEF_APUT(4, Instruction::APUT_CHAR, 16u, 400u, 402u),
1409 DEF_AGET(5, Instruction::AGET_CHAR, 19u, 400u, 401u), // Differs from 11u and 14u...
1410 DEF_AGET(5, Instruction::AGET_CHAR, 20u, 400u, 402u), // and same as the CONST 16u.
1411
1412 DEF_AGET(3, Instruction::AGET_SHORT, 21u, 500u, 501u),
1413 DEF_APUT(4, Instruction::APUT_SHORT, 22u, 500u, 502u), // Clobbers element at index 501u.
1414 DEF_AGET(5, Instruction::AGET_SHORT, 23u, 500u, 501u), // Differs from the top.
1415
1416 DEF_AGET(3, Instruction::AGET_OBJECT, 24u, 600u, 601u),
1417 DEF_APUT(4, Instruction::APUT_OBJECT, 25u, 601u, 602u), // Clobbers 600u/601u.
1418 DEF_AGET(5, Instruction::AGET_OBJECT, 26u, 600u, 601u), // Differs from the top.
1419
1420 DEF_AGET(3, Instruction::AGET_BOOLEAN, 27u, 700u, 701u),
1421 DEF_APUT(4, Instruction::APUT_BOOLEAN, 27u, 701u, 702u), // Storing the same value.
1422 DEF_AGET(5, Instruction::AGET_BOOLEAN, 29u, 700u, 701u), // Differs from the top.
1423 };
1424
1425 PrepareMIRs(mirs);
1426 PerformGVN();
1427 ASSERT_EQ(arraysize(mirs), value_names_.size());
1428 EXPECT_EQ(value_names_[0], value_names_[1]);
1429 EXPECT_EQ(value_names_[0], value_names_[2]);
1430
1431 EXPECT_NE(value_names_[3], value_names_[4]);
1432 EXPECT_NE(value_names_[3], value_names_[6]);
1433 EXPECT_NE(value_names_[4], value_names_[6]);
1434
1435 EXPECT_NE(value_names_[7], value_names_[9]);
1436 EXPECT_EQ(value_names_[9], value_names_[10]);
1437
1438 EXPECT_NE(value_names_[14], value_names_[11]);
1439 EXPECT_NE(value_names_[14], value_names_[16]);
1440 EXPECT_EQ(value_names_[14], value_names_[15]);
1441 EXPECT_NE(value_names_[19], value_names_[11]);
1442 EXPECT_NE(value_names_[19], value_names_[14]);
1443 EXPECT_EQ(value_names_[19], value_names_[16]);
1444 EXPECT_EQ(value_names_[19], value_names_[20]);
1445
1446 EXPECT_NE(value_names_[21], value_names_[23]);
1447
1448 EXPECT_NE(value_names_[24], value_names_[26]);
1449
1450 EXPECT_EQ(value_names_[27], value_names_[29]);
1451}
1452
1453TEST_F(GlobalValueNumberingTestLoop, Phi) {
1454 static const MIRDef mirs[] = {
1455 DEF_CONST(3, Instruction::CONST, 0u, 1000),
1456 DEF_PHI2(4, 1u, 0u, 6u), // Merge CONST 0u (1000) with the same.
1457 DEF_PHI2(4, 2u, 0u, 7u), // Merge CONST 0u (1000) with the Phi itself.
1458 DEF_PHI2(4, 3u, 0u, 8u), // Merge CONST 0u (1000) and CONST 4u (2000).
1459 DEF_PHI2(4, 4u, 0u, 9u), // Merge CONST 0u (1000) and Phi 3u.
1460 DEF_CONST(4, Instruction::CONST, 5u, 2000),
1461 DEF_MOVE(4, Instruction::MOVE, 6u, 0u),
1462 DEF_MOVE(4, Instruction::MOVE, 7u, 2u),
1463 DEF_MOVE(4, Instruction::MOVE, 8u, 5u),
1464 DEF_MOVE(4, Instruction::MOVE, 9u, 3u),
1465 };
1466
1467 PrepareMIRs(mirs);
1468 PerformGVN();
1469 ASSERT_EQ(arraysize(mirs), value_names_.size());
1470 EXPECT_EQ(value_names_[1], value_names_[0]);
1471 EXPECT_EQ(value_names_[2], value_names_[0]);
1472
1473 EXPECT_NE(value_names_[3], value_names_[0]);
1474 EXPECT_NE(value_names_[3], value_names_[5]);
1475 EXPECT_NE(value_names_[4], value_names_[0]);
1476 EXPECT_NE(value_names_[4], value_names_[5]);
1477 EXPECT_NE(value_names_[4], value_names_[3]);
1478}
1479
1480TEST_F(GlobalValueNumberingTestCatch, IFields) {
1481 static const IFieldDef ifields[] = {
1482 { 0u, 1u, 0u, false },
1483 { 1u, 1u, 1u, false },
1484 };
1485 static const MIRDef mirs[] = {
1486 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 200u),
1487 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 201u),
1488 DEF_IGET(3, Instruction::IGET, 2u, 100u, 0u),
1489 DEF_IGET(3, Instruction::IGET, 3u, 200u, 0u),
1490 DEF_IGET(3, Instruction::IGET, 4u, 201u, 0u),
1491 DEF_INVOKE1(4, Instruction::INVOKE_STATIC, 201u), // Clobbering catch, 201u escapes.
1492 DEF_IGET(4, Instruction::IGET, 6u, 100u, 0u), // Differs from IGET 2u.
1493 DEF_IPUT(4, Instruction::IPUT, 6u, 100u, 1u),
1494 DEF_IPUT(4, Instruction::IPUT, 6u, 101u, 0u),
1495 DEF_IPUT(4, Instruction::IPUT, 6u, 200u, 0u),
1496 DEF_IGET(5, Instruction::IGET, 10u, 100u, 0u), // Differs from IGETs 2u and 6u.
1497 DEF_IGET(5, Instruction::IGET, 11u, 200u, 0u), // Same as the top.
1498 DEF_IGET(5, Instruction::IGET, 12u, 201u, 0u), // Differs from the top, 201u escaped.
1499 DEF_IPUT(5, Instruction::IPUT, 10u, 100u, 1u),
1500 DEF_IPUT(5, Instruction::IPUT, 10u, 101u, 0u),
1501 DEF_IPUT(5, Instruction::IPUT, 10u, 200u, 0u),
1502 DEF_IGET(6, Instruction::IGET, 16u, 100u, 0u), // Differs from IGETs 2u, 6u and 10u.
1503 DEF_IGET(6, Instruction::IGET, 17u, 100u, 1u), // Same as IGET 16u.
1504 DEF_IGET(6, Instruction::IGET, 18u, 101u, 0u), // Same as IGET 16u.
1505 DEF_IGET(6, Instruction::IGET, 19u, 200u, 0u), // Same as IGET 16u.
1506 };
1507
1508 PrepareIFields(ifields);
1509 PrepareMIRs(mirs);
1510 PerformGVN();
1511 ASSERT_EQ(arraysize(mirs), value_names_.size());
1512 EXPECT_NE(value_names_[2], value_names_[6]);
1513 EXPECT_NE(value_names_[2], value_names_[10]);
1514 EXPECT_NE(value_names_[6], value_names_[10]);
1515 EXPECT_EQ(value_names_[3], value_names_[11]);
1516 EXPECT_NE(value_names_[4], value_names_[12]);
1517
1518 EXPECT_NE(value_names_[2], value_names_[16]);
1519 EXPECT_NE(value_names_[6], value_names_[16]);
1520 EXPECT_NE(value_names_[10], value_names_[16]);
1521 EXPECT_EQ(value_names_[16], value_names_[17]);
1522 EXPECT_EQ(value_names_[16], value_names_[18]);
1523 EXPECT_EQ(value_names_[16], value_names_[19]);
1524}
1525
1526TEST_F(GlobalValueNumberingTestCatch, SFields) {
1527 static const SFieldDef sfields[] = {
1528 { 0u, 1u, 0u, false },
1529 { 1u, 1u, 1u, false },
1530 };
1531 static const MIRDef mirs[] = {
1532 DEF_SGET(3, Instruction::SGET, 0u, 0u),
1533 DEF_INVOKE1(4, Instruction::INVOKE_STATIC, 100u), // Clobbering catch.
1534 DEF_SGET(4, Instruction::SGET, 2u, 0u), // Differs from SGET 0u.
1535 DEF_SPUT(4, Instruction::SPUT, 2u, 1u),
1536 DEF_SGET(5, Instruction::SGET, 4u, 0u), // Differs from SGETs 0u and 2u.
1537 DEF_SPUT(5, Instruction::SPUT, 4u, 1u),
1538 DEF_SGET(6, Instruction::SGET, 6u, 0u), // Differs from SGETs 0u, 2u and 4u.
1539 DEF_SGET(6, Instruction::SGET, 7u, 1u), // Same as field #1.
1540 };
1541
1542 PrepareSFields(sfields);
1543 PrepareMIRs(mirs);
1544 PerformGVN();
1545 ASSERT_EQ(arraysize(mirs), value_names_.size());
1546 EXPECT_NE(value_names_[0], value_names_[2]);
1547 EXPECT_NE(value_names_[0], value_names_[4]);
1548 EXPECT_NE(value_names_[2], value_names_[4]);
1549 EXPECT_NE(value_names_[0], value_names_[6]);
1550 EXPECT_NE(value_names_[2], value_names_[6]);
1551 EXPECT_NE(value_names_[4], value_names_[6]);
1552 EXPECT_EQ(value_names_[6], value_names_[7]);
1553}
1554
1555TEST_F(GlobalValueNumberingTestCatch, Arrays) {
1556 static const MIRDef mirs[] = {
1557 DEF_UNIQUE_REF(3, Instruction::NEW_ARRAY, 200u),
1558 DEF_UNIQUE_REF(3, Instruction::NEW_ARRAY, 201u),
1559 DEF_AGET(3, Instruction::AGET, 2u, 100u, 101u),
1560 DEF_AGET(3, Instruction::AGET, 3u, 200u, 202u),
1561 DEF_AGET(3, Instruction::AGET, 4u, 200u, 203u),
1562 DEF_AGET(3, Instruction::AGET, 5u, 201u, 202u),
1563 DEF_AGET(3, Instruction::AGET, 6u, 201u, 203u),
1564 DEF_INVOKE1(4, Instruction::INVOKE_STATIC, 201u), // Clobbering catch, 201u escapes.
1565 DEF_AGET(4, Instruction::AGET, 8u, 100u, 101u), // Differs from AGET 2u.
1566 DEF_APUT(4, Instruction::APUT, 8u, 100u, 102u),
1567 DEF_APUT(4, Instruction::APUT, 8u, 200u, 202u),
1568 DEF_APUT(4, Instruction::APUT, 8u, 200u, 203u),
1569 DEF_APUT(4, Instruction::APUT, 8u, 201u, 202u),
1570 DEF_APUT(4, Instruction::APUT, 8u, 201u, 203u),
1571 DEF_AGET(5, Instruction::AGET, 14u, 100u, 101u), // Differs from AGETs 2u and 8u.
1572 DEF_AGET(5, Instruction::AGET, 15u, 200u, 202u), // Same as AGET 3u.
1573 DEF_AGET(5, Instruction::AGET, 16u, 200u, 203u), // Same as AGET 4u.
1574 DEF_AGET(5, Instruction::AGET, 17u, 201u, 202u), // Differs from AGET 5u.
1575 DEF_AGET(5, Instruction::AGET, 18u, 201u, 203u), // Differs from AGET 6u.
1576 DEF_APUT(5, Instruction::APUT, 14u, 100u, 102u),
1577 DEF_APUT(5, Instruction::APUT, 14u, 200u, 202u),
1578 DEF_APUT(5, Instruction::APUT, 14u, 200u, 203u),
1579 DEF_APUT(5, Instruction::APUT, 14u, 201u, 202u),
1580 DEF_APUT(5, Instruction::APUT, 14u, 201u, 203u),
1581 DEF_AGET(6, Instruction::AGET, 24u, 100u, 101u), // Differs from AGETs 2u, 8u and 14u.
1582 DEF_AGET(6, Instruction::AGET, 25u, 100u, 101u), // Same as AGET 24u.
1583 DEF_AGET(6, Instruction::AGET, 26u, 200u, 202u), // Same as AGET 24u.
1584 DEF_AGET(6, Instruction::AGET, 27u, 200u, 203u), // Same as AGET 24u.
1585 DEF_AGET(6, Instruction::AGET, 28u, 201u, 202u), // Same as AGET 24u.
1586 DEF_AGET(6, Instruction::AGET, 29u, 201u, 203u), // Same as AGET 24u.
1587 };
1588
1589 PrepareMIRs(mirs);
1590 PerformGVN();
1591 ASSERT_EQ(arraysize(mirs), value_names_.size());
1592 EXPECT_NE(value_names_[2], value_names_[8]);
1593 EXPECT_NE(value_names_[2], value_names_[14]);
1594 EXPECT_NE(value_names_[8], value_names_[14]);
1595 EXPECT_EQ(value_names_[3], value_names_[15]);
1596 EXPECT_EQ(value_names_[4], value_names_[16]);
1597 EXPECT_NE(value_names_[5], value_names_[17]);
1598 EXPECT_NE(value_names_[6], value_names_[18]);
1599 EXPECT_NE(value_names_[2], value_names_[24]);
1600 EXPECT_NE(value_names_[8], value_names_[24]);
1601 EXPECT_NE(value_names_[14], value_names_[24]);
1602 EXPECT_EQ(value_names_[24], value_names_[25]);
1603 EXPECT_EQ(value_names_[24], value_names_[26]);
1604 EXPECT_EQ(value_names_[24], value_names_[27]);
1605 EXPECT_EQ(value_names_[24], value_names_[28]);
1606 EXPECT_EQ(value_names_[24], value_names_[29]);
1607}
1608
1609TEST_F(GlobalValueNumberingTestCatch, Phi) {
1610 static const MIRDef mirs[] = {
1611 DEF_CONST(3, Instruction::CONST, 0u, 1000),
1612 DEF_CONST(3, Instruction::CONST, 1u, 2000),
1613 DEF_MOVE(3, Instruction::MOVE, 2u, 1u),
1614 DEF_INVOKE1(4, Instruction::INVOKE_STATIC, 100u), // Clobbering catch.
1615 DEF_CONST(5, Instruction::CONST, 4u, 1000),
1616 DEF_CONST(5, Instruction::CONST, 5u, 3000),
1617 DEF_MOVE(5, Instruction::MOVE, 6u, 5u),
1618 DEF_PHI2(6, 7u, 0u, 4u),
1619 DEF_PHI2(6, 8u, 0u, 5u),
1620 DEF_PHI2(6, 9u, 0u, 6u),
1621 DEF_PHI2(6, 10u, 1u, 4u),
1622 DEF_PHI2(6, 11u, 1u, 5u),
1623 DEF_PHI2(6, 12u, 1u, 6u),
1624 DEF_PHI2(6, 13u, 2u, 4u),
1625 DEF_PHI2(6, 14u, 2u, 5u),
1626 DEF_PHI2(6, 15u, 2u, 6u),
1627 };
1628 PrepareMIRs(mirs);
1629 PerformGVN();
1630 ASSERT_EQ(arraysize(mirs), value_names_.size());
1631 ASSERT_EQ(value_names_[4], value_names_[0]); // Both CONSTs are 1000.
1632 EXPECT_EQ(value_names_[7], value_names_[0]); // Merging CONST 0u and CONST 4u, both 1000.
1633 EXPECT_NE(value_names_[8], value_names_[0]);
1634 EXPECT_NE(value_names_[8], value_names_[5]);
1635 EXPECT_EQ(value_names_[9], value_names_[8]);
1636 EXPECT_NE(value_names_[10], value_names_[1]);
1637 EXPECT_NE(value_names_[10], value_names_[4]);
1638 EXPECT_NE(value_names_[10], value_names_[8]);
1639 EXPECT_NE(value_names_[11], value_names_[1]);
1640 EXPECT_NE(value_names_[11], value_names_[5]);
1641 EXPECT_NE(value_names_[11], value_names_[8]);
1642 EXPECT_NE(value_names_[11], value_names_[10]);
1643 EXPECT_EQ(value_names_[12], value_names_[11]);
1644 EXPECT_EQ(value_names_[13], value_names_[10]);
1645 EXPECT_EQ(value_names_[14], value_names_[11]);
1646 EXPECT_EQ(value_names_[15], value_names_[11]);
1647}
1648
1649TEST_F(GlobalValueNumberingTest, NullCheckIFields) {
1650 static const IFieldDef ifields[] = {
1651 { 0u, 1u, 0u, false }, // Object.
1652 { 1u, 1u, 1u, false }, // Object.
1653 };
1654 static const BBDef bbs[] = {
1655 DEF_BB(kNullBlock, DEF_SUCC0(), DEF_PRED0()),
1656 DEF_BB(kEntryBlock, DEF_SUCC1(3), DEF_PRED0()),
1657 DEF_BB(kExitBlock, DEF_SUCC0(), DEF_PRED1(5)),
1658 DEF_BB(kDalvikByteCode, DEF_SUCC2(4, 5), DEF_PRED1(1)), // 4 is fall-through, 5 is taken.
1659 DEF_BB(kDalvikByteCode, DEF_SUCC1(5), DEF_PRED1(3)),
1660 DEF_BB(kDalvikByteCode, DEF_SUCC1(2), DEF_PRED2(3, 4)),
1661 };
1662 static const MIRDef mirs[] = {
1663 DEF_IGET(3, Instruction::IGET_OBJECT, 0u, 100u, 0u),
1664 DEF_IGET(3, Instruction::IGET_OBJECT, 1u, 100u, 1u),
1665 DEF_IGET(3, Instruction::IGET_OBJECT, 2u, 101u, 0u),
1666 DEF_IFZ(3, Instruction::IF_NEZ, 0u), // Null-check for field #0 for taken.
1667 DEF_UNIQUE_REF(4, Instruction::NEW_ARRAY, 4u),
1668 DEF_IPUT(4, Instruction::IPUT_OBJECT, 4u, 100u, 0u),
1669 DEF_IPUT(4, Instruction::IPUT_OBJECT, 4u, 100u, 1u),
1670 DEF_IPUT(4, Instruction::IPUT_OBJECT, 4u, 101u, 0u),
1671 DEF_IGET(5, Instruction::IGET_OBJECT, 8u, 100u, 0u), // 100u/#0, IF_NEZ/NEW_ARRAY.
1672 DEF_IGET(5, Instruction::IGET_OBJECT, 9u, 100u, 1u), // 100u/#1, -/NEW_ARRAY.
1673 DEF_IGET(5, Instruction::IGET_OBJECT, 10u, 101u, 0u), // 101u/#0, -/NEW_ARRAY.
1674 DEF_CONST(5, Instruction::CONST, 11u, 0),
1675 DEF_AGET(5, Instruction::AGET, 12u, 8u, 11u), // Null-check eliminated.
1676 DEF_AGET(5, Instruction::AGET, 13u, 9u, 11u), // Null-check kept.
1677 DEF_AGET(5, Instruction::AGET, 14u, 10u, 11u), // Null-check kept.
1678 };
1679 static const bool expected_ignore_null_check[] = {
1680 false, true, false, false, // BB #3; unimportant.
1681 false, true, true, true, // BB #4; unimportant.
1682 true, true, true, false, true, false, false, // BB #5; only the last three are important.
1683 };
1684
1685 PrepareIFields(ifields);
1686 PrepareBasicBlocks(bbs);
1687 PrepareMIRs(mirs);
1688 PerformGVN();
1689 ASSERT_EQ(arraysize(mirs), value_names_.size());
1690 PerformGVNCodeModifications();
1691 ASSERT_EQ(arraysize(expected_ignore_null_check), mir_count_);
1692 for (size_t i = 0u; i != arraysize(mirs); ++i) {
1693 EXPECT_EQ(expected_ignore_null_check[i],
1694 (mirs_[i].optimization_flags & MIR_IGNORE_NULL_CHECK) != 0) << i;
1695 }
1696}
1697
1698TEST_F(GlobalValueNumberingTest, NullCheckSFields) {
1699 static const SFieldDef sfields[] = {
1700 { 0u, 1u, 0u, false }, // Object.
1701 { 1u, 1u, 1u, false }, // Object.
1702 };
1703 static const BBDef bbs[] = {
1704 DEF_BB(kNullBlock, DEF_SUCC0(), DEF_PRED0()),
1705 DEF_BB(kEntryBlock, DEF_SUCC1(3), DEF_PRED0()),
1706 DEF_BB(kExitBlock, DEF_SUCC0(), DEF_PRED1(5)),
1707 DEF_BB(kDalvikByteCode, DEF_SUCC2(4, 5), DEF_PRED1(1)), // 4 is fall-through, 5 is taken.
1708 DEF_BB(kDalvikByteCode, DEF_SUCC1(5), DEF_PRED1(3)),
1709 DEF_BB(kDalvikByteCode, DEF_SUCC1(2), DEF_PRED2(3, 4)),
1710 };
1711 static const MIRDef mirs[] = {
1712 DEF_SGET(3, Instruction::SGET_OBJECT, 0u, 0u),
1713 DEF_SGET(3, Instruction::SGET_OBJECT, 1u, 1u),
1714 DEF_IFZ(3, Instruction::IF_NEZ, 0u), // Null-check for field #0 for taken.
1715 DEF_UNIQUE_REF(4, Instruction::NEW_ARRAY, 3u),
1716 DEF_SPUT(4, Instruction::SPUT_OBJECT, 3u, 0u),
1717 DEF_SPUT(4, Instruction::SPUT_OBJECT, 3u, 1u),
1718 DEF_SGET(5, Instruction::SGET_OBJECT, 6u, 0u), // Field #0 is null-checked, IF_NEZ/NEW_ARRAY.
1719 DEF_SGET(5, Instruction::SGET_OBJECT, 7u, 1u), // Field #1 is not null-checked, -/NEW_ARRAY.
1720 DEF_CONST(5, Instruction::CONST, 8u, 0),
1721 DEF_AGET(5, Instruction::AGET, 9u, 6u, 8u), // Null-check eliminated.
1722 DEF_AGET(5, Instruction::AGET, 10u, 7u, 8u), // Null-check kept.
1723 };
1724 static const bool expected_ignore_null_check[] = {
1725 false, false, false, false, false, false, false, false, false, true, false
1726 };
1727
1728 PrepareSFields(sfields);
1729 PrepareBasicBlocks(bbs);
1730 PrepareMIRs(mirs);
1731 PerformGVN();
1732 ASSERT_EQ(arraysize(mirs), value_names_.size());
1733 PerformGVNCodeModifications();
1734 ASSERT_EQ(arraysize(expected_ignore_null_check), mir_count_);
1735 for (size_t i = 0u; i != arraysize(mirs); ++i) {
1736 EXPECT_EQ(expected_ignore_null_check[i],
1737 (mirs_[i].optimization_flags & MIR_IGNORE_NULL_CHECK) != 0) << i;
1738 }
1739}
1740
1741TEST_F(GlobalValueNumberingTest, NullCheckArrays) {
1742 static const BBDef bbs[] = {
1743 DEF_BB(kNullBlock, DEF_SUCC0(), DEF_PRED0()),
1744 DEF_BB(kEntryBlock, DEF_SUCC1(3), DEF_PRED0()),
1745 DEF_BB(kExitBlock, DEF_SUCC0(), DEF_PRED1(5)),
1746 DEF_BB(kDalvikByteCode, DEF_SUCC2(4, 5), DEF_PRED1(1)), // 4 is fall-through, 5 is taken.
1747 DEF_BB(kDalvikByteCode, DEF_SUCC1(5), DEF_PRED1(3)),
1748 DEF_BB(kDalvikByteCode, DEF_SUCC1(2), DEF_PRED2(3, 4)),
1749 };
1750 static const MIRDef mirs[] = {
1751 DEF_AGET(3, Instruction::AGET_OBJECT, 0u, 100u, 102u),
1752 DEF_AGET(3, Instruction::AGET_OBJECT, 1u, 100u, 103u),
1753 DEF_AGET(3, Instruction::AGET_OBJECT, 2u, 101u, 102u),
1754 DEF_IFZ(3, Instruction::IF_NEZ, 0u), // Null-check for field #0 for taken.
1755 DEF_UNIQUE_REF(4, Instruction::NEW_ARRAY, 4u),
1756 DEF_APUT(4, Instruction::APUT_OBJECT, 4u, 100u, 102u),
1757 DEF_APUT(4, Instruction::APUT_OBJECT, 4u, 100u, 103u),
1758 DEF_APUT(4, Instruction::APUT_OBJECT, 4u, 101u, 102u),
1759 DEF_AGET(5, Instruction::AGET_OBJECT, 8u, 100u, 102u), // Null-checked, IF_NEZ/NEW_ARRAY.
1760 DEF_AGET(5, Instruction::AGET_OBJECT, 9u, 100u, 103u), // Not null-checked, -/NEW_ARRAY.
1761 DEF_AGET(5, Instruction::AGET_OBJECT, 10u, 101u, 102u), // Not null-checked, -/NEW_ARRAY.
1762 DEF_CONST(5, Instruction::CONST, 11u, 0),
1763 DEF_AGET(5, Instruction::AGET, 12u, 8u, 11u), // Null-check eliminated.
1764 DEF_AGET(5, Instruction::AGET, 13u, 9u, 11u), // Null-check kept.
1765 DEF_AGET(5, Instruction::AGET, 14u, 10u, 11u), // Null-check kept.
1766 };
1767 static const bool expected_ignore_null_check[] = {
1768 false, true, false, false, // BB #3; unimportant.
1769 false, true, true, true, // BB #4; unimportant.
1770 true, true, true, false, true, false, false, // BB #5; only the last three are important.
1771 };
1772
1773 PrepareBasicBlocks(bbs);
1774 PrepareMIRs(mirs);
1775 PerformGVN();
1776 ASSERT_EQ(arraysize(mirs), value_names_.size());
1777 PerformGVNCodeModifications();
1778 ASSERT_EQ(arraysize(expected_ignore_null_check), mir_count_);
1779 for (size_t i = 0u; i != arraysize(mirs); ++i) {
1780 EXPECT_EQ(expected_ignore_null_check[i],
1781 (mirs_[i].optimization_flags & MIR_IGNORE_NULL_CHECK) != 0) << i;
1782 }
1783}
1784
1785TEST_F(GlobalValueNumberingTestDiamond, RangeCheckArrays) {
1786 // NOTE: We don't merge range checks when we merge value names for Phis or memory locations.
1787 static const MIRDef mirs[] = {
1788 DEF_AGET(4, Instruction::AGET, 0u, 100u, 101u),
1789 DEF_AGET(5, Instruction::AGET, 1u, 100u, 101u),
1790 DEF_APUT(6, Instruction::APUT, 2u, 100u, 101u),
1791
1792 DEF_AGET(4, Instruction::AGET, 3u, 200u, 201u),
1793 DEF_AGET(5, Instruction::AGET, 4u, 200u, 202u),
1794 DEF_APUT(6, Instruction::APUT, 5u, 200u, 201u),
1795
1796 DEF_AGET(4, Instruction::AGET, 6u, 300u, 302u),
1797 DEF_AGET(5, Instruction::AGET, 7u, 301u, 302u),
1798 DEF_APUT(6, Instruction::APUT, 8u, 300u, 302u),
1799 };
1800 static const bool expected_ignore_null_check[] = {
1801 false, false, true,
1802 false, false, true,
1803 false, false, false,
1804 };
1805 static const bool expected_ignore_range_check[] = {
1806 false, false, true,
1807 false, false, false,
1808 false, false, false,
1809 };
1810
1811 PrepareMIRs(mirs);
1812 PerformGVN();
1813 ASSERT_EQ(arraysize(mirs), value_names_.size());
1814 PerformGVNCodeModifications();
1815 ASSERT_EQ(arraysize(expected_ignore_null_check), mir_count_);
1816 ASSERT_EQ(arraysize(expected_ignore_range_check), mir_count_);
1817 for (size_t i = 0u; i != arraysize(mirs); ++i) {
1818 EXPECT_EQ(expected_ignore_null_check[i],
1819 (mirs_[i].optimization_flags & MIR_IGNORE_NULL_CHECK) != 0) << i;
1820 EXPECT_EQ(expected_ignore_range_check[i],
1821 (mirs_[i].optimization_flags & MIR_IGNORE_RANGE_CHECK) != 0) << i;
1822 }
1823}
1824
1825TEST_F(GlobalValueNumberingTestDiamond, MergeSameValueInDifferentMemoryLocations) {
1826 static const IFieldDef ifields[] = {
1827 { 0u, 1u, 0u, false }, // Int.
1828 { 1u, 1u, 1u, false }, // Int.
1829 };
1830 static const SFieldDef sfields[] = {
1831 { 0u, 1u, 0u, false }, // Int.
1832 { 1u, 1u, 1u, false }, // Int.
1833 };
1834 static const MIRDef mirs[] = {
1835 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 100u),
1836 DEF_UNIQUE_REF(3, Instruction::NEW_ARRAY, 200u),
1837 DEF_CONST(4, Instruction::CONST, 2u, 1000),
1838 DEF_IPUT(4, Instruction::IPUT, 2u, 100u, 0u),
1839 DEF_IPUT(4, Instruction::IPUT, 2u, 100u, 1u),
1840 DEF_IPUT(4, Instruction::IPUT, 2u, 101u, 0u),
1841 DEF_APUT(4, Instruction::APUT, 2u, 200u, 202u),
1842 DEF_APUT(4, Instruction::APUT, 2u, 200u, 203u),
1843 DEF_APUT(4, Instruction::APUT, 2u, 201u, 202u),
1844 DEF_APUT(4, Instruction::APUT, 2u, 201u, 203u),
1845 DEF_SPUT(4, Instruction::SPUT, 2u, 0u),
1846 DEF_SPUT(4, Instruction::SPUT, 2u, 1u),
1847 DEF_CONST(5, Instruction::CONST, 12u, 2000),
1848 DEF_IPUT(5, Instruction::IPUT, 12u, 100u, 0u),
1849 DEF_IPUT(5, Instruction::IPUT, 12u, 100u, 1u),
1850 DEF_IPUT(5, Instruction::IPUT, 12u, 101u, 0u),
1851 DEF_APUT(5, Instruction::APUT, 12u, 200u, 202u),
1852 DEF_APUT(5, Instruction::APUT, 12u, 200u, 203u),
1853 DEF_APUT(5, Instruction::APUT, 12u, 201u, 202u),
1854 DEF_APUT(5, Instruction::APUT, 12u, 201u, 203u),
1855 DEF_SPUT(5, Instruction::SPUT, 12u, 0u),
1856 DEF_SPUT(5, Instruction::SPUT, 12u, 1u),
1857 DEF_PHI2(6, 22u, 2u, 12u),
1858 DEF_IGET(6, Instruction::IGET, 23u, 100u, 0u),
1859 DEF_IGET(6, Instruction::IGET, 24u, 100u, 1u),
1860 DEF_IGET(6, Instruction::IGET, 25u, 101u, 0u),
1861 DEF_AGET(6, Instruction::AGET, 26u, 200u, 202u),
1862 DEF_AGET(6, Instruction::AGET, 27u, 200u, 203u),
1863 DEF_AGET(6, Instruction::AGET, 28u, 201u, 202u),
1864 DEF_AGET(6, Instruction::AGET, 29u, 201u, 203u),
1865 DEF_SGET(6, Instruction::SGET, 30u, 0u),
1866 DEF_SGET(6, Instruction::SGET, 31u, 1u),
1867 };
1868 PrepareIFields(ifields);
1869 PrepareSFields(sfields);
1870 PrepareMIRs(mirs);
1871 PerformGVN();
1872 ASSERT_EQ(arraysize(mirs), value_names_.size());
1873 EXPECT_NE(value_names_[2], value_names_[12]);
1874 EXPECT_NE(value_names_[2], value_names_[22]);
1875 EXPECT_NE(value_names_[12], value_names_[22]);
1876 for (size_t i = 23; i != arraysize(mirs); ++i) {
1877 EXPECT_EQ(value_names_[22], value_names_[i]) << i;
1878 }
1879}
1880
1881TEST_F(GlobalValueNumberingTest, InfiniteLocationLoop) {
1882 // This is a pattern that lead to an infinite loop during the GVN development. This has been
1883 // fixed by rewriting the merging of AliasingValues to merge only locations read from or
1884 // written to in each incoming LVN rather than merging all locations read from or written to
1885 // in any incoming LVN. It also showed up only when the GVN used the DFS ordering instead of
1886 // the "topological" ordering but, since the "topological" ordering is not really topological
1887 // when there are cycles and an optimizing Java compiler (or a tool like proguard) could
1888 // theoretically create any sort of flow graph, this could have shown up in real code.
1889 //
1890 // While we were merging all the locations:
1891 // The first time the Phi evaluates to the same value name as CONST 0u. After the second
1892 // evaluation, when the BB #9 has been processed, the Phi receives its own value name.
1893 // However, the index from the first evaluation keeps disappearing and reappearing in the
1894 // LVN's aliasing_array_value_map_'s load_value_map for BBs #9, #4, #5, #7 because of the
1895 // DFS ordering of LVN evaluation.
1896 static const IFieldDef ifields[] = {
1897 { 0u, 1u, 0u, false }, // Object.
1898 };
1899 static const BBDef bbs[] = {
1900 DEF_BB(kNullBlock, DEF_SUCC0(), DEF_PRED0()),
1901 DEF_BB(kEntryBlock, DEF_SUCC1(3), DEF_PRED0()),
1902 DEF_BB(kExitBlock, DEF_SUCC0(), DEF_PRED1(4)),
1903 DEF_BB(kDalvikByteCode, DEF_SUCC1(4), DEF_PRED1(1)),
1904 DEF_BB(kDalvikByteCode, DEF_SUCC2(5, 2), DEF_PRED2(3, 9)),
1905 DEF_BB(kDalvikByteCode, DEF_SUCC2(6, 7), DEF_PRED1(4)),
1906 DEF_BB(kDalvikByteCode, DEF_SUCC1(9), DEF_PRED1(5)),
1907 DEF_BB(kDalvikByteCode, DEF_SUCC2(8, 9), DEF_PRED1(5)),
1908 DEF_BB(kDalvikByteCode, DEF_SUCC1(9), DEF_PRED1(7)),
1909 DEF_BB(kDalvikByteCode, DEF_SUCC1(4), DEF_PRED3(6, 7, 8)),
1910 };
1911 static const MIRDef mirs[] = {
1912 DEF_CONST(3, Instruction::CONST, 0u, 0),
1913 DEF_PHI2(4, 1u, 0u, 10u),
1914 DEF_INVOKE1(6, Instruction::INVOKE_STATIC, 100u),
1915 DEF_IGET(6, Instruction::IGET_OBJECT, 3u, 100u, 0u),
1916 DEF_CONST(6, Instruction::CONST, 4u, 1000),
1917 DEF_APUT(6, Instruction::APUT, 4u, 3u, 1u), // Index is Phi 1u.
1918 DEF_INVOKE1(8, Instruction::INVOKE_STATIC, 100u),
1919 DEF_IGET(8, Instruction::IGET_OBJECT, 7u, 100u, 0u),
1920 DEF_CONST(8, Instruction::CONST, 8u, 2000),
1921 DEF_APUT(8, Instruction::APUT, 9u, 7u, 1u), // Index is Phi 1u.
1922 DEF_CONST(9, Instruction::CONST, 10u, 3000),
1923 };
1924 PrepareIFields(ifields);
1925 PrepareBasicBlocks(bbs);
1926 PrepareMIRs(mirs);
1927 // Using DFS order for this test. The GVN result should not depend on the used ordering
1928 // once the GVN actually converges. But creating a test for this convergence issue with
1929 // the topological ordering could be a very challenging task.
1930 PerformPreOrderDfsGVN();
1931}
1932
Vladimir Marko55fff042014-07-10 12:42:52 +01001933TEST_F(GlobalValueNumberingTestTwoConsecutiveLoops, IFieldAndPhi) {
Vladimir Marko95a05972014-05-30 10:01:32 +01001934 static const IFieldDef ifields[] = {
1935 { 0u, 1u, 0u, false }, // Int.
1936 };
1937 static const MIRDef mirs[] = {
1938 DEF_MOVE(3, Instruction::MOVE_OBJECT, 0u, 100u),
1939 DEF_IPUT(3, Instruction::IPUT_OBJECT, 0u, 200u, 0u),
1940 DEF_PHI2(4, 2u, 0u, 3u),
1941 DEF_MOVE(5, Instruction::MOVE_OBJECT, 3u, 300u),
1942 DEF_IPUT(5, Instruction::IPUT_OBJECT, 3u, 200u, 0u),
1943 DEF_MOVE(6, Instruction::MOVE_OBJECT, 5u, 2u),
1944 DEF_IGET(6, Instruction::IGET_OBJECT, 6u, 200u, 0u),
1945 DEF_MOVE(7, Instruction::MOVE_OBJECT, 7u, 5u),
1946 DEF_IGET(7, Instruction::IGET_OBJECT, 8u, 200u, 0u),
1947 DEF_MOVE(8, Instruction::MOVE_OBJECT, 9u, 5u),
1948 DEF_IGET(8, Instruction::IGET_OBJECT, 10u, 200u, 0u),
1949 DEF_MOVE(9, Instruction::MOVE_OBJECT, 11u, 5u),
1950 DEF_IGET(9, Instruction::IGET_OBJECT, 12u, 200u, 0u),
1951 };
1952
1953 PrepareIFields(ifields);
1954 PrepareMIRs(mirs);
1955 PerformGVN();
1956 ASSERT_EQ(arraysize(mirs), value_names_.size());
1957 EXPECT_NE(value_names_[0], value_names_[3]);
1958 EXPECT_NE(value_names_[0], value_names_[2]);
1959 EXPECT_NE(value_names_[3], value_names_[2]);
1960 EXPECT_EQ(value_names_[2], value_names_[5]);
1961 EXPECT_EQ(value_names_[5], value_names_[6]);
1962 EXPECT_EQ(value_names_[5], value_names_[7]);
1963 EXPECT_EQ(value_names_[5], value_names_[8]);
1964 EXPECT_EQ(value_names_[5], value_names_[9]);
1965 EXPECT_EQ(value_names_[5], value_names_[10]);
1966 EXPECT_EQ(value_names_[5], value_names_[11]);
1967 EXPECT_EQ(value_names_[5], value_names_[12]);
1968}
1969
Vladimir Marko55fff042014-07-10 12:42:52 +01001970TEST_F(GlobalValueNumberingTestTwoConsecutiveLoops, NullCheck) {
Vladimir Marko95a05972014-05-30 10:01:32 +01001971 static const IFieldDef ifields[] = {
1972 { 0u, 1u, 0u, false }, // Int.
1973 };
1974 static const SFieldDef sfields[] = {
1975 { 0u, 1u, 0u, false }, // Int.
1976 };
1977 static const MIRDef mirs[] = {
1978 DEF_MOVE(3, Instruction::MOVE_OBJECT, 0u, 100u),
1979 DEF_IGET(3, Instruction::IGET_OBJECT, 1u, 200u, 0u),
1980 DEF_SGET(3, Instruction::SGET_OBJECT, 2u, 0u),
1981 DEF_AGET(3, Instruction::AGET_OBJECT, 3u, 300u, 201u),
1982 DEF_PHI2(4, 4u, 0u, 8u),
1983 DEF_IGET(5, Instruction::IGET_OBJECT, 5u, 200u, 0u),
1984 DEF_SGET(5, Instruction::SGET_OBJECT, 6u, 0u),
1985 DEF_AGET(5, Instruction::AGET_OBJECT, 7u, 300u, 201u),
1986 DEF_MOVE(5, Instruction::MOVE_OBJECT, 8u, 400u),
1987 DEF_IPUT(5, Instruction::IPUT_OBJECT, 4u, 200u, 0u), // PUT the Phi 4u.
1988 DEF_SPUT(5, Instruction::SPUT_OBJECT, 4u, 0u), // PUT the Phi 4u.
1989 DEF_APUT(5, Instruction::APUT_OBJECT, 4u, 300u, 201u), // PUT the Phi 4u.
1990 DEF_MOVE(6, Instruction::MOVE_OBJECT, 12u, 4u),
1991 DEF_IGET(6, Instruction::IGET_OBJECT, 13u, 200u, 0u),
1992 DEF_SGET(6, Instruction::SGET_OBJECT, 14u, 0u),
1993 DEF_AGET(6, Instruction::AGET_OBJECT, 15u, 300u, 201u),
1994 DEF_AGET(6, Instruction::AGET_OBJECT, 16u, 12u, 600u),
1995 DEF_AGET(6, Instruction::AGET_OBJECT, 17u, 13u, 600u),
1996 DEF_AGET(6, Instruction::AGET_OBJECT, 18u, 14u, 600u),
1997 DEF_AGET(6, Instruction::AGET_OBJECT, 19u, 15u, 600u),
1998 DEF_MOVE(8, Instruction::MOVE_OBJECT, 20u, 12u),
1999 DEF_IGET(8, Instruction::IGET_OBJECT, 21u, 200u, 0u),
2000 DEF_SGET(8, Instruction::SGET_OBJECT, 22u, 0u),
2001 DEF_AGET(8, Instruction::AGET_OBJECT, 23u, 300u, 201u),
2002 DEF_AGET(8, Instruction::AGET_OBJECT, 24u, 12u, 600u),
2003 DEF_AGET(8, Instruction::AGET_OBJECT, 25u, 13u, 600u),
2004 DEF_AGET(8, Instruction::AGET_OBJECT, 26u, 14u, 600u),
2005 DEF_AGET(8, Instruction::AGET_OBJECT, 27u, 15u, 600u),
2006 DEF_MOVE(9, Instruction::MOVE_OBJECT, 28u, 12u),
2007 DEF_IGET(9, Instruction::IGET_OBJECT, 29u, 200u, 0u),
2008 DEF_SGET(9, Instruction::SGET_OBJECT, 30u, 0u),
2009 DEF_AGET(9, Instruction::AGET_OBJECT, 31u, 300u, 201u),
2010 DEF_AGET(9, Instruction::AGET_OBJECT, 32u, 12u, 600u),
2011 DEF_AGET(9, Instruction::AGET_OBJECT, 33u, 13u, 600u),
2012 DEF_AGET(9, Instruction::AGET_OBJECT, 34u, 14u, 600u),
2013 DEF_AGET(9, Instruction::AGET_OBJECT, 35u, 15u, 600u),
2014 };
2015 static const bool expected_ignore_null_check[] = {
2016 false, false, false, false, // BB #3.
2017 false, true, false, true, false, true, false, true, // BBs #4 and #5.
2018 false, true, false, true, false, false, false, false, // BB #6.
2019 false, true, false, true, true, true, true, true, // BB #7.
2020 false, true, false, true, true, true, true, true, // BB #8.
2021 };
2022 static const bool expected_ignore_range_check[] = {
2023 false, false, false, false, // BB #3.
2024 false, false, false, true, false, false, false, true, // BBs #4 and #5.
2025 false, false, false, true, false, false, false, false, // BB #6.
2026 false, false, false, true, true, true, true, true, // BB #7.
2027 false, false, false, true, true, true, true, true, // BB #8.
2028 };
2029
2030 PrepareIFields(ifields);
2031 PrepareSFields(sfields);
2032 PrepareMIRs(mirs);
2033 PerformGVN();
2034 ASSERT_EQ(arraysize(mirs), value_names_.size());
2035 EXPECT_NE(value_names_[0], value_names_[4]);
2036 EXPECT_NE(value_names_[1], value_names_[5]);
2037 EXPECT_NE(value_names_[2], value_names_[6]);
2038 EXPECT_NE(value_names_[3], value_names_[7]);
2039 EXPECT_NE(value_names_[4], value_names_[8]);
Vladimir Marko95a05972014-05-30 10:01:32 +01002040 EXPECT_EQ(value_names_[4], value_names_[12]);
Vladimir Marko55fff042014-07-10 12:42:52 +01002041 EXPECT_EQ(value_names_[5], value_names_[13]);
2042 EXPECT_EQ(value_names_[6], value_names_[14]);
2043 EXPECT_EQ(value_names_[7], value_names_[15]);
Vladimir Marko95a05972014-05-30 10:01:32 +01002044 EXPECT_EQ(value_names_[12], value_names_[20]);
2045 EXPECT_EQ(value_names_[13], value_names_[21]);
2046 EXPECT_EQ(value_names_[14], value_names_[22]);
2047 EXPECT_EQ(value_names_[15], value_names_[23]);
2048 EXPECT_EQ(value_names_[12], value_names_[28]);
2049 EXPECT_EQ(value_names_[13], value_names_[29]);
2050 EXPECT_EQ(value_names_[14], value_names_[30]);
2051 EXPECT_EQ(value_names_[15], value_names_[31]);
2052 PerformGVNCodeModifications();
2053 for (size_t i = 0u; i != arraysize(mirs); ++i) {
2054 EXPECT_EQ(expected_ignore_null_check[i],
2055 (mirs_[i].optimization_flags & MIR_IGNORE_NULL_CHECK) != 0) << i;
2056 EXPECT_EQ(expected_ignore_range_check[i],
2057 (mirs_[i].optimization_flags & MIR_IGNORE_RANGE_CHECK) != 0) << i;
2058 }
2059}
2060
Vladimir Marko55fff042014-07-10 12:42:52 +01002061TEST_F(GlobalValueNumberingTestTwoNestedLoops, IFieldAndPhi) {
Vladimir Marko95a05972014-05-30 10:01:32 +01002062 static const IFieldDef ifields[] = {
2063 { 0u, 1u, 0u, false }, // Int.
2064 };
2065 static const MIRDef mirs[] = {
2066 DEF_MOVE(3, Instruction::MOVE_OBJECT, 0u, 100u),
2067 DEF_IPUT(3, Instruction::IPUT_OBJECT, 0u, 200u, 0u),
2068 DEF_PHI2(4, 2u, 0u, 11u),
2069 DEF_MOVE(4, Instruction::MOVE_OBJECT, 3u, 2u),
2070 DEF_IGET(4, Instruction::IGET_OBJECT, 4u, 200u, 0u),
2071 DEF_MOVE(5, Instruction::MOVE_OBJECT, 5u, 3u),
2072 DEF_IGET(5, Instruction::IGET_OBJECT, 6u, 200u, 0u),
2073 DEF_MOVE(6, Instruction::MOVE_OBJECT, 7u, 3u),
2074 DEF_IGET(6, Instruction::IGET_OBJECT, 8u, 200u, 0u),
2075 DEF_MOVE(7, Instruction::MOVE_OBJECT, 9u, 3u),
2076 DEF_IGET(7, Instruction::IGET_OBJECT, 10u, 200u, 0u),
2077 DEF_MOVE(7, Instruction::MOVE_OBJECT, 11u, 300u),
2078 DEF_IPUT(7, Instruction::IPUT_OBJECT, 11u, 200u, 0u),
2079 DEF_MOVE(8, Instruction::MOVE_OBJECT, 13u, 3u),
2080 DEF_IGET(8, Instruction::IGET_OBJECT, 14u, 200u, 0u),
2081 };
2082
2083 PrepareIFields(ifields);
2084 PrepareMIRs(mirs);
2085 PerformGVN();
2086 ASSERT_EQ(arraysize(mirs), value_names_.size());
2087 EXPECT_NE(value_names_[0], value_names_[11]);
2088 EXPECT_NE(value_names_[0], value_names_[2]);
2089 EXPECT_NE(value_names_[11], value_names_[2]);
2090 EXPECT_EQ(value_names_[2], value_names_[3]);
2091 EXPECT_EQ(value_names_[3], value_names_[4]);
2092 EXPECT_EQ(value_names_[3], value_names_[5]);
2093 EXPECT_EQ(value_names_[3], value_names_[6]);
2094 EXPECT_EQ(value_names_[3], value_names_[7]);
2095 EXPECT_EQ(value_names_[3], value_names_[8]);
2096 EXPECT_EQ(value_names_[3], value_names_[9]);
2097 EXPECT_EQ(value_names_[3], value_names_[10]);
2098 EXPECT_EQ(value_names_[3], value_names_[13]);
2099 EXPECT_EQ(value_names_[3], value_names_[14]);
2100}
2101
Vladimir Marko11ca6122014-07-17 20:50:07 +01002102TEST_F(GlobalValueNumberingTest, NormalPathToCatchEntry) {
2103 // When there's an empty catch block, all the exception paths lead to the next block in
2104 // the normal path and we can also have normal "taken" or "fall-through" branches to that
2105 // path. Check that LocalValueNumbering::PruneNonAliasingRefsForCatch() can handle it.
2106 static const BBDef bbs[] = {
2107 DEF_BB(kNullBlock, DEF_SUCC0(), DEF_PRED0()),
2108 DEF_BB(kEntryBlock, DEF_SUCC1(3), DEF_PRED0()),
Vladimir Marko55fff042014-07-10 12:42:52 +01002109 DEF_BB(kExitBlock, DEF_SUCC0(), DEF_PRED1(5)),
Vladimir Marko11ca6122014-07-17 20:50:07 +01002110 DEF_BB(kDalvikByteCode, DEF_SUCC1(4), DEF_PRED1(1)),
2111 DEF_BB(kDalvikByteCode, DEF_SUCC1(5), DEF_PRED1(3)),
2112 DEF_BB(kDalvikByteCode, DEF_SUCC1(2), DEF_PRED2(3, 4)),
2113 };
2114 static const MIRDef mirs[] = {
2115 DEF_INVOKE1(4, Instruction::INVOKE_STATIC, 100u),
2116 };
2117 PrepareBasicBlocks(bbs);
2118 BasicBlock* catch_handler = cu_.mir_graph->GetBasicBlock(5u);
2119 catch_handler->catch_entry = true;
Vladimir Marko55fff042014-07-10 12:42:52 +01002120 // Add successor block info to the check block.
2121 BasicBlock* check_bb = cu_.mir_graph->GetBasicBlock(3u);
2122 check_bb->successor_block_list_type = kCatch;
2123 check_bb->successor_blocks = new (&cu_.arena) GrowableArray<SuccessorBlockInfo*>(
2124 &cu_.arena, 2, kGrowableArraySuccessorBlocks);
2125 SuccessorBlockInfo* successor_block_info = reinterpret_cast<SuccessorBlockInfo*>
2126 (cu_.arena.Alloc(sizeof(SuccessorBlockInfo), kArenaAllocSuccessor));
2127 successor_block_info->block = catch_handler->id;
2128 check_bb->successor_blocks->Insert(successor_block_info);
Vladimir Marko11ca6122014-07-17 20:50:07 +01002129 BasicBlock* merge_block = cu_.mir_graph->GetBasicBlock(4u);
2130 std::swap(merge_block->taken, merge_block->fall_through);
2131 PrepareMIRs(mirs);
2132 PerformGVN();
2133}
2134
Vladimir Marko95a05972014-05-30 10:01:32 +01002135} // namespace art