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