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