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