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