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