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