blob: b4559ef3756aef1b81a34c794eced1b61532d5fd [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 Marko22fe45d2015-03-18 11:33:58 +0000139#define DEF_UNOP(bb, opcode, result, src) DEF_MOVE(bb, opcode, result, src)
Vladimir Marko95a05972014-05-30 10:01:32 +0100140
141 void DoPrepareIFields(const IFieldDef* defs, size_t count) {
Vladimir Markoe39c54e2014-09-22 14:50:02 +0100142 cu_.mir_graph->ifield_lowering_infos_.clear();
143 cu_.mir_graph->ifield_lowering_infos_.reserve(count);
Vladimir Marko95a05972014-05-30 10:01:32 +0100144 for (size_t i = 0u; i != count; ++i) {
145 const IFieldDef* def = &defs[i];
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800146 MirIFieldLoweringInfo field_info(def->field_idx, def->type, false);
Vladimir Marko95a05972014-05-30 10:01:32 +0100147 if (def->declaring_dex_file != 0u) {
148 field_info.declaring_dex_file_ = reinterpret_cast<const DexFile*>(def->declaring_dex_file);
149 field_info.declaring_field_idx_ = def->declaring_field_idx;
Vladimir Markoaf6925b2014-10-31 16:37:32 +0000150 field_info.flags_ &= ~(def->is_volatile ? 0u : MirSFieldLoweringInfo::kFlagIsVolatile);
Vladimir Marko95a05972014-05-30 10:01:32 +0100151 }
Vladimir Markoe39c54e2014-09-22 14:50:02 +0100152 cu_.mir_graph->ifield_lowering_infos_.push_back(field_info);
Vladimir Marko95a05972014-05-30 10:01:32 +0100153 }
154 }
155
156 template <size_t count>
157 void PrepareIFields(const IFieldDef (&defs)[count]) {
158 DoPrepareIFields(defs, count);
159 }
160
161 void DoPrepareSFields(const SFieldDef* defs, size_t count) {
Vladimir Markoe39c54e2014-09-22 14:50:02 +0100162 cu_.mir_graph->sfield_lowering_infos_.clear();
163 cu_.mir_graph->sfield_lowering_infos_.reserve(count);
Vladimir Marko95a05972014-05-30 10:01:32 +0100164 for (size_t i = 0u; i != count; ++i) {
165 const SFieldDef* def = &defs[i];
Vladimir Markoaf6925b2014-10-31 16:37:32 +0000166 MirSFieldLoweringInfo field_info(def->field_idx, def->type);
Vladimir Marko95a05972014-05-30 10:01:32 +0100167 // Mark even unresolved fields as initialized.
Vladimir Markoaf6925b2014-10-31 16:37:32 +0000168 field_info.flags_ |= MirSFieldLoweringInfo::kFlagClassIsInitialized;
Vladimir Marko66c6d7b2014-10-16 15:41:48 +0100169 // NOTE: MirSFieldLoweringInfo::kFlagClassIsInDexCache isn't used by GVN.
Vladimir Marko95a05972014-05-30 10:01:32 +0100170 if (def->declaring_dex_file != 0u) {
171 field_info.declaring_dex_file_ = reinterpret_cast<const DexFile*>(def->declaring_dex_file);
172 field_info.declaring_field_idx_ = def->declaring_field_idx;
Vladimir Markoaf6925b2014-10-31 16:37:32 +0000173 field_info.flags_ &= ~(def->is_volatile ? 0u : MirSFieldLoweringInfo::kFlagIsVolatile);
Vladimir Marko95a05972014-05-30 10:01:32 +0100174 }
Vladimir Markoe39c54e2014-09-22 14:50:02 +0100175 cu_.mir_graph->sfield_lowering_infos_.push_back(field_info);
Vladimir Marko95a05972014-05-30 10:01:32 +0100176 }
177 }
178
179 template <size_t count>
180 void PrepareSFields(const SFieldDef (&defs)[count]) {
181 DoPrepareSFields(defs, count);
182 }
183
184 void DoPrepareBasicBlocks(const BBDef* defs, size_t count) {
185 cu_.mir_graph->block_id_map_.clear();
Vladimir Markoe39c54e2014-09-22 14:50:02 +0100186 cu_.mir_graph->block_list_.clear();
Vladimir Marko95a05972014-05-30 10:01:32 +0100187 ASSERT_LT(3u, count); // null, entry, exit and at least one bytecode block.
188 ASSERT_EQ(kNullBlock, defs[0].type);
189 ASSERT_EQ(kEntryBlock, defs[1].type);
190 ASSERT_EQ(kExitBlock, defs[2].type);
191 for (size_t i = 0u; i != count; ++i) {
192 const BBDef* def = &defs[i];
Vladimir Markoe39c54e2014-09-22 14:50:02 +0100193 BasicBlock* bb = cu_.mir_graph->CreateNewBB(def->type);
Vladimir Marko95a05972014-05-30 10:01:32 +0100194 if (def->num_successors <= 2) {
195 bb->successor_block_list_type = kNotUsed;
Vladimir Marko95a05972014-05-30 10:01:32 +0100196 bb->fall_through = (def->num_successors >= 1) ? def->successors[0] : 0u;
197 bb->taken = (def->num_successors >= 2) ? def->successors[1] : 0u;
198 } else {
199 bb->successor_block_list_type = kPackedSwitch;
200 bb->fall_through = 0u;
201 bb->taken = 0u;
Vladimir Markoe39c54e2014-09-22 14:50:02 +0100202 bb->successor_blocks.reserve(def->num_successors);
Vladimir Marko95a05972014-05-30 10:01:32 +0100203 for (size_t j = 0u; j != def->num_successors; ++j) {
204 SuccessorBlockInfo* successor_block_info =
205 static_cast<SuccessorBlockInfo*>(cu_.arena.Alloc(sizeof(SuccessorBlockInfo),
206 kArenaAllocSuccessor));
207 successor_block_info->block = j;
208 successor_block_info->key = 0u; // Not used by class init check elimination.
Vladimir Markoe39c54e2014-09-22 14:50:02 +0100209 bb->successor_blocks.push_back(successor_block_info);
Vladimir Marko95a05972014-05-30 10:01:32 +0100210 }
211 }
Vladimir Markoe39c54e2014-09-22 14:50:02 +0100212 bb->predecessors.assign(def->predecessors, def->predecessors + def->num_predecessors);
Vladimir Marko95a05972014-05-30 10:01:32 +0100213 if (def->type == kDalvikByteCode || def->type == kEntryBlock || def->type == kExitBlock) {
214 bb->data_flow_info = static_cast<BasicBlockDataFlow*>(
215 cu_.arena.Alloc(sizeof(BasicBlockDataFlow), kArenaAllocDFInfo));
Vladimir Markob19955d2014-07-29 12:04:10 +0100216 bb->data_flow_info->live_in_v = live_in_v_;
Vladimir Marko95a05972014-05-30 10:01:32 +0100217 }
218 }
Vladimir Markoe39c54e2014-09-22 14:50:02 +0100219 ASSERT_EQ(count, cu_.mir_graph->block_list_.size());
220 cu_.mir_graph->entry_block_ = cu_.mir_graph->block_list_[1];
Vladimir Marko95a05972014-05-30 10:01:32 +0100221 ASSERT_EQ(kEntryBlock, cu_.mir_graph->entry_block_->block_type);
Vladimir Markoe39c54e2014-09-22 14:50:02 +0100222 cu_.mir_graph->exit_block_ = cu_.mir_graph->block_list_[2];
Vladimir Marko95a05972014-05-30 10:01:32 +0100223 ASSERT_EQ(kExitBlock, cu_.mir_graph->exit_block_->block_type);
224 }
225
226 template <size_t count>
227 void PrepareBasicBlocks(const BBDef (&defs)[count]) {
228 DoPrepareBasicBlocks(defs, count);
229 }
230
231 void DoPrepareMIRs(const MIRDef* defs, size_t count) {
232 mir_count_ = count;
Vladimir Markoe4fcc5b2015-02-13 10:28:29 +0000233 mirs_ = cu_.arena.AllocArray<MIR>(count, kArenaAllocMIR);
Vladimir Marko95a05972014-05-30 10:01:32 +0100234 ssa_reps_.resize(count);
235 for (size_t i = 0u; i != count; ++i) {
236 const MIRDef* def = &defs[i];
237 MIR* mir = &mirs_[i];
Vladimir Markoe39c54e2014-09-22 14:50:02 +0100238 ASSERT_LT(def->bbid, cu_.mir_graph->block_list_.size());
239 BasicBlock* bb = cu_.mir_graph->block_list_[def->bbid];
Vladimir Marko95a05972014-05-30 10:01:32 +0100240 bb->AppendMIR(mir);
241 mir->dalvikInsn.opcode = def->opcode;
242 mir->dalvikInsn.vB = static_cast<int32_t>(def->value);
243 mir->dalvikInsn.vB_wide = def->value;
Vladimir Markoaf6925b2014-10-31 16:37:32 +0000244 if (IsInstructionIGetOrIPut(def->opcode)) {
Vladimir Markoe39c54e2014-09-22 14:50:02 +0100245 ASSERT_LT(def->field_info, cu_.mir_graph->ifield_lowering_infos_.size());
Vladimir Marko95a05972014-05-30 10:01:32 +0100246 mir->meta.ifield_lowering_info = def->field_info;
Vladimir Markoaf6925b2014-10-31 16:37:32 +0000247 ASSERT_EQ(cu_.mir_graph->ifield_lowering_infos_[def->field_info].MemAccessType(),
248 IGetOrIPutMemAccessType(def->opcode));
249 } else if (IsInstructionSGetOrSPut(def->opcode)) {
Vladimir Markoe39c54e2014-09-22 14:50:02 +0100250 ASSERT_LT(def->field_info, cu_.mir_graph->sfield_lowering_infos_.size());
Vladimir Marko95a05972014-05-30 10:01:32 +0100251 mir->meta.sfield_lowering_info = def->field_info;
Vladimir Markoaf6925b2014-10-31 16:37:32 +0000252 ASSERT_EQ(cu_.mir_graph->sfield_lowering_infos_[def->field_info].MemAccessType(),
253 SGetOrSPutMemAccessType(def->opcode));
Vladimir Marko95a05972014-05-30 10:01:32 +0100254 } else if (def->opcode == static_cast<Instruction::Code>(kMirOpPhi)) {
Vladimir Markoe4fcc5b2015-02-13 10:28:29 +0000255 mir->meta.phi_incoming =
256 allocator_->AllocArray<BasicBlockId>(def->num_uses, kArenaAllocDFInfo);
Vladimir Markoe39c54e2014-09-22 14:50:02 +0100257 ASSERT_EQ(def->num_uses, bb->predecessors.size());
258 std::copy(bb->predecessors.begin(), bb->predecessors.end(), mir->meta.phi_incoming);
Vladimir Marko95a05972014-05-30 10:01:32 +0100259 }
260 mir->ssa_rep = &ssa_reps_[i];
261 mir->ssa_rep->num_uses = def->num_uses;
262 mir->ssa_rep->uses = const_cast<int32_t*>(def->uses); // Not modified by LVN.
263 mir->ssa_rep->fp_use = nullptr; // Not used by LVN.
264 mir->ssa_rep->num_defs = def->num_defs;
265 mir->ssa_rep->defs = const_cast<int32_t*>(def->defs); // Not modified by LVN.
266 mir->ssa_rep->fp_def = nullptr; // Not used by LVN.
267 mir->dalvikInsn.opcode = def->opcode;
268 mir->offset = i; // LVN uses offset only for debug output
269 mir->optimization_flags = 0u;
270 }
Razvan A Lupusoru8d0d03e2014-06-06 17:04:52 -0700271 DexFile::CodeItem* code_item = static_cast<DexFile::CodeItem*>(
272 cu_.arena.Alloc(sizeof(DexFile::CodeItem), kArenaAllocMisc));
273 code_item->insns_size_in_code_units_ = 2u * count;
Razvan A Lupusoru75035972014-09-11 15:24:59 -0700274 cu_.mir_graph->current_code_item_ = code_item;
Vladimir Marko95a05972014-05-30 10:01:32 +0100275 }
276
277 template <size_t count>
278 void PrepareMIRs(const MIRDef (&defs)[count]) {
279 DoPrepareMIRs(defs, count);
280 }
281
Vladimir Marko7a01dc22015-01-02 17:00:44 +0000282 void DoPrepareVregToSsaMapExit(BasicBlockId bb_id, const int32_t* map, size_t count) {
283 BasicBlock* bb = cu_.mir_graph->GetBasicBlock(bb_id);
284 ASSERT_TRUE(bb != nullptr);
285 ASSERT_TRUE(bb->data_flow_info != nullptr);
286 bb->data_flow_info->vreg_to_ssa_map_exit =
287 cu_.arena.AllocArray<int32_t>(count, kArenaAllocDFInfo);
288 std::copy_n(map, count, bb->data_flow_info->vreg_to_ssa_map_exit);
289 }
290
291 template <size_t count>
292 void PrepareVregToSsaMapExit(BasicBlockId bb_id, const int32_t (&map)[count]) {
293 DoPrepareVregToSsaMapExit(bb_id, map, count);
294 }
295
Vladimir Marko95a05972014-05-30 10:01:32 +0100296 void PerformGVN() {
Vladimir Marko55fff042014-07-10 12:42:52 +0100297 DoPerformGVN<LoopRepeatingTopologicalSortIterator>();
Vladimir Marko95a05972014-05-30 10:01:32 +0100298 }
299
300 void PerformPreOrderDfsGVN() {
Vladimir Marko95a05972014-05-30 10:01:32 +0100301 DoPerformGVN<RepeatingPreOrderDfsIterator>();
302 }
303
304 template <typename IteratorType>
305 void DoPerformGVN() {
Vladimir Marko55fff042014-07-10 12:42:52 +0100306 cu_.mir_graph->SSATransformationStart();
307 cu_.mir_graph->ComputeDFSOrders();
308 cu_.mir_graph->ComputeDominators();
309 cu_.mir_graph->ComputeTopologicalSortOrder();
310 cu_.mir_graph->SSATransformationEnd();
Vladimir Marko7a01dc22015-01-02 17:00:44 +0000311 cu_.mir_graph->temp_.gvn.ifield_ids = GlobalValueNumbering::PrepareGvnFieldIds(
Vladimir Markoaf6925b2014-10-31 16:37:32 +0000312 allocator_.get(), cu_.mir_graph->ifield_lowering_infos_);
Vladimir Marko7a01dc22015-01-02 17:00:44 +0000313 cu_.mir_graph->temp_.gvn.sfield_ids = GlobalValueNumbering::PrepareGvnFieldIds(
Vladimir Markoaf6925b2014-10-31 16:37:32 +0000314 allocator_.get(), cu_.mir_graph->sfield_lowering_infos_);
Vladimir Marko95a05972014-05-30 10:01:32 +0100315 ASSERT_TRUE(gvn_ == nullptr);
Vladimir Marko415ac882014-09-30 18:09:14 +0100316 gvn_.reset(new (allocator_.get()) GlobalValueNumbering(&cu_, allocator_.get(),
317 GlobalValueNumbering::kModeGvn));
Vladimir Marko95a05972014-05-30 10:01:32 +0100318 value_names_.resize(mir_count_, 0xffffu);
319 IteratorType iterator(cu_.mir_graph.get());
320 bool change = false;
321 for (BasicBlock* bb = iterator.Next(change); bb != nullptr; bb = iterator.Next(change)) {
322 LocalValueNumbering* lvn = gvn_->PrepareBasicBlock(bb);
323 if (lvn != nullptr) {
324 for (MIR* mir = bb->first_mir_insn; mir != nullptr; mir = mir->next) {
325 value_names_[mir - mirs_] = lvn->GetValueNumber(mir);
326 }
327 }
328 change = (lvn != nullptr) && gvn_->FinishBasicBlock(bb);
329 ASSERT_TRUE(gvn_->Good());
330 }
331 }
332
333 void PerformGVNCodeModifications() {
334 ASSERT_TRUE(gvn_ != nullptr);
335 ASSERT_TRUE(gvn_->Good());
Vladimir Marko415ac882014-09-30 18:09:14 +0100336 gvn_->StartPostProcessing();
Vladimir Marko55fff042014-07-10 12:42:52 +0100337 TopologicalSortIterator iterator(cu_.mir_graph.get());
Vladimir Marko95a05972014-05-30 10:01:32 +0100338 for (BasicBlock* bb = iterator.Next(); bb != nullptr; bb = iterator.Next()) {
339 LocalValueNumbering* lvn = gvn_->PrepareBasicBlock(bb);
340 if (lvn != nullptr) {
341 for (MIR* mir = bb->first_mir_insn; mir != nullptr; mir = mir->next) {
342 uint16_t value_name = lvn->GetValueNumber(mir);
343 ASSERT_EQ(value_name, value_names_[mir - mirs_]);
344 }
345 }
346 bool change = (lvn != nullptr) && gvn_->FinishBasicBlock(bb);
347 ASSERT_FALSE(change);
348 ASSERT_TRUE(gvn_->Good());
349 }
350 }
351
352 GlobalValueNumberingTest()
353 : pool_(),
Andreas Gampe0b9203e2015-01-22 20:39:27 -0800354 cu_(&pool_, kRuntimeISA, nullptr, nullptr),
Vladimir Marko95a05972014-05-30 10:01:32 +0100355 mir_count_(0u),
356 mirs_(nullptr),
357 ssa_reps_(),
358 allocator_(),
359 gvn_(),
Vladimir Markob19955d2014-07-29 12:04:10 +0100360 value_names_(),
361 live_in_v_(new (&cu_.arena) ArenaBitVector(&cu_.arena, kMaxSsaRegs, false, kBitMapMisc)) {
Vladimir Marko95a05972014-05-30 10:01:32 +0100362 cu_.mir_graph.reset(new MIRGraph(&cu_, &cu_.arena));
363 cu_.access_flags = kAccStatic; // Don't let "this" interfere with this test.
364 allocator_.reset(ScopedArenaAllocator::Create(&cu_.arena_stack));
Vladimir Marko7a01dc22015-01-02 17:00:44 +0000365 // By default, the zero-initialized reg_location_[.] with ref == false tells LVN that
366 // 0 constants are integral, not references. Nothing else is used by LVN/GVN.
367 cu_.mir_graph->reg_location_ =
368 cu_.arena.AllocArray<RegLocation>(kMaxSsaRegs, kArenaAllocRegAlloc);
Vladimir Markob19955d2014-07-29 12:04:10 +0100369 // Bind all possible sregs to live vregs for test purposes.
370 live_in_v_->SetInitialBits(kMaxSsaRegs);
Vladimir Markoe39c54e2014-09-22 14:50:02 +0100371 cu_.mir_graph->ssa_base_vregs_.reserve(kMaxSsaRegs);
372 cu_.mir_graph->ssa_subscripts_.reserve(kMaxSsaRegs);
Vladimir Markob19955d2014-07-29 12:04:10 +0100373 for (unsigned int i = 0; i < kMaxSsaRegs; i++) {
Vladimir Markoe39c54e2014-09-22 14:50:02 +0100374 cu_.mir_graph->ssa_base_vregs_.push_back(i);
375 cu_.mir_graph->ssa_subscripts_.push_back(0);
Vladimir Markob19955d2014-07-29 12:04:10 +0100376 }
Vladimir Markoa4426cf2014-10-22 17:15:53 +0100377 // Set shorty for a void-returning method without arguments.
378 cu_.shorty = "V";
Vladimir Marko95a05972014-05-30 10:01:32 +0100379 }
380
Vladimir Markob19955d2014-07-29 12:04:10 +0100381 static constexpr size_t kMaxSsaRegs = 16384u;
382
Vladimir Marko95a05972014-05-30 10:01:32 +0100383 ArenaPool pool_;
384 CompilationUnit cu_;
385 size_t mir_count_;
386 MIR* mirs_;
387 std::vector<SSARepresentation> ssa_reps_;
388 std::unique_ptr<ScopedArenaAllocator> allocator_;
389 std::unique_ptr<GlobalValueNumbering> gvn_;
390 std::vector<uint16_t> value_names_;
Vladimir Markob19955d2014-07-29 12:04:10 +0100391 ArenaBitVector* live_in_v_;
Vladimir Marko95a05972014-05-30 10:01:32 +0100392};
393
Vladimir Markoa4426cf2014-10-22 17:15:53 +0100394constexpr uint16_t GlobalValueNumberingTest::kNoValue;
395
Vladimir Marko95a05972014-05-30 10:01:32 +0100396class GlobalValueNumberingTestDiamond : public GlobalValueNumberingTest {
397 public:
398 GlobalValueNumberingTestDiamond();
399
400 private:
401 static const BBDef kDiamondBbs[];
402};
403
404const GlobalValueNumberingTest::BBDef GlobalValueNumberingTestDiamond::kDiamondBbs[] = {
405 DEF_BB(kNullBlock, DEF_SUCC0(), DEF_PRED0()),
406 DEF_BB(kEntryBlock, DEF_SUCC1(3), DEF_PRED0()),
407 DEF_BB(kExitBlock, DEF_SUCC0(), DEF_PRED1(6)),
408 DEF_BB(kDalvikByteCode, DEF_SUCC2(4, 5), DEF_PRED1(1)), // Block #3, top of the diamond.
409 DEF_BB(kDalvikByteCode, DEF_SUCC1(6), DEF_PRED1(3)), // Block #4, left side.
410 DEF_BB(kDalvikByteCode, DEF_SUCC1(6), DEF_PRED1(3)), // Block #5, right side.
411 DEF_BB(kDalvikByteCode, DEF_SUCC1(2), DEF_PRED2(4, 5)), // Block #6, bottom.
412};
413
414GlobalValueNumberingTestDiamond::GlobalValueNumberingTestDiamond()
415 : GlobalValueNumberingTest() {
416 PrepareBasicBlocks(kDiamondBbs);
417}
418
419class GlobalValueNumberingTestLoop : public GlobalValueNumberingTest {
420 public:
421 GlobalValueNumberingTestLoop();
422
423 private:
424 static const BBDef kLoopBbs[];
425};
426
427const GlobalValueNumberingTest::BBDef GlobalValueNumberingTestLoop::kLoopBbs[] = {
428 DEF_BB(kNullBlock, DEF_SUCC0(), DEF_PRED0()),
429 DEF_BB(kEntryBlock, DEF_SUCC1(3), DEF_PRED0()),
430 DEF_BB(kExitBlock, DEF_SUCC0(), DEF_PRED1(5)),
431 DEF_BB(kDalvikByteCode, DEF_SUCC1(4), DEF_PRED1(1)),
432 DEF_BB(kDalvikByteCode, DEF_SUCC2(5, 4), DEF_PRED2(3, 4)), // "taken" loops to self.
433 DEF_BB(kDalvikByteCode, DEF_SUCC1(2), DEF_PRED1(4)),
434};
435
436GlobalValueNumberingTestLoop::GlobalValueNumberingTestLoop()
437 : GlobalValueNumberingTest() {
438 PrepareBasicBlocks(kLoopBbs);
439}
440
441class GlobalValueNumberingTestCatch : public GlobalValueNumberingTest {
442 public:
443 GlobalValueNumberingTestCatch();
444
445 private:
446 static const BBDef kCatchBbs[];
447};
448
449const GlobalValueNumberingTest::BBDef GlobalValueNumberingTestCatch::kCatchBbs[] = {
450 DEF_BB(kNullBlock, DEF_SUCC0(), DEF_PRED0()),
451 DEF_BB(kEntryBlock, DEF_SUCC1(3), DEF_PRED0()),
452 DEF_BB(kExitBlock, DEF_SUCC0(), DEF_PRED1(6)),
453 DEF_BB(kDalvikByteCode, DEF_SUCC1(4), DEF_PRED1(1)), // The top.
454 DEF_BB(kDalvikByteCode, DEF_SUCC1(6), DEF_PRED1(3)), // The throwing insn.
455 DEF_BB(kDalvikByteCode, DEF_SUCC1(6), DEF_PRED1(3)), // Catch handler.
456 DEF_BB(kDalvikByteCode, DEF_SUCC1(2), DEF_PRED2(4, 5)), // The merged block.
457};
458
459GlobalValueNumberingTestCatch::GlobalValueNumberingTestCatch()
460 : GlobalValueNumberingTest() {
461 PrepareBasicBlocks(kCatchBbs);
462 // Mark catch handler.
463 BasicBlock* catch_handler = cu_.mir_graph->GetBasicBlock(5u);
464 catch_handler->catch_entry = true;
465 // Add successor block info to the check block.
466 BasicBlock* check_bb = cu_.mir_graph->GetBasicBlock(3u);
467 check_bb->successor_block_list_type = kCatch;
Vladimir Marko95a05972014-05-30 10:01:32 +0100468 SuccessorBlockInfo* successor_block_info = reinterpret_cast<SuccessorBlockInfo*>
469 (cu_.arena.Alloc(sizeof(SuccessorBlockInfo), kArenaAllocSuccessor));
470 successor_block_info->block = catch_handler->id;
Vladimir Markoe39c54e2014-09-22 14:50:02 +0100471 check_bb->successor_blocks.push_back(successor_block_info);
Vladimir Marko95a05972014-05-30 10:01:32 +0100472}
473
474class GlobalValueNumberingTestTwoConsecutiveLoops : public GlobalValueNumberingTest {
475 public:
476 GlobalValueNumberingTestTwoConsecutiveLoops();
477
478 private:
479 static const BBDef kTwoConsecutiveLoopsBbs[];
480};
481
482const GlobalValueNumberingTest::BBDef
483GlobalValueNumberingTestTwoConsecutiveLoops::kTwoConsecutiveLoopsBbs[] = {
484 DEF_BB(kNullBlock, DEF_SUCC0(), DEF_PRED0()),
485 DEF_BB(kEntryBlock, DEF_SUCC1(3), DEF_PRED0()),
486 DEF_BB(kExitBlock, DEF_SUCC0(), DEF_PRED1(9)),
487 DEF_BB(kDalvikByteCode, DEF_SUCC1(4), DEF_PRED1(1)),
488 DEF_BB(kDalvikByteCode, DEF_SUCC2(5, 6), DEF_PRED2(3, 5)), // "taken" skips over the loop.
489 DEF_BB(kDalvikByteCode, DEF_SUCC1(4), DEF_PRED1(4)),
490 DEF_BB(kDalvikByteCode, DEF_SUCC1(7), DEF_PRED1(4)),
491 DEF_BB(kDalvikByteCode, DEF_SUCC2(8, 9), DEF_PRED2(6, 8)), // "taken" skips over the loop.
492 DEF_BB(kDalvikByteCode, DEF_SUCC1(7), DEF_PRED1(7)),
493 DEF_BB(kDalvikByteCode, DEF_SUCC1(2), DEF_PRED1(7)),
494};
495
496GlobalValueNumberingTestTwoConsecutiveLoops::GlobalValueNumberingTestTwoConsecutiveLoops()
497 : GlobalValueNumberingTest() {
498 PrepareBasicBlocks(kTwoConsecutiveLoopsBbs);
499}
500
501class GlobalValueNumberingTestTwoNestedLoops : public GlobalValueNumberingTest {
502 public:
503 GlobalValueNumberingTestTwoNestedLoops();
504
505 private:
506 static const BBDef kTwoNestedLoopsBbs[];
507};
508
509const GlobalValueNumberingTest::BBDef
510GlobalValueNumberingTestTwoNestedLoops::kTwoNestedLoopsBbs[] = {
511 DEF_BB(kNullBlock, DEF_SUCC0(), DEF_PRED0()),
512 DEF_BB(kEntryBlock, DEF_SUCC1(3), DEF_PRED0()),
513 DEF_BB(kExitBlock, DEF_SUCC0(), DEF_PRED1(8)),
514 DEF_BB(kDalvikByteCode, DEF_SUCC1(4), DEF_PRED1(1)),
515 DEF_BB(kDalvikByteCode, DEF_SUCC2(5, 8), DEF_PRED2(3, 7)), // "taken" skips over the loop.
516 DEF_BB(kDalvikByteCode, DEF_SUCC2(6, 7), DEF_PRED2(4, 6)), // "taken" skips over the loop.
517 DEF_BB(kDalvikByteCode, DEF_SUCC1(5), DEF_PRED1(5)),
518 DEF_BB(kDalvikByteCode, DEF_SUCC1(4), DEF_PRED1(5)),
519 DEF_BB(kDalvikByteCode, DEF_SUCC1(2), DEF_PRED1(4)),
520};
521
522GlobalValueNumberingTestTwoNestedLoops::GlobalValueNumberingTestTwoNestedLoops()
523 : GlobalValueNumberingTest() {
524 PrepareBasicBlocks(kTwoNestedLoopsBbs);
525}
526
527TEST_F(GlobalValueNumberingTestDiamond, NonAliasingIFields) {
528 static const IFieldDef ifields[] = {
Vladimir Markoaf6925b2014-10-31 16:37:32 +0000529 { 0u, 1u, 0u, false, kDexMemAccessWord },
530 { 1u, 1u, 1u, false, kDexMemAccessWord },
531 { 2u, 1u, 2u, false, kDexMemAccessWord },
532 { 3u, 1u, 3u, false, kDexMemAccessWord },
533 { 4u, 1u, 4u, false, kDexMemAccessShort },
534 { 5u, 1u, 5u, false, kDexMemAccessChar },
535 { 6u, 0u, 0u, false, kDexMemAccessShort }, // Unresolved.
536 { 7u, 1u, 7u, false, kDexMemAccessWord },
537 { 8u, 0u, 0u, false, kDexMemAccessWord }, // Unresolved.
538 { 9u, 1u, 9u, false, kDexMemAccessWord },
539 { 10u, 1u, 10u, false, kDexMemAccessWord },
540 { 11u, 1u, 11u, false, kDexMemAccessWord },
Vladimir Marko95a05972014-05-30 10:01:32 +0100541 };
542 static const MIRDef mirs[] = {
543 // NOTE: MIRs here are ordered by unique tests. They will be put into appropriate blocks.
544 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 100u),
545 DEF_IGET(3, Instruction::IGET, 1u, 100u, 0u),
546 DEF_IGET(6, Instruction::IGET, 2u, 100u, 0u), // Same as at the top.
547
548 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 200u),
549 DEF_IGET(4, Instruction::IGET, 4u, 200u, 1u),
550 DEF_IGET(6, Instruction::IGET, 5u, 200u, 1u), // Same as at the left side.
551
552 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 300u),
553 DEF_IGET(3, Instruction::IGET, 7u, 300u, 2u),
554 DEF_CONST(5, Instruction::CONST, 8u, 1000),
555 DEF_IPUT(5, Instruction::IPUT, 8u, 300u, 2u),
556 DEF_IGET(6, Instruction::IGET, 10u, 300u, 2u), // Differs from the top and the CONST.
557
558 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 400u),
559 DEF_IGET(3, Instruction::IGET, 12u, 400u, 3u),
560 DEF_CONST(3, Instruction::CONST, 13u, 2000),
561 DEF_IPUT(4, Instruction::IPUT, 13u, 400u, 3u),
562 DEF_IPUT(5, Instruction::IPUT, 13u, 400u, 3u),
563 DEF_IGET(6, Instruction::IGET, 16u, 400u, 3u), // Differs from the top, equals the CONST.
564
565 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 500u),
566 DEF_IGET(3, Instruction::IGET_SHORT, 18u, 500u, 4u),
567 DEF_IGET(3, Instruction::IGET_CHAR, 19u, 500u, 5u),
568 DEF_IPUT(4, Instruction::IPUT_SHORT, 20u, 500u, 6u), // Clobbers field #4, not #5.
569 DEF_IGET(6, Instruction::IGET_SHORT, 21u, 500u, 4u), // Differs from the top.
570 DEF_IGET(6, Instruction::IGET_CHAR, 22u, 500u, 5u), // Same as the top.
571
572 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 600u),
573 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 601u),
574 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 602u),
575 DEF_IGET(3, Instruction::IGET, 26u, 600u, 7u),
576 DEF_IGET(3, Instruction::IGET, 27u, 601u, 7u),
577 DEF_IPUT(4, Instruction::IPUT, 28u, 602u, 8u), // Doesn't clobber field #7 for other refs.
578 DEF_IGET(6, Instruction::IGET, 29u, 600u, 7u), // Same as the top.
579 DEF_IGET(6, Instruction::IGET, 30u, 601u, 7u), // Same as the top.
580
581 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 700u),
582 DEF_CONST(4, Instruction::CONST, 32u, 3000),
583 DEF_IPUT(4, Instruction::IPUT, 32u, 700u, 9u),
584 DEF_IPUT(4, Instruction::IPUT, 32u, 700u, 10u),
585 DEF_CONST(5, Instruction::CONST, 35u, 3001),
586 DEF_IPUT(5, Instruction::IPUT, 35u, 700u, 9u),
587 DEF_IPUT(5, Instruction::IPUT, 35u, 700u, 10u),
588 DEF_IGET(6, Instruction::IGET, 38u, 700u, 9u),
589 DEF_IGET(6, Instruction::IGET, 39u, 700u, 10u), // Same value as read from field #9.
590
591 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 800u),
592 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 801u),
593 DEF_CONST(4, Instruction::CONST, 42u, 3000),
594 DEF_IPUT(4, Instruction::IPUT, 42u, 800u, 11u),
595 DEF_IPUT(4, Instruction::IPUT, 42u, 801u, 11u),
596 DEF_CONST(5, Instruction::CONST, 45u, 3001),
597 DEF_IPUT(5, Instruction::IPUT, 45u, 800u, 11u),
598 DEF_IPUT(5, Instruction::IPUT, 45u, 801u, 11u),
599 DEF_IGET(6, Instruction::IGET, 48u, 800u, 11u),
600 DEF_IGET(6, Instruction::IGET, 49u, 801u, 11u), // Same value as read from ref 46u.
601
602 // Invoke doesn't interfere with non-aliasing refs. There's one test above where a reference
603 // escapes in the left BB (we let a reference escape if we use it to store to an unresolved
604 // field) and the INVOKE in the right BB shouldn't interfere with that either.
605 DEF_INVOKE1(5, Instruction::INVOKE_STATIC, 48u),
606 };
607
608 PrepareIFields(ifields);
609 PrepareMIRs(mirs);
610 PerformGVN();
611 ASSERT_EQ(arraysize(mirs), value_names_.size());
612 EXPECT_EQ(value_names_[1], value_names_[2]);
613
614 EXPECT_EQ(value_names_[4], value_names_[5]);
615
616 EXPECT_NE(value_names_[7], value_names_[10]);
617 EXPECT_NE(value_names_[8], value_names_[10]);
618
619 EXPECT_NE(value_names_[12], value_names_[16]);
620 EXPECT_EQ(value_names_[13], value_names_[16]);
621
622 EXPECT_NE(value_names_[18], value_names_[21]);
623 EXPECT_EQ(value_names_[19], value_names_[22]);
624
625 EXPECT_EQ(value_names_[26], value_names_[29]);
626 EXPECT_EQ(value_names_[27], value_names_[30]);
627
628 EXPECT_EQ(value_names_[38], value_names_[39]);
629
630 EXPECT_EQ(value_names_[48], value_names_[49]);
631}
632
633TEST_F(GlobalValueNumberingTestDiamond, AliasingIFieldsSingleObject) {
634 static const IFieldDef ifields[] = {
Vladimir Markoaf6925b2014-10-31 16:37:32 +0000635 { 0u, 1u, 0u, false, kDexMemAccessWord },
636 { 1u, 1u, 1u, false, kDexMemAccessWord },
637 { 2u, 1u, 2u, false, kDexMemAccessWord },
638 { 3u, 1u, 3u, false, kDexMemAccessWord },
639 { 4u, 1u, 4u, false, kDexMemAccessShort },
640 { 5u, 1u, 5u, false, kDexMemAccessChar },
641 { 6u, 0u, 0u, false, kDexMemAccessShort }, // Unresolved.
642 { 7u, 1u, 7u, false, kDexMemAccessWord },
643 { 8u, 1u, 8u, false, kDexMemAccessWord },
Vladimir Marko95a05972014-05-30 10:01:32 +0100644 };
645 static const MIRDef mirs[] = {
646 // NOTE: MIRs here are ordered by unique tests. They will be put into appropriate blocks.
647 DEF_IGET(3, Instruction::IGET, 0u, 100u, 0u),
648 DEF_IGET(6, Instruction::IGET, 1u, 100u, 0u), // Same as at the top.
649
650 DEF_IGET(4, Instruction::IGET, 2u, 100u, 1u),
651 DEF_IGET(6, Instruction::IGET, 3u, 100u, 1u), // Same as at the left side.
652
653 DEF_IGET(3, Instruction::IGET, 4u, 100u, 2u),
654 DEF_CONST(5, Instruction::CONST, 5u, 1000),
655 DEF_IPUT(5, Instruction::IPUT, 5u, 100u, 2u),
656 DEF_IGET(6, Instruction::IGET, 7u, 100u, 2u), // Differs from the top and the CONST.
657
658 DEF_IGET(3, Instruction::IGET, 8u, 100u, 3u),
659 DEF_CONST(3, Instruction::CONST, 9u, 2000),
660 DEF_IPUT(4, Instruction::IPUT, 9u, 100u, 3u),
661 DEF_IPUT(5, Instruction::IPUT, 9u, 100u, 3u),
662 DEF_IGET(6, Instruction::IGET, 12u, 100u, 3u), // Differs from the top, equals the CONST.
663
664 DEF_IGET(3, Instruction::IGET_SHORT, 13u, 100u, 4u),
665 DEF_IGET(3, Instruction::IGET_CHAR, 14u, 100u, 5u),
666 DEF_IPUT(4, Instruction::IPUT_SHORT, 15u, 100u, 6u), // Clobbers field #4, not #5.
667 DEF_IGET(6, Instruction::IGET_SHORT, 16u, 100u, 4u), // Differs from the top.
668 DEF_IGET(6, Instruction::IGET_CHAR, 17u, 100u, 5u), // Same as the top.
669
670 DEF_CONST(4, Instruction::CONST, 18u, 3000),
671 DEF_IPUT(4, Instruction::IPUT, 18u, 100u, 7u),
672 DEF_IPUT(4, Instruction::IPUT, 18u, 100u, 8u),
673 DEF_CONST(5, Instruction::CONST, 21u, 3001),
674 DEF_IPUT(5, Instruction::IPUT, 21u, 100u, 7u),
675 DEF_IPUT(5, Instruction::IPUT, 21u, 100u, 8u),
676 DEF_IGET(6, Instruction::IGET, 24u, 100u, 7u),
677 DEF_IGET(6, Instruction::IGET, 25u, 100u, 8u), // Same value as read from field #7.
678 };
679
680 PrepareIFields(ifields);
681 PrepareMIRs(mirs);
682 PerformGVN();
683 ASSERT_EQ(arraysize(mirs), value_names_.size());
684 EXPECT_EQ(value_names_[0], value_names_[1]);
685
686 EXPECT_EQ(value_names_[2], value_names_[3]);
687
688 EXPECT_NE(value_names_[4], value_names_[7]);
689 EXPECT_NE(value_names_[5], value_names_[7]);
690
691 EXPECT_NE(value_names_[8], value_names_[12]);
692 EXPECT_EQ(value_names_[9], value_names_[12]);
693
694 EXPECT_NE(value_names_[13], value_names_[16]);
695 EXPECT_EQ(value_names_[14], value_names_[17]);
696
697 EXPECT_EQ(value_names_[24], value_names_[25]);
698}
699
700TEST_F(GlobalValueNumberingTestDiamond, AliasingIFieldsTwoObjects) {
701 static const IFieldDef ifields[] = {
Vladimir Markoaf6925b2014-10-31 16:37:32 +0000702 { 0u, 1u, 0u, false, kDexMemAccessWord },
703 { 1u, 1u, 1u, false, kDexMemAccessWord },
704 { 2u, 1u, 2u, false, kDexMemAccessWord },
705 { 3u, 1u, 3u, false, kDexMemAccessWord },
706 { 4u, 1u, 4u, false, kDexMemAccessShort },
707 { 5u, 1u, 5u, false, kDexMemAccessChar },
708 { 6u, 0u, 0u, false, kDexMemAccessShort }, // Unresolved.
709 { 7u, 1u, 7u, false, kDexMemAccessWord },
710 { 8u, 1u, 8u, false, kDexMemAccessWord },
Vladimir Marko95a05972014-05-30 10:01:32 +0100711 };
712 static const MIRDef mirs[] = {
713 // NOTE: MIRs here are ordered by unique tests. They will be put into appropriate blocks.
714 DEF_IGET(3, Instruction::IGET, 0u, 100u, 0u),
715 DEF_IPUT(4, Instruction::IPUT, 1u, 101u, 0u), // May alias with the IGET at the top.
716 DEF_IGET(6, Instruction::IGET, 2u, 100u, 0u), // Differs from the top.
717
718 DEF_IGET(3, Instruction::IGET, 3u, 100u, 1u),
719 DEF_IPUT(5, Instruction::IPUT, 3u, 101u, 1u), // If aliasing, stores the same value.
720 DEF_IGET(6, Instruction::IGET, 5u, 100u, 1u), // Same as the top.
721
722 DEF_IGET(3, Instruction::IGET, 6u, 100u, 2u),
723 DEF_CONST(5, Instruction::CONST, 7u, 1000),
724 DEF_IPUT(5, Instruction::IPUT, 7u, 101u, 2u),
725 DEF_IGET(6, Instruction::IGET, 9u, 100u, 2u), // Differs from the top and the CONST.
726
727 DEF_IGET(3, Instruction::IGET, 10u, 100u, 3u),
728 DEF_CONST(3, Instruction::CONST, 11u, 2000),
729 DEF_IPUT(4, Instruction::IPUT, 11u, 101u, 3u),
730 DEF_IPUT(5, Instruction::IPUT, 11u, 101u, 3u),
731 DEF_IGET(6, Instruction::IGET, 14u, 100u, 3u), // Differs from the top and the CONST.
732
733 DEF_IGET(3, Instruction::IGET_SHORT, 15u, 100u, 4u),
734 DEF_IGET(3, Instruction::IGET_CHAR, 16u, 100u, 5u),
735 DEF_IPUT(4, Instruction::IPUT_SHORT, 17u, 101u, 6u), // Clobbers field #4, not #5.
736 DEF_IGET(6, Instruction::IGET_SHORT, 18u, 100u, 4u), // Differs from the top.
737 DEF_IGET(6, Instruction::IGET_CHAR, 19u, 100u, 5u), // Same as the top.
738
739 DEF_CONST(4, Instruction::CONST, 20u, 3000),
740 DEF_IPUT(4, Instruction::IPUT, 20u, 100u, 7u),
741 DEF_IPUT(4, Instruction::IPUT, 20u, 101u, 8u),
742 DEF_CONST(5, Instruction::CONST, 23u, 3001),
743 DEF_IPUT(5, Instruction::IPUT, 23u, 100u, 7u),
744 DEF_IPUT(5, Instruction::IPUT, 23u, 101u, 8u),
745 DEF_IGET(6, Instruction::IGET, 26u, 100u, 7u),
746 DEF_IGET(6, Instruction::IGET, 27u, 101u, 8u), // Same value as read from field #7.
747 };
748
749 PrepareIFields(ifields);
750 PrepareMIRs(mirs);
751 PerformGVN();
752 ASSERT_EQ(arraysize(mirs), value_names_.size());
753 EXPECT_NE(value_names_[0], value_names_[2]);
754
755 EXPECT_EQ(value_names_[3], value_names_[5]);
756
757 EXPECT_NE(value_names_[6], value_names_[9]);
758 EXPECT_NE(value_names_[7], value_names_[9]);
759
760 EXPECT_NE(value_names_[10], value_names_[14]);
761 EXPECT_NE(value_names_[10], value_names_[14]);
762
763 EXPECT_NE(value_names_[15], value_names_[18]);
764 EXPECT_EQ(value_names_[16], value_names_[19]);
765
766 EXPECT_EQ(value_names_[26], value_names_[27]);
767}
768
769TEST_F(GlobalValueNumberingTestDiamond, SFields) {
770 static const SFieldDef sfields[] = {
Vladimir Markoaf6925b2014-10-31 16:37:32 +0000771 { 0u, 1u, 0u, false, kDexMemAccessWord },
772 { 1u, 1u, 1u, false, kDexMemAccessWord },
773 { 2u, 1u, 2u, false, kDexMemAccessWord },
774 { 3u, 1u, 3u, false, kDexMemAccessWord },
775 { 4u, 1u, 4u, false, kDexMemAccessShort },
776 { 5u, 1u, 5u, false, kDexMemAccessChar },
777 { 6u, 0u, 0u, false, kDexMemAccessShort }, // Unresolved.
778 { 7u, 1u, 7u, false, kDexMemAccessWord },
779 { 8u, 1u, 8u, false, kDexMemAccessWord },
Vladimir Marko95a05972014-05-30 10:01:32 +0100780 };
781 static const MIRDef mirs[] = {
782 // NOTE: MIRs here are ordered by unique tests. They will be put into appropriate blocks.
783 DEF_SGET(3, Instruction::SGET, 0u, 0u),
784 DEF_SGET(6, Instruction::SGET, 1u, 0u), // Same as at the top.
785
786 DEF_SGET(4, Instruction::SGET, 2u, 1u),
787 DEF_SGET(6, Instruction::SGET, 3u, 1u), // Same as at the left side.
788
789 DEF_SGET(3, Instruction::SGET, 4u, 2u),
790 DEF_CONST(5, Instruction::CONST, 5u, 100),
791 DEF_SPUT(5, Instruction::SPUT, 5u, 2u),
792 DEF_SGET(6, Instruction::SGET, 7u, 2u), // Differs from the top and the CONST.
793
794 DEF_SGET(3, Instruction::SGET, 8u, 3u),
795 DEF_CONST(3, Instruction::CONST, 9u, 200),
796 DEF_SPUT(4, Instruction::SPUT, 9u, 3u),
797 DEF_SPUT(5, Instruction::SPUT, 9u, 3u),
798 DEF_SGET(6, Instruction::SGET, 12u, 3u), // Differs from the top, equals the CONST.
799
800 DEF_SGET(3, Instruction::SGET_SHORT, 13u, 4u),
801 DEF_SGET(3, Instruction::SGET_CHAR, 14u, 5u),
802 DEF_SPUT(4, Instruction::SPUT_SHORT, 15u, 6u), // Clobbers field #4, not #5.
803 DEF_SGET(6, Instruction::SGET_SHORT, 16u, 4u), // Differs from the top.
804 DEF_SGET(6, Instruction::SGET_CHAR, 17u, 5u), // Same as the top.
805
806 DEF_CONST(4, Instruction::CONST, 18u, 300),
807 DEF_SPUT(4, Instruction::SPUT, 18u, 7u),
808 DEF_SPUT(4, Instruction::SPUT, 18u, 8u),
809 DEF_CONST(5, Instruction::CONST, 21u, 301),
810 DEF_SPUT(5, Instruction::SPUT, 21u, 7u),
811 DEF_SPUT(5, Instruction::SPUT, 21u, 8u),
812 DEF_SGET(6, Instruction::SGET, 24u, 7u),
813 DEF_SGET(6, Instruction::SGET, 25u, 8u), // Same value as read from field #7.
814 };
815
816 PrepareSFields(sfields);
817 PrepareMIRs(mirs);
818 PerformGVN();
819 ASSERT_EQ(arraysize(mirs), value_names_.size());
820 EXPECT_EQ(value_names_[0], value_names_[1]);
821
822 EXPECT_EQ(value_names_[2], value_names_[3]);
823
824 EXPECT_NE(value_names_[4], value_names_[7]);
825 EXPECT_NE(value_names_[5], value_names_[7]);
826
827 EXPECT_NE(value_names_[8], value_names_[12]);
828 EXPECT_EQ(value_names_[9], value_names_[12]);
829
830 EXPECT_NE(value_names_[13], value_names_[16]);
831 EXPECT_EQ(value_names_[14], value_names_[17]);
832
833 EXPECT_EQ(value_names_[24], value_names_[25]);
834}
835
836TEST_F(GlobalValueNumberingTestDiamond, NonAliasingArrays) {
837 static const MIRDef mirs[] = {
838 // NOTE: MIRs here are ordered by unique tests. They will be put into appropriate blocks.
839 DEF_UNIQUE_REF(3, Instruction::NEW_ARRAY, 100u),
840 DEF_AGET(3, Instruction::AGET, 1u, 100u, 101u),
841 DEF_AGET(6, Instruction::AGET, 2u, 100u, 101u), // Same as at the top.
842
843 DEF_UNIQUE_REF(3, Instruction::NEW_ARRAY, 200u),
844 DEF_IGET(4, Instruction::AGET, 4u, 200u, 201u),
845 DEF_IGET(6, Instruction::AGET, 5u, 200u, 201u), // Same as at the left side.
846
847 DEF_UNIQUE_REF(3, Instruction::NEW_ARRAY, 300u),
848 DEF_AGET(3, Instruction::AGET, 7u, 300u, 301u),
849 DEF_CONST(5, Instruction::CONST, 8u, 1000),
850 DEF_APUT(5, Instruction::APUT, 8u, 300u, 301u),
851 DEF_AGET(6, Instruction::AGET, 10u, 300u, 301u), // Differs from the top and the CONST.
852
853 DEF_UNIQUE_REF(3, Instruction::NEW_ARRAY, 400u),
854 DEF_AGET(3, Instruction::AGET, 12u, 400u, 401u),
855 DEF_CONST(3, Instruction::CONST, 13u, 2000),
856 DEF_APUT(4, Instruction::APUT, 13u, 400u, 401u),
857 DEF_APUT(5, Instruction::APUT, 13u, 400u, 401u),
858 DEF_AGET(6, Instruction::AGET, 16u, 400u, 401u), // Differs from the top, equals the CONST.
859
860 DEF_UNIQUE_REF(3, Instruction::NEW_ARRAY, 500u),
861 DEF_AGET(3, Instruction::AGET, 18u, 500u, 501u),
862 DEF_APUT(4, Instruction::APUT, 19u, 500u, 502u), // Clobbers value at index 501u.
863 DEF_AGET(6, Instruction::AGET, 20u, 500u, 501u), // Differs from the top.
864
865 DEF_UNIQUE_REF(3, Instruction::NEW_ARRAY, 600u),
866 DEF_CONST(4, Instruction::CONST, 22u, 3000),
867 DEF_APUT(4, Instruction::APUT, 22u, 600u, 601u),
868 DEF_APUT(4, Instruction::APUT, 22u, 600u, 602u),
869 DEF_CONST(5, Instruction::CONST, 25u, 3001),
870 DEF_APUT(5, Instruction::APUT, 25u, 600u, 601u),
871 DEF_APUT(5, Instruction::APUT, 25u, 600u, 602u),
872 DEF_AGET(6, Instruction::AGET, 28u, 600u, 601u),
873 DEF_AGET(6, Instruction::AGET, 29u, 600u, 602u), // Same value as read from index 601u.
874
875 DEF_UNIQUE_REF(3, Instruction::NEW_ARRAY, 700u),
876 DEF_UNIQUE_REF(3, Instruction::NEW_ARRAY, 701u),
877 DEF_AGET(3, Instruction::AGET, 32u, 700u, 702u),
878 DEF_APUT(4, Instruction::APUT, 33u, 701u, 702u), // Doesn't interfere with unrelated array.
879 DEF_AGET(6, Instruction::AGET, 34u, 700u, 702u), // Same value as at the top.
880 };
881
882 PrepareMIRs(mirs);
883 PerformGVN();
884 ASSERT_EQ(arraysize(mirs), value_names_.size());
885 EXPECT_EQ(value_names_[1], value_names_[2]);
886
887 EXPECT_EQ(value_names_[4], value_names_[5]);
888
889 EXPECT_NE(value_names_[7], value_names_[10]);
890 EXPECT_NE(value_names_[8], value_names_[10]);
891
892 EXPECT_NE(value_names_[12], value_names_[16]);
893 EXPECT_EQ(value_names_[13], value_names_[16]);
894
895 EXPECT_NE(value_names_[18], value_names_[20]);
896
897 EXPECT_NE(value_names_[28], value_names_[22]);
898 EXPECT_NE(value_names_[28], value_names_[25]);
899 EXPECT_EQ(value_names_[28], value_names_[29]);
900
901 EXPECT_EQ(value_names_[32], value_names_[34]);
902}
903
904TEST_F(GlobalValueNumberingTestDiamond, AliasingArrays) {
905 static const MIRDef mirs[] = {
906 // NOTE: MIRs here are ordered by unique tests. They will be put into appropriate blocks.
907 // NOTE: We're also testing that these tests really do not interfere with each other.
908
909 DEF_AGET(3, Instruction::AGET_BOOLEAN, 0u, 100u, 101u),
910 DEF_AGET(6, Instruction::AGET_BOOLEAN, 1u, 100u, 101u), // Same as at the top.
911
912 DEF_IGET(4, Instruction::AGET_OBJECT, 2u, 200u, 201u),
913 DEF_IGET(6, Instruction::AGET_OBJECT, 3u, 200u, 201u), // Same as at the left side.
914
915 DEF_AGET(3, Instruction::AGET_WIDE, 4u, 300u, 301u),
916 DEF_CONST(5, Instruction::CONST_WIDE, 5u, 1000),
917 DEF_APUT(5, Instruction::APUT_WIDE, 5u, 300u, 301u),
918 DEF_AGET(6, Instruction::AGET_WIDE, 7u, 300u, 301u), // Differs from the top and the CONST.
919
920 DEF_AGET(3, Instruction::AGET_SHORT, 8u, 400u, 401u),
921 DEF_CONST(3, Instruction::CONST, 9u, 2000),
922 DEF_APUT(4, Instruction::APUT_SHORT, 9u, 400u, 401u),
923 DEF_APUT(5, Instruction::APUT_SHORT, 9u, 400u, 401u),
924 DEF_AGET(6, Instruction::AGET_SHORT, 12u, 400u, 401u), // Differs from the top, == CONST.
925
926 DEF_AGET(3, Instruction::AGET_CHAR, 13u, 500u, 501u),
927 DEF_APUT(4, Instruction::APUT_CHAR, 14u, 500u, 502u), // Clobbers value at index 501u.
928 DEF_AGET(6, Instruction::AGET_CHAR, 15u, 500u, 501u), // Differs from the top.
929
930 DEF_AGET(3, Instruction::AGET_BYTE, 16u, 600u, 602u),
931 DEF_APUT(4, Instruction::APUT_BYTE, 17u, 601u, 602u), // Clobbers values in array 600u.
932 DEF_AGET(6, Instruction::AGET_BYTE, 18u, 600u, 602u), // Differs from the top.
933
934 DEF_CONST(4, Instruction::CONST, 19u, 3000),
935 DEF_APUT(4, Instruction::APUT, 19u, 700u, 701u),
936 DEF_APUT(4, Instruction::APUT, 19u, 700u, 702u),
937 DEF_CONST(5, Instruction::CONST, 22u, 3001),
938 DEF_APUT(5, Instruction::APUT, 22u, 700u, 701u),
939 DEF_APUT(5, Instruction::APUT, 22u, 700u, 702u),
940 DEF_AGET(6, Instruction::AGET, 25u, 700u, 701u),
941 DEF_AGET(6, Instruction::AGET, 26u, 700u, 702u), // Same value as read from index 601u.
942 };
943
944 PrepareMIRs(mirs);
945 PerformGVN();
946 ASSERT_EQ(arraysize(mirs), value_names_.size());
947 EXPECT_EQ(value_names_[0], value_names_[1]);
948
949 EXPECT_EQ(value_names_[2], value_names_[3]);
950
951 EXPECT_NE(value_names_[4], value_names_[7]);
952 EXPECT_NE(value_names_[5], value_names_[7]);
953
954 EXPECT_NE(value_names_[8], value_names_[12]);
955 EXPECT_EQ(value_names_[9], value_names_[12]);
956
957 EXPECT_NE(value_names_[13], value_names_[15]);
958
959 EXPECT_NE(value_names_[16], value_names_[18]);
960
961 EXPECT_NE(value_names_[25], value_names_[19]);
962 EXPECT_NE(value_names_[25], value_names_[22]);
963 EXPECT_EQ(value_names_[25], value_names_[26]);
964}
965
966TEST_F(GlobalValueNumberingTestDiamond, Phi) {
967 static const MIRDef mirs[] = {
968 DEF_CONST(3, Instruction::CONST, 0u, 1000),
969 DEF_CONST(4, Instruction::CONST, 1u, 2000),
970 DEF_CONST(5, Instruction::CONST, 2u, 3000),
971 DEF_MOVE(4, Instruction::MOVE, 3u, 0u),
972 DEF_MOVE(4, Instruction::MOVE, 4u, 1u),
973 DEF_MOVE(5, Instruction::MOVE, 5u, 0u),
974 DEF_MOVE(5, Instruction::MOVE, 6u, 2u),
975 DEF_PHI2(6, 7u, 3u, 5u), // Same as CONST 0u (1000).
976 DEF_PHI2(6, 8u, 3u, 0u), // Same as CONST 0u (1000).
977 DEF_PHI2(6, 9u, 0u, 5u), // Same as CONST 0u (1000).
978 DEF_PHI2(6, 10u, 4u, 5u), // Merge 1u (2000) and 0u (1000).
979 DEF_PHI2(6, 11u, 1u, 5u), // Merge 1u (2000) and 0u (1000).
980 DEF_PHI2(6, 12u, 4u, 0u), // Merge 1u (2000) and 0u (1000).
981 DEF_PHI2(6, 13u, 1u, 0u), // Merge 1u (2000) and 0u (1000).
982 DEF_PHI2(6, 14u, 3u, 6u), // Merge 0u (1000) and 2u (3000).
983 DEF_PHI2(6, 15u, 0u, 6u), // Merge 0u (1000) and 2u (3000).
984 DEF_PHI2(6, 16u, 3u, 2u), // Merge 0u (1000) and 2u (3000).
985 DEF_PHI2(6, 17u, 0u, 2u), // Merge 0u (1000) and 2u (3000).
986 DEF_PHI2(6, 18u, 4u, 6u), // Merge 1u (2000) and 2u (3000).
987 DEF_PHI2(6, 19u, 1u, 6u), // Merge 1u (2000) and 2u (3000).
988 DEF_PHI2(6, 20u, 4u, 2u), // Merge 1u (2000) and 2u (3000).
989 DEF_PHI2(6, 21u, 1u, 2u), // Merge 1u (2000) and 2u (3000).
990 };
991
992 PrepareMIRs(mirs);
993 PerformGVN();
994 ASSERT_EQ(arraysize(mirs), value_names_.size());
995 EXPECT_EQ(value_names_[0], value_names_[7]);
996 EXPECT_EQ(value_names_[0], value_names_[8]);
997 EXPECT_EQ(value_names_[0], value_names_[9]);
998 EXPECT_NE(value_names_[10], value_names_[0]);
999 EXPECT_NE(value_names_[10], value_names_[1]);
1000 EXPECT_NE(value_names_[10], value_names_[2]);
1001 EXPECT_EQ(value_names_[10], value_names_[11]);
1002 EXPECT_EQ(value_names_[10], value_names_[12]);
1003 EXPECT_EQ(value_names_[10], value_names_[13]);
1004 EXPECT_NE(value_names_[14], value_names_[0]);
1005 EXPECT_NE(value_names_[14], value_names_[1]);
1006 EXPECT_NE(value_names_[14], value_names_[2]);
1007 EXPECT_NE(value_names_[14], value_names_[10]);
1008 EXPECT_EQ(value_names_[14], value_names_[15]);
1009 EXPECT_EQ(value_names_[14], value_names_[16]);
1010 EXPECT_EQ(value_names_[14], value_names_[17]);
1011 EXPECT_NE(value_names_[18], value_names_[0]);
1012 EXPECT_NE(value_names_[18], value_names_[1]);
1013 EXPECT_NE(value_names_[18], value_names_[2]);
1014 EXPECT_NE(value_names_[18], value_names_[10]);
1015 EXPECT_NE(value_names_[18], value_names_[14]);
1016 EXPECT_EQ(value_names_[18], value_names_[19]);
1017 EXPECT_EQ(value_names_[18], value_names_[20]);
1018 EXPECT_EQ(value_names_[18], value_names_[21]);
1019}
1020
Vladimir Markoa4426cf2014-10-22 17:15:53 +01001021TEST_F(GlobalValueNumberingTestDiamond, PhiWide) {
1022 static const MIRDef mirs[] = {
1023 DEF_CONST_WIDE(3, Instruction::CONST_WIDE, 0u, 1000),
1024 DEF_CONST_WIDE(4, Instruction::CONST_WIDE, 2u, 2000),
1025 DEF_CONST_WIDE(5, Instruction::CONST_WIDE, 4u, 3000),
1026 DEF_MOVE_WIDE(4, Instruction::MOVE_WIDE, 6u, 0u),
1027 DEF_MOVE_WIDE(4, Instruction::MOVE_WIDE, 8u, 2u),
1028 DEF_MOVE_WIDE(5, Instruction::MOVE_WIDE, 10u, 0u),
1029 DEF_MOVE_WIDE(5, Instruction::MOVE_WIDE, 12u, 4u),
1030 DEF_PHI2(6, 14u, 6u, 10u), // Same as CONST_WIDE 0u (1000).
1031 DEF_PHI2(6, 15u, 7u, 11u), // Same as CONST_WIDE 0u (1000), high word.
1032 DEF_PHI2(6, 16u, 6u, 0u), // Same as CONST_WIDE 0u (1000).
1033 DEF_PHI2(6, 17u, 7u, 1u), // Same as CONST_WIDE 0u (1000), high word.
1034 DEF_PHI2(6, 18u, 0u, 10u), // Same as CONST_WIDE 0u (1000).
1035 DEF_PHI2(6, 19u, 1u, 11u), // Same as CONST_WIDE 0u (1000), high word.
1036 DEF_PHI2(6, 20u, 8u, 10u), // Merge 2u (2000) and 0u (1000).
1037 DEF_PHI2(6, 21u, 9u, 11u), // Merge 2u (2000) and 0u (1000), high word.
1038 DEF_PHI2(6, 22u, 2u, 10u), // Merge 2u (2000) and 0u (1000).
1039 DEF_PHI2(6, 23u, 3u, 11u), // Merge 2u (2000) and 0u (1000), high word.
1040 DEF_PHI2(6, 24u, 8u, 0u), // Merge 2u (2000) and 0u (1000).
1041 DEF_PHI2(6, 25u, 9u, 1u), // Merge 2u (2000) and 0u (1000), high word.
1042 DEF_PHI2(6, 26u, 2u, 0u), // Merge 2u (2000) and 0u (1000).
1043 DEF_PHI2(6, 27u, 5u, 1u), // Merge 2u (2000) and 0u (1000), high word.
1044 DEF_PHI2(6, 28u, 6u, 12u), // Merge 0u (1000) and 4u (3000).
1045 DEF_PHI2(6, 29u, 7u, 13u), // Merge 0u (1000) and 4u (3000), high word.
1046 DEF_PHI2(6, 30u, 0u, 12u), // Merge 0u (1000) and 4u (3000).
1047 DEF_PHI2(6, 31u, 1u, 13u), // Merge 0u (1000) and 4u (3000), high word.
1048 DEF_PHI2(6, 32u, 6u, 4u), // Merge 0u (1000) and 4u (3000).
1049 DEF_PHI2(6, 33u, 7u, 5u), // Merge 0u (1000) and 4u (3000), high word.
1050 DEF_PHI2(6, 34u, 0u, 4u), // Merge 0u (1000) and 4u (3000).
1051 DEF_PHI2(6, 35u, 1u, 5u), // Merge 0u (1000) and 4u (3000), high word.
1052 DEF_PHI2(6, 36u, 8u, 12u), // Merge 2u (2000) and 4u (3000).
1053 DEF_PHI2(6, 37u, 9u, 13u), // Merge 2u (2000) and 4u (3000), high word.
1054 DEF_PHI2(6, 38u, 2u, 12u), // Merge 2u (2000) and 4u (3000).
1055 DEF_PHI2(6, 39u, 3u, 13u), // Merge 2u (2000) and 4u (3000), high word.
1056 DEF_PHI2(6, 40u, 8u, 4u), // Merge 2u (2000) and 4u (3000).
1057 DEF_PHI2(6, 41u, 9u, 5u), // Merge 2u (2000) and 4u (3000), high word.
1058 DEF_PHI2(6, 42u, 2u, 4u), // Merge 2u (2000) and 4u (3000).
1059 DEF_PHI2(6, 43u, 3u, 5u), // Merge 2u (2000) and 4u (3000), high word.
1060 };
1061
1062 PrepareMIRs(mirs);
1063 PerformGVN();
1064 ASSERT_EQ(arraysize(mirs), value_names_.size());
1065 EXPECT_EQ(value_names_[0], value_names_[7]);
1066 EXPECT_EQ(value_names_[0], value_names_[9]);
1067 EXPECT_EQ(value_names_[0], value_names_[11]);
1068 EXPECT_NE(value_names_[13], value_names_[0]);
1069 EXPECT_NE(value_names_[13], value_names_[1]);
1070 EXPECT_NE(value_names_[13], value_names_[2]);
1071 EXPECT_EQ(value_names_[13], value_names_[15]);
1072 EXPECT_EQ(value_names_[13], value_names_[17]);
1073 EXPECT_EQ(value_names_[13], value_names_[19]);
1074 EXPECT_NE(value_names_[21], value_names_[0]);
1075 EXPECT_NE(value_names_[21], value_names_[1]);
1076 EXPECT_NE(value_names_[21], value_names_[2]);
1077 EXPECT_NE(value_names_[21], value_names_[13]);
1078 EXPECT_EQ(value_names_[21], value_names_[23]);
1079 EXPECT_EQ(value_names_[21], value_names_[25]);
1080 EXPECT_EQ(value_names_[21], value_names_[27]);
1081 EXPECT_NE(value_names_[29], value_names_[0]);
1082 EXPECT_NE(value_names_[29], value_names_[1]);
1083 EXPECT_NE(value_names_[29], value_names_[2]);
1084 EXPECT_NE(value_names_[29], value_names_[13]);
1085 EXPECT_NE(value_names_[29], value_names_[21]);
1086 EXPECT_EQ(value_names_[29], value_names_[31]);
1087 EXPECT_EQ(value_names_[29], value_names_[33]);
1088 EXPECT_EQ(value_names_[29], value_names_[35]);
1089 // High words should get kNoValue.
1090 EXPECT_EQ(value_names_[8], kNoValue);
1091 EXPECT_EQ(value_names_[10], kNoValue);
1092 EXPECT_EQ(value_names_[12], kNoValue);
1093 EXPECT_EQ(value_names_[14], kNoValue);
1094 EXPECT_EQ(value_names_[16], kNoValue);
1095 EXPECT_EQ(value_names_[18], kNoValue);
1096 EXPECT_EQ(value_names_[20], kNoValue);
1097 EXPECT_EQ(value_names_[22], kNoValue);
1098 EXPECT_EQ(value_names_[24], kNoValue);
1099 EXPECT_EQ(value_names_[26], kNoValue);
1100 EXPECT_EQ(value_names_[28], kNoValue);
1101 EXPECT_EQ(value_names_[30], kNoValue);
1102 EXPECT_EQ(value_names_[32], kNoValue);
1103 EXPECT_EQ(value_names_[34], kNoValue);
1104 EXPECT_EQ(value_names_[36], kNoValue);
1105}
1106
Vladimir Marko95a05972014-05-30 10:01:32 +01001107TEST_F(GlobalValueNumberingTestLoop, NonAliasingIFields) {
1108 static const IFieldDef ifields[] = {
Vladimir Markoaf6925b2014-10-31 16:37:32 +00001109 { 0u, 1u, 0u, false, kDexMemAccessWord },
1110 { 1u, 1u, 1u, false, kDexMemAccessWord },
1111 { 2u, 1u, 2u, false, kDexMemAccessWord },
1112 { 3u, 1u, 3u, false, kDexMemAccessWord },
1113 { 4u, 1u, 4u, false, kDexMemAccessWord },
1114 { 5u, 1u, 5u, false, kDexMemAccessShort },
1115 { 6u, 1u, 6u, false, kDexMemAccessChar },
1116 { 7u, 0u, 0u, false, kDexMemAccessShort }, // Unresolved.
1117 { 8u, 1u, 8u, false, kDexMemAccessWord },
1118 { 9u, 0u, 0u, false, kDexMemAccessWord }, // Unresolved.
1119 { 10u, 1u, 10u, false, kDexMemAccessWord },
1120 { 11u, 1u, 11u, false, kDexMemAccessWord },
Vladimir Marko95a05972014-05-30 10:01:32 +01001121 };
1122 static const MIRDef mirs[] = {
1123 // NOTE: MIRs here are ordered by unique tests. They will be put into appropriate blocks.
1124 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 100u),
1125 DEF_IGET(3, Instruction::IGET, 1u, 100u, 0u),
1126 DEF_IGET(4, Instruction::IGET, 2u, 100u, 0u), // Same as at the top.
1127 DEF_IGET(5, Instruction::IGET, 3u, 100u, 0u), // Same as at the top.
1128
1129 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 200u),
1130 DEF_IGET(3, Instruction::IGET, 5u, 200u, 1u),
1131 DEF_IGET(4, Instruction::IGET, 6u, 200u, 1u), // Differs from top...
1132 DEF_IPUT(4, Instruction::IPUT, 7u, 200u, 1u), // Because of this IPUT.
1133 DEF_IGET(5, Instruction::IGET, 8u, 200u, 1u), // Differs from top and the loop IGET.
1134
1135 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 300u),
1136 DEF_IGET(3, Instruction::IGET, 10u, 300u, 2u),
1137 DEF_IPUT(4, Instruction::IPUT, 11u, 300u, 2u), // Because of this IPUT...
1138 DEF_IGET(4, Instruction::IGET, 12u, 300u, 2u), // Differs from top.
1139 DEF_IGET(5, Instruction::IGET, 13u, 300u, 2u), // Differs from top but same as the loop IGET.
1140
1141 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 400u),
1142 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 401u),
1143 DEF_CONST(3, Instruction::CONST, 16u, 3000),
1144 DEF_IPUT(3, Instruction::IPUT, 16u, 400u, 3u),
1145 DEF_IPUT(3, Instruction::IPUT, 16u, 400u, 4u),
1146 DEF_IPUT(3, Instruction::IPUT, 16u, 401u, 3u),
1147 DEF_IGET(4, Instruction::IGET, 20u, 400u, 3u), // Differs from 16u and 23u.
1148 DEF_IGET(4, Instruction::IGET, 21u, 400u, 4u), // Same as 20u.
1149 DEF_IGET(4, Instruction::IGET, 22u, 401u, 3u), // Same as 20u.
1150 DEF_CONST(4, Instruction::CONST, 23u, 4000),
1151 DEF_IPUT(4, Instruction::IPUT, 23u, 400u, 3u),
1152 DEF_IPUT(4, Instruction::IPUT, 23u, 400u, 4u),
1153 DEF_IPUT(4, Instruction::IPUT, 23u, 401u, 3u),
1154 DEF_IGET(5, Instruction::IGET, 27u, 400u, 3u), // Differs from 16u and 20u...
1155 DEF_IGET(5, Instruction::IGET, 28u, 400u, 4u), // and same as the CONST 23u
1156 DEF_IGET(5, Instruction::IGET, 29u, 400u, 4u), // and same as the CONST 23u.
1157
1158 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 500u),
1159 DEF_IGET(3, Instruction::IGET_SHORT, 31u, 500u, 5u),
1160 DEF_IGET(3, Instruction::IGET_CHAR, 32u, 500u, 6u),
1161 DEF_IPUT(4, Instruction::IPUT_SHORT, 33u, 500u, 7u), // Clobbers field #5, not #6.
1162 DEF_IGET(5, Instruction::IGET_SHORT, 34u, 500u, 5u), // Differs from the top.
1163 DEF_IGET(5, Instruction::IGET_CHAR, 35u, 500u, 6u), // Same as the top.
1164
1165 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 600u),
1166 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 601u),
1167 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 602u),
1168 DEF_IGET(3, Instruction::IGET, 39u, 600u, 8u),
1169 DEF_IGET(3, Instruction::IGET, 40u, 601u, 8u),
1170 DEF_IPUT(4, Instruction::IPUT, 41u, 602u, 9u), // Doesn't clobber field #8 for other refs.
1171 DEF_IGET(5, Instruction::IGET, 42u, 600u, 8u), // Same as the top.
1172 DEF_IGET(5, Instruction::IGET, 43u, 601u, 8u), // Same as the top.
1173
1174 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 700u),
1175 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 701u),
1176 DEF_CONST(3, Instruction::CONST, 46u, 3000),
1177 DEF_IPUT(3, Instruction::IPUT, 46u, 700u, 10u),
1178 DEF_IPUT(3, Instruction::IPUT, 46u, 700u, 11u),
1179 DEF_IPUT(3, Instruction::IPUT, 46u, 701u, 10u),
1180 DEF_IGET(4, Instruction::IGET, 50u, 700u, 10u), // Differs from the CONSTs 46u and 53u.
1181 DEF_IGET(4, Instruction::IGET, 51u, 700u, 11u), // Same as 50u.
1182 DEF_IGET(4, Instruction::IGET, 52u, 701u, 10u), // Same as 50u.
1183 DEF_CONST(4, Instruction::CONST, 53u, 3001),
1184 DEF_IPUT(4, Instruction::IPUT, 53u, 700u, 10u),
1185 DEF_IPUT(4, Instruction::IPUT, 53u, 700u, 11u),
1186 DEF_IPUT(4, Instruction::IPUT, 53u, 701u, 10u),
1187 DEF_IGET(5, Instruction::IGET, 57u, 700u, 10u), // Same as the CONST 53u.
1188 DEF_IGET(5, Instruction::IGET, 58u, 700u, 11u), // Same as the CONST 53u.
1189 DEF_IGET(5, Instruction::IGET, 59u, 701u, 10u), // Same as the CONST 53u.
1190 };
1191
1192 PrepareIFields(ifields);
1193 PrepareMIRs(mirs);
1194 PerformGVN();
1195 ASSERT_EQ(arraysize(mirs), value_names_.size());
1196 EXPECT_EQ(value_names_[1], value_names_[2]);
1197 EXPECT_EQ(value_names_[1], value_names_[3]);
1198
1199 EXPECT_NE(value_names_[5], value_names_[6]);
1200 EXPECT_NE(value_names_[5], value_names_[7]);
1201 EXPECT_NE(value_names_[6], value_names_[7]);
1202
1203 EXPECT_NE(value_names_[10], value_names_[12]);
1204 EXPECT_EQ(value_names_[12], value_names_[13]);
1205
1206 EXPECT_NE(value_names_[20], value_names_[16]);
1207 EXPECT_NE(value_names_[20], value_names_[23]);
1208 EXPECT_EQ(value_names_[20], value_names_[21]);
1209 EXPECT_EQ(value_names_[20], value_names_[22]);
1210 EXPECT_NE(value_names_[27], value_names_[16]);
1211 EXPECT_NE(value_names_[27], value_names_[20]);
1212 EXPECT_EQ(value_names_[27], value_names_[28]);
1213 EXPECT_EQ(value_names_[27], value_names_[29]);
1214
1215 EXPECT_NE(value_names_[31], value_names_[34]);
1216 EXPECT_EQ(value_names_[32], value_names_[35]);
1217
1218 EXPECT_EQ(value_names_[39], value_names_[42]);
1219 EXPECT_EQ(value_names_[40], value_names_[43]);
1220
1221 EXPECT_NE(value_names_[50], value_names_[46]);
1222 EXPECT_NE(value_names_[50], value_names_[53]);
1223 EXPECT_EQ(value_names_[50], value_names_[51]);
1224 EXPECT_EQ(value_names_[50], value_names_[52]);
1225 EXPECT_EQ(value_names_[57], value_names_[53]);
1226 EXPECT_EQ(value_names_[58], value_names_[53]);
1227 EXPECT_EQ(value_names_[59], value_names_[53]);
1228}
1229
1230TEST_F(GlobalValueNumberingTestLoop, AliasingIFieldsSingleObject) {
1231 static const IFieldDef ifields[] = {
Vladimir Markoaf6925b2014-10-31 16:37:32 +00001232 { 0u, 1u, 0u, false, kDexMemAccessWord },
1233 { 1u, 1u, 1u, false, kDexMemAccessWord },
1234 { 2u, 1u, 2u, false, kDexMemAccessWord },
1235 { 3u, 1u, 3u, false, kDexMemAccessWord },
1236 { 4u, 1u, 4u, false, kDexMemAccessWord },
1237 { 5u, 1u, 5u, false, kDexMemAccessShort },
1238 { 6u, 1u, 6u, false, kDexMemAccessChar },
1239 { 7u, 0u, 0u, false, kDexMemAccessShort }, // Unresolved.
Vladimir Marko95a05972014-05-30 10:01:32 +01001240 };
1241 static const MIRDef mirs[] = {
1242 // NOTE: MIRs here are ordered by unique tests. They will be put into appropriate blocks.
1243 DEF_IGET(3, Instruction::IGET, 0u, 100u, 0u),
1244 DEF_IGET(4, Instruction::IGET, 1u, 100u, 0u), // Same as at the top.
1245 DEF_IGET(5, Instruction::IGET, 2u, 100u, 0u), // Same as at the top.
1246
1247 DEF_IGET(3, Instruction::IGET, 3u, 100u, 1u),
1248 DEF_IGET(4, Instruction::IGET, 4u, 100u, 1u), // Differs from top...
1249 DEF_IPUT(4, Instruction::IPUT, 5u, 100u, 1u), // Because of this IPUT.
1250 DEF_IGET(5, Instruction::IGET, 6u, 100u, 1u), // Differs from top and the loop IGET.
1251
1252 DEF_IGET(3, Instruction::IGET, 7u, 100u, 2u),
1253 DEF_IPUT(4, Instruction::IPUT, 8u, 100u, 2u), // Because of this IPUT...
1254 DEF_IGET(4, Instruction::IGET, 9u, 100u, 2u), // Differs from top.
1255 DEF_IGET(5, Instruction::IGET, 10u, 100u, 2u), // Differs from top but same as the loop IGET.
1256
1257 DEF_CONST(3, Instruction::CONST, 11u, 3000),
1258 DEF_IPUT(3, Instruction::IPUT, 11u, 100u, 3u),
1259 DEF_IPUT(3, Instruction::IPUT, 11u, 100u, 4u),
1260 DEF_IGET(4, Instruction::IGET, 14u, 100u, 3u), // Differs from 11u and 16u.
1261 DEF_IGET(4, Instruction::IGET, 15u, 100u, 4u), // Same as 14u.
1262 DEF_CONST(4, Instruction::CONST, 16u, 4000),
1263 DEF_IPUT(4, Instruction::IPUT, 16u, 100u, 3u),
1264 DEF_IPUT(4, Instruction::IPUT, 16u, 100u, 4u),
1265 DEF_IGET(5, Instruction::IGET, 19u, 100u, 3u), // Differs from 11u and 14u...
1266 DEF_IGET(5, Instruction::IGET, 20u, 100u, 4u), // and same as the CONST 16u.
1267
1268 DEF_IGET(3, Instruction::IGET_SHORT, 21u, 100u, 5u),
1269 DEF_IGET(3, Instruction::IGET_CHAR, 22u, 100u, 6u),
1270 DEF_IPUT(4, Instruction::IPUT_SHORT, 23u, 100u, 7u), // Clobbers field #5, not #6.
1271 DEF_IGET(5, Instruction::IGET_SHORT, 24u, 100u, 5u), // Differs from the top.
1272 DEF_IGET(5, Instruction::IGET_CHAR, 25u, 100u, 6u), // Same as the top.
1273 };
1274
1275 PrepareIFields(ifields);
1276 PrepareMIRs(mirs);
1277 PerformGVN();
1278 ASSERT_EQ(arraysize(mirs), value_names_.size());
1279 EXPECT_EQ(value_names_[0], value_names_[1]);
1280 EXPECT_EQ(value_names_[0], value_names_[2]);
1281
1282 EXPECT_NE(value_names_[3], value_names_[4]);
1283 EXPECT_NE(value_names_[3], value_names_[6]);
1284 EXPECT_NE(value_names_[4], value_names_[6]);
1285
1286 EXPECT_NE(value_names_[7], value_names_[9]);
1287 EXPECT_EQ(value_names_[9], value_names_[10]);
1288
1289 EXPECT_NE(value_names_[14], value_names_[11]);
1290 EXPECT_NE(value_names_[14], value_names_[16]);
1291 EXPECT_EQ(value_names_[14], value_names_[15]);
1292 EXPECT_NE(value_names_[19], value_names_[11]);
1293 EXPECT_NE(value_names_[19], value_names_[14]);
1294 EXPECT_EQ(value_names_[19], value_names_[16]);
1295 EXPECT_EQ(value_names_[19], value_names_[20]);
1296
1297 EXPECT_NE(value_names_[21], value_names_[24]);
1298 EXPECT_EQ(value_names_[22], value_names_[25]);
1299}
1300
1301TEST_F(GlobalValueNumberingTestLoop, AliasingIFieldsTwoObjects) {
1302 static const IFieldDef ifields[] = {
Vladimir Markoaf6925b2014-10-31 16:37:32 +00001303 { 0u, 1u, 0u, false, kDexMemAccessWord },
1304 { 1u, 1u, 1u, false, kDexMemAccessWord },
1305 { 2u, 1u, 2u, false, kDexMemAccessWord },
1306 { 3u, 1u, 3u, false, kDexMemAccessShort },
1307 { 4u, 1u, 4u, false, kDexMemAccessChar },
1308 { 5u, 0u, 0u, false, kDexMemAccessShort }, // Unresolved.
1309 { 6u, 1u, 6u, false, kDexMemAccessWord },
1310 { 7u, 1u, 7u, false, kDexMemAccessWord },
Vladimir Marko95a05972014-05-30 10:01:32 +01001311 };
1312 static const MIRDef mirs[] = {
1313 // NOTE: MIRs here are ordered by unique tests. They will be put into appropriate blocks.
1314 DEF_IGET(3, Instruction::IGET, 0u, 100u, 0u),
1315 DEF_IPUT(4, Instruction::IPUT, 1u, 101u, 0u), // May alias with the IGET at the top.
1316 DEF_IGET(5, Instruction::IGET, 2u, 100u, 0u), // Differs from the top.
1317
1318 DEF_IGET(3, Instruction::IGET, 3u, 100u, 1u),
1319 DEF_IPUT(4, Instruction::IPUT, 3u, 101u, 1u), // If aliasing, stores the same value.
1320 DEF_IGET(5, Instruction::IGET, 5u, 100u, 1u), // Same as the top.
1321
1322 DEF_IGET(3, Instruction::IGET, 6u, 100u, 2u),
1323 DEF_CONST(4, Instruction::CONST, 7u, 1000),
1324 DEF_IPUT(4, Instruction::IPUT, 7u, 101u, 2u),
1325 DEF_IGET(5, Instruction::IGET, 9u, 100u, 2u), // Differs from the top and the CONST.
1326
1327 DEF_IGET(3, Instruction::IGET_SHORT, 10u, 100u, 3u),
1328 DEF_IGET(3, Instruction::IGET_CHAR, 11u, 100u, 4u),
1329 DEF_IPUT(4, Instruction::IPUT_SHORT, 12u, 101u, 5u), // Clobbers field #3, not #4.
1330 DEF_IGET(5, Instruction::IGET_SHORT, 13u, 100u, 3u), // Differs from the top.
1331 DEF_IGET(5, Instruction::IGET_CHAR, 14u, 100u, 4u), // Same as the top.
1332
1333 DEF_CONST(3, Instruction::CONST, 15u, 3000),
1334 DEF_IPUT(3, Instruction::IPUT, 15u, 100u, 6u),
1335 DEF_IPUT(3, Instruction::IPUT, 15u, 100u, 7u),
1336 DEF_IPUT(3, Instruction::IPUT, 15u, 101u, 6u),
1337 DEF_IGET(4, Instruction::IGET, 19u, 100u, 6u), // Differs from CONSTs 15u and 22u.
1338 DEF_IGET(4, Instruction::IGET, 20u, 100u, 7u), // Same value as 19u.
1339 DEF_IGET(4, Instruction::IGET, 21u, 101u, 6u), // Same value as read from field #7.
1340 DEF_CONST(4, Instruction::CONST, 22u, 3001),
1341 DEF_IPUT(4, Instruction::IPUT, 22u, 100u, 6u),
1342 DEF_IPUT(4, Instruction::IPUT, 22u, 100u, 7u),
1343 DEF_IPUT(4, Instruction::IPUT, 22u, 101u, 6u),
1344 DEF_IGET(5, Instruction::IGET, 26u, 100u, 6u), // Same as CONST 22u.
1345 DEF_IGET(5, Instruction::IGET, 27u, 100u, 7u), // Same as CONST 22u.
1346 DEF_IGET(5, Instruction::IGET, 28u, 101u, 6u), // Same as CONST 22u.
1347 };
1348
1349 PrepareIFields(ifields);
1350 PrepareMIRs(mirs);
1351 PerformGVN();
1352 ASSERT_EQ(arraysize(mirs), value_names_.size());
1353 EXPECT_NE(value_names_[0], value_names_[2]);
1354
1355 EXPECT_EQ(value_names_[3], value_names_[5]);
1356
1357 EXPECT_NE(value_names_[6], value_names_[9]);
1358 EXPECT_NE(value_names_[7], value_names_[9]);
1359
1360 EXPECT_NE(value_names_[10], value_names_[13]);
1361 EXPECT_EQ(value_names_[11], value_names_[14]);
1362
1363 EXPECT_NE(value_names_[19], value_names_[15]);
1364 EXPECT_NE(value_names_[19], value_names_[22]);
1365 EXPECT_EQ(value_names_[22], value_names_[26]);
1366 EXPECT_EQ(value_names_[22], value_names_[27]);
1367 EXPECT_EQ(value_names_[22], value_names_[28]);
1368}
1369
1370TEST_F(GlobalValueNumberingTestLoop, IFieldToBaseDependency) {
1371 static const IFieldDef ifields[] = {
Vladimir Markoaf6925b2014-10-31 16:37:32 +00001372 { 0u, 1u, 0u, false, kDexMemAccessWord },
Vladimir Marko95a05972014-05-30 10:01:32 +01001373 };
1374 static const MIRDef mirs[] = {
1375 // For the IGET that loads sreg 3u using base 2u, the following IPUT creates a dependency
1376 // from the field value to the base. However, this dependency does not result in an
1377 // infinite loop since the merge of the field value for base 0u gets assigned a value name
1378 // based only on the base 0u, not on the actual value, and breaks the dependency cycle.
1379 DEF_IGET(3, Instruction::IGET, 0u, 100u, 0u),
1380 DEF_IGET(3, Instruction::IGET, 1u, 0u, 0u),
1381 DEF_IGET(4, Instruction::IGET, 2u, 0u, 0u),
1382 DEF_IGET(4, Instruction::IGET, 3u, 2u, 0u),
1383 DEF_IPUT(4, Instruction::IPUT, 3u, 0u, 0u),
1384 DEF_IGET(5, Instruction::IGET, 5u, 0u, 0u),
1385 };
1386
1387 PrepareIFields(ifields);
1388 PrepareMIRs(mirs);
1389 PerformGVN();
1390 ASSERT_EQ(arraysize(mirs), value_names_.size());
1391 EXPECT_NE(value_names_[1], value_names_[2]);
1392 EXPECT_EQ(value_names_[3], value_names_[5]);
1393}
1394
1395TEST_F(GlobalValueNumberingTestLoop, SFields) {
1396 static const SFieldDef sfields[] = {
Vladimir Markoaf6925b2014-10-31 16:37:32 +00001397 { 0u, 1u, 0u, false, kDexMemAccessWord },
1398 { 1u, 1u, 1u, false, kDexMemAccessWord },
1399 { 2u, 1u, 2u, false, kDexMemAccessWord },
Vladimir Marko95a05972014-05-30 10:01:32 +01001400 };
1401 static const MIRDef mirs[] = {
1402 // NOTE: MIRs here are ordered by unique tests. They will be put into appropriate blocks.
1403 DEF_SGET(3, Instruction::SGET, 0u, 0u),
1404 DEF_SGET(4, Instruction::SGET, 1u, 0u), // Same as at the top.
1405 DEF_SGET(5, Instruction::SGET, 2u, 0u), // Same as at the top.
1406
1407 DEF_SGET(3, Instruction::SGET, 3u, 1u),
1408 DEF_SGET(4, Instruction::SGET, 4u, 1u), // Differs from top...
1409 DEF_SPUT(4, Instruction::SPUT, 5u, 1u), // Because of this SPUT.
1410 DEF_SGET(5, Instruction::SGET, 6u, 1u), // Differs from top and the loop SGET.
1411
1412 DEF_SGET(3, Instruction::SGET, 7u, 2u),
1413 DEF_SPUT(4, Instruction::SPUT, 8u, 2u), // Because of this SPUT...
1414 DEF_SGET(4, Instruction::SGET, 9u, 2u), // Differs from top.
1415 DEF_SGET(5, Instruction::SGET, 10u, 2u), // Differs from top but same as the loop SGET.
1416 };
1417
1418 PrepareSFields(sfields);
1419 PrepareMIRs(mirs);
1420 PerformGVN();
1421 ASSERT_EQ(arraysize(mirs), value_names_.size());
1422 EXPECT_EQ(value_names_[0], value_names_[1]);
1423 EXPECT_EQ(value_names_[0], value_names_[2]);
1424
1425 EXPECT_NE(value_names_[3], value_names_[4]);
1426 EXPECT_NE(value_names_[3], value_names_[6]);
1427 EXPECT_NE(value_names_[4], value_names_[5]);
1428
1429 EXPECT_NE(value_names_[7], value_names_[9]);
1430 EXPECT_EQ(value_names_[9], value_names_[10]);
1431}
1432
1433TEST_F(GlobalValueNumberingTestLoop, NonAliasingArrays) {
1434 static const MIRDef mirs[] = {
1435 // NOTE: MIRs here are ordered by unique tests. They will be put into appropriate blocks.
1436 DEF_UNIQUE_REF(3, Instruction::NEW_ARRAY, 100u),
1437 DEF_AGET(3, Instruction::AGET, 1u, 100u, 101u),
1438 DEF_AGET(4, Instruction::AGET, 2u, 100u, 101u), // Same as at the top.
1439 DEF_AGET(5, Instruction::AGET, 3u, 100u, 101u), // Same as at the top.
1440
1441 DEF_UNIQUE_REF(3, Instruction::NEW_ARRAY, 200u),
1442 DEF_AGET(3, Instruction::AGET, 5u, 200u, 201u),
1443 DEF_AGET(4, Instruction::AGET, 6u, 200u, 201u), // Differs from top...
1444 DEF_APUT(4, Instruction::APUT, 7u, 200u, 201u), // Because of this IPUT.
1445 DEF_AGET(5, Instruction::AGET, 8u, 200u, 201u), // Differs from top and the loop AGET.
1446
1447 DEF_UNIQUE_REF(3, Instruction::NEW_ARRAY, 300u),
1448 DEF_AGET(3, Instruction::AGET, 10u, 300u, 301u),
1449 DEF_APUT(4, Instruction::APUT, 11u, 300u, 301u), // Because of this IPUT...
1450 DEF_AGET(4, Instruction::AGET, 12u, 300u, 301u), // Differs from top.
1451 DEF_AGET(5, Instruction::AGET, 13u, 300u, 301u), // Differs from top but == the loop AGET.
1452
1453 DEF_UNIQUE_REF(3, Instruction::NEW_ARRAY, 400u),
1454 DEF_CONST(3, Instruction::CONST, 15u, 3000),
1455 DEF_APUT(3, Instruction::APUT, 15u, 400u, 401u),
1456 DEF_APUT(3, Instruction::APUT, 15u, 400u, 402u),
1457 DEF_AGET(4, Instruction::AGET, 18u, 400u, 401u), // Differs from 15u and 20u.
1458 DEF_AGET(4, Instruction::AGET, 19u, 400u, 402u), // Same as 18u.
1459 DEF_CONST(4, Instruction::CONST, 20u, 4000),
1460 DEF_APUT(4, Instruction::APUT, 20u, 400u, 401u),
1461 DEF_APUT(4, Instruction::APUT, 20u, 400u, 402u),
1462 DEF_AGET(5, Instruction::AGET, 23u, 400u, 401u), // Differs from 15u and 18u...
1463 DEF_AGET(5, Instruction::AGET, 24u, 400u, 402u), // and same as the CONST 20u.
1464
1465 DEF_UNIQUE_REF(3, Instruction::NEW_ARRAY, 500u),
1466 DEF_AGET(3, Instruction::AGET, 26u, 500u, 501u),
1467 DEF_APUT(4, Instruction::APUT, 27u, 500u, 502u), // Clobbers element at index 501u.
1468 DEF_AGET(5, Instruction::AGET, 28u, 500u, 501u), // Differs from the top.
1469 };
1470
1471 PrepareMIRs(mirs);
1472 PerformGVN();
1473 ASSERT_EQ(arraysize(mirs), value_names_.size());
1474 EXPECT_EQ(value_names_[1], value_names_[2]);
1475 EXPECT_EQ(value_names_[1], value_names_[3]);
1476
1477 EXPECT_NE(value_names_[5], value_names_[6]);
1478 EXPECT_NE(value_names_[5], value_names_[8]);
1479 EXPECT_NE(value_names_[6], value_names_[8]);
1480
1481 EXPECT_NE(value_names_[10], value_names_[12]);
1482 EXPECT_EQ(value_names_[12], value_names_[13]);
1483
1484 EXPECT_NE(value_names_[18], value_names_[15]);
1485 EXPECT_NE(value_names_[18], value_names_[20]);
1486 EXPECT_EQ(value_names_[18], value_names_[19]);
1487 EXPECT_NE(value_names_[23], value_names_[15]);
1488 EXPECT_NE(value_names_[23], value_names_[18]);
1489 EXPECT_EQ(value_names_[23], value_names_[20]);
1490 EXPECT_EQ(value_names_[23], value_names_[24]);
1491
1492 EXPECT_NE(value_names_[26], value_names_[28]);
1493}
1494
1495TEST_F(GlobalValueNumberingTestLoop, AliasingArrays) {
1496 static const MIRDef mirs[] = {
1497 // NOTE: MIRs here are ordered by unique tests. They will be put into appropriate blocks.
1498 DEF_AGET(3, Instruction::AGET_WIDE, 0u, 100u, 101u),
1499 DEF_AGET(4, Instruction::AGET_WIDE, 1u, 100u, 101u), // Same as at the top.
1500 DEF_AGET(5, Instruction::AGET_WIDE, 2u, 100u, 101u), // Same as at the top.
1501
1502 DEF_AGET(3, Instruction::AGET_BYTE, 3u, 200u, 201u),
1503 DEF_AGET(4, Instruction::AGET_BYTE, 4u, 200u, 201u), // Differs from top...
1504 DEF_APUT(4, Instruction::APUT_BYTE, 5u, 200u, 201u), // Because of this IPUT.
1505 DEF_AGET(5, Instruction::AGET_BYTE, 6u, 200u, 201u), // Differs from top and the loop AGET.
1506
1507 DEF_AGET(3, Instruction::AGET, 7u, 300u, 301u),
1508 DEF_APUT(4, Instruction::APUT, 8u, 300u, 301u), // Because of this IPUT...
1509 DEF_AGET(4, Instruction::AGET, 9u, 300u, 301u), // Differs from top.
1510 DEF_AGET(5, Instruction::AGET, 10u, 300u, 301u), // Differs from top but == the loop AGET.
1511
1512 DEF_CONST(3, Instruction::CONST, 11u, 3000),
1513 DEF_APUT(3, Instruction::APUT_CHAR, 11u, 400u, 401u),
1514 DEF_APUT(3, Instruction::APUT_CHAR, 11u, 400u, 402u),
1515 DEF_AGET(4, Instruction::AGET_CHAR, 14u, 400u, 401u), // Differs from 11u and 16u.
1516 DEF_AGET(4, Instruction::AGET_CHAR, 15u, 400u, 402u), // Same as 14u.
1517 DEF_CONST(4, Instruction::CONST, 16u, 4000),
1518 DEF_APUT(4, Instruction::APUT_CHAR, 16u, 400u, 401u),
1519 DEF_APUT(4, Instruction::APUT_CHAR, 16u, 400u, 402u),
1520 DEF_AGET(5, Instruction::AGET_CHAR, 19u, 400u, 401u), // Differs from 11u and 14u...
1521 DEF_AGET(5, Instruction::AGET_CHAR, 20u, 400u, 402u), // and same as the CONST 16u.
1522
1523 DEF_AGET(3, Instruction::AGET_SHORT, 21u, 500u, 501u),
1524 DEF_APUT(4, Instruction::APUT_SHORT, 22u, 500u, 502u), // Clobbers element at index 501u.
1525 DEF_AGET(5, Instruction::AGET_SHORT, 23u, 500u, 501u), // Differs from the top.
1526
1527 DEF_AGET(3, Instruction::AGET_OBJECT, 24u, 600u, 601u),
1528 DEF_APUT(4, Instruction::APUT_OBJECT, 25u, 601u, 602u), // Clobbers 600u/601u.
1529 DEF_AGET(5, Instruction::AGET_OBJECT, 26u, 600u, 601u), // Differs from the top.
1530
1531 DEF_AGET(3, Instruction::AGET_BOOLEAN, 27u, 700u, 701u),
1532 DEF_APUT(4, Instruction::APUT_BOOLEAN, 27u, 701u, 702u), // Storing the same value.
1533 DEF_AGET(5, Instruction::AGET_BOOLEAN, 29u, 700u, 701u), // Differs from the top.
1534 };
1535
1536 PrepareMIRs(mirs);
1537 PerformGVN();
1538 ASSERT_EQ(arraysize(mirs), value_names_.size());
1539 EXPECT_EQ(value_names_[0], value_names_[1]);
1540 EXPECT_EQ(value_names_[0], value_names_[2]);
1541
1542 EXPECT_NE(value_names_[3], value_names_[4]);
1543 EXPECT_NE(value_names_[3], value_names_[6]);
1544 EXPECT_NE(value_names_[4], value_names_[6]);
1545
1546 EXPECT_NE(value_names_[7], value_names_[9]);
1547 EXPECT_EQ(value_names_[9], value_names_[10]);
1548
1549 EXPECT_NE(value_names_[14], value_names_[11]);
1550 EXPECT_NE(value_names_[14], value_names_[16]);
1551 EXPECT_EQ(value_names_[14], value_names_[15]);
1552 EXPECT_NE(value_names_[19], value_names_[11]);
1553 EXPECT_NE(value_names_[19], value_names_[14]);
1554 EXPECT_EQ(value_names_[19], value_names_[16]);
1555 EXPECT_EQ(value_names_[19], value_names_[20]);
1556
1557 EXPECT_NE(value_names_[21], value_names_[23]);
1558
1559 EXPECT_NE(value_names_[24], value_names_[26]);
1560
1561 EXPECT_EQ(value_names_[27], value_names_[29]);
1562}
1563
1564TEST_F(GlobalValueNumberingTestLoop, Phi) {
1565 static const MIRDef mirs[] = {
1566 DEF_CONST(3, Instruction::CONST, 0u, 1000),
1567 DEF_PHI2(4, 1u, 0u, 6u), // Merge CONST 0u (1000) with the same.
1568 DEF_PHI2(4, 2u, 0u, 7u), // Merge CONST 0u (1000) with the Phi itself.
1569 DEF_PHI2(4, 3u, 0u, 8u), // Merge CONST 0u (1000) and CONST 4u (2000).
1570 DEF_PHI2(4, 4u, 0u, 9u), // Merge CONST 0u (1000) and Phi 3u.
1571 DEF_CONST(4, Instruction::CONST, 5u, 2000),
1572 DEF_MOVE(4, Instruction::MOVE, 6u, 0u),
1573 DEF_MOVE(4, Instruction::MOVE, 7u, 2u),
1574 DEF_MOVE(4, Instruction::MOVE, 8u, 5u),
1575 DEF_MOVE(4, Instruction::MOVE, 9u, 3u),
1576 };
1577
1578 PrepareMIRs(mirs);
1579 PerformGVN();
1580 ASSERT_EQ(arraysize(mirs), value_names_.size());
1581 EXPECT_EQ(value_names_[1], value_names_[0]);
1582 EXPECT_EQ(value_names_[2], value_names_[0]);
1583
1584 EXPECT_NE(value_names_[3], value_names_[0]);
1585 EXPECT_NE(value_names_[3], value_names_[5]);
1586 EXPECT_NE(value_names_[4], value_names_[0]);
1587 EXPECT_NE(value_names_[4], value_names_[5]);
1588 EXPECT_NE(value_names_[4], value_names_[3]);
1589}
1590
Vladimir Marko7a01dc22015-01-02 17:00:44 +00001591TEST_F(GlobalValueNumberingTestLoop, IFieldLoopVariable) {
1592 static const IFieldDef ifields[] = {
1593 { 0u, 1u, 0u, false, kDexMemAccessWord },
1594 };
1595 static const MIRDef mirs[] = {
1596 DEF_CONST(3, Instruction::CONST, 0u, 0),
1597 DEF_IPUT(3, Instruction::IPUT, 0u, 100u, 0u),
1598 DEF_IGET(4, Instruction::IGET, 2u, 100u, 0u),
1599 DEF_BINOP(4, Instruction::ADD_INT, 3u, 2u, 101u),
1600 DEF_IPUT(4, Instruction::IPUT, 3u, 100u, 0u),
1601 };
1602
1603 PrepareIFields(ifields);
1604 PrepareMIRs(mirs);
1605 PerformGVN();
1606 ASSERT_EQ(arraysize(mirs), value_names_.size());
1607 EXPECT_NE(value_names_[2], value_names_[0]);
1608 EXPECT_NE(value_names_[3], value_names_[0]);
1609 EXPECT_NE(value_names_[3], value_names_[2]);
1610
1611
1612 // Set up vreg_to_ssa_map_exit for prologue and loop and set post-processing mode
1613 // as needed for GetStartingVregValueNumber().
1614 const int32_t prologue_vreg_to_ssa_map_exit[] = { 0 };
1615 const int32_t loop_vreg_to_ssa_map_exit[] = { 3 };
1616 PrepareVregToSsaMapExit(3, prologue_vreg_to_ssa_map_exit);
1617 PrepareVregToSsaMapExit(4, loop_vreg_to_ssa_map_exit);
1618 gvn_->StartPostProcessing();
1619
1620 // Check that vreg 0 has the same value number as the result of IGET 2u.
1621 const LocalValueNumbering* loop = gvn_->GetLvn(4);
1622 EXPECT_EQ(value_names_[2], loop->GetStartingVregValueNumber(0));
1623}
1624
Vladimir Marko95a05972014-05-30 10:01:32 +01001625TEST_F(GlobalValueNumberingTestCatch, IFields) {
1626 static const IFieldDef ifields[] = {
Vladimir Markoaf6925b2014-10-31 16:37:32 +00001627 { 0u, 1u, 0u, false, kDexMemAccessWord },
1628 { 1u, 1u, 1u, false, kDexMemAccessWord },
Vladimir Marko95a05972014-05-30 10:01:32 +01001629 };
1630 static const MIRDef mirs[] = {
1631 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 200u),
1632 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 201u),
1633 DEF_IGET(3, Instruction::IGET, 2u, 100u, 0u),
1634 DEF_IGET(3, Instruction::IGET, 3u, 200u, 0u),
1635 DEF_IGET(3, Instruction::IGET, 4u, 201u, 0u),
1636 DEF_INVOKE1(4, Instruction::INVOKE_STATIC, 201u), // Clobbering catch, 201u escapes.
1637 DEF_IGET(4, Instruction::IGET, 6u, 100u, 0u), // Differs from IGET 2u.
1638 DEF_IPUT(4, Instruction::IPUT, 6u, 100u, 1u),
1639 DEF_IPUT(4, Instruction::IPUT, 6u, 101u, 0u),
1640 DEF_IPUT(4, Instruction::IPUT, 6u, 200u, 0u),
1641 DEF_IGET(5, Instruction::IGET, 10u, 100u, 0u), // Differs from IGETs 2u and 6u.
1642 DEF_IGET(5, Instruction::IGET, 11u, 200u, 0u), // Same as the top.
1643 DEF_IGET(5, Instruction::IGET, 12u, 201u, 0u), // Differs from the top, 201u escaped.
1644 DEF_IPUT(5, Instruction::IPUT, 10u, 100u, 1u),
1645 DEF_IPUT(5, Instruction::IPUT, 10u, 101u, 0u),
1646 DEF_IPUT(5, Instruction::IPUT, 10u, 200u, 0u),
1647 DEF_IGET(6, Instruction::IGET, 16u, 100u, 0u), // Differs from IGETs 2u, 6u and 10u.
1648 DEF_IGET(6, Instruction::IGET, 17u, 100u, 1u), // Same as IGET 16u.
1649 DEF_IGET(6, Instruction::IGET, 18u, 101u, 0u), // Same as IGET 16u.
1650 DEF_IGET(6, Instruction::IGET, 19u, 200u, 0u), // Same as IGET 16u.
1651 };
1652
1653 PrepareIFields(ifields);
1654 PrepareMIRs(mirs);
1655 PerformGVN();
1656 ASSERT_EQ(arraysize(mirs), value_names_.size());
1657 EXPECT_NE(value_names_[2], value_names_[6]);
1658 EXPECT_NE(value_names_[2], value_names_[10]);
1659 EXPECT_NE(value_names_[6], value_names_[10]);
1660 EXPECT_EQ(value_names_[3], value_names_[11]);
1661 EXPECT_NE(value_names_[4], value_names_[12]);
1662
1663 EXPECT_NE(value_names_[2], value_names_[16]);
1664 EXPECT_NE(value_names_[6], value_names_[16]);
1665 EXPECT_NE(value_names_[10], value_names_[16]);
1666 EXPECT_EQ(value_names_[16], value_names_[17]);
1667 EXPECT_EQ(value_names_[16], value_names_[18]);
1668 EXPECT_EQ(value_names_[16], value_names_[19]);
1669}
1670
1671TEST_F(GlobalValueNumberingTestCatch, SFields) {
1672 static const SFieldDef sfields[] = {
Vladimir Markoaf6925b2014-10-31 16:37:32 +00001673 { 0u, 1u, 0u, false, kDexMemAccessWord },
1674 { 1u, 1u, 1u, false, kDexMemAccessWord },
Vladimir Marko95a05972014-05-30 10:01:32 +01001675 };
1676 static const MIRDef mirs[] = {
1677 DEF_SGET(3, Instruction::SGET, 0u, 0u),
1678 DEF_INVOKE1(4, Instruction::INVOKE_STATIC, 100u), // Clobbering catch.
1679 DEF_SGET(4, Instruction::SGET, 2u, 0u), // Differs from SGET 0u.
1680 DEF_SPUT(4, Instruction::SPUT, 2u, 1u),
1681 DEF_SGET(5, Instruction::SGET, 4u, 0u), // Differs from SGETs 0u and 2u.
1682 DEF_SPUT(5, Instruction::SPUT, 4u, 1u),
1683 DEF_SGET(6, Instruction::SGET, 6u, 0u), // Differs from SGETs 0u, 2u and 4u.
1684 DEF_SGET(6, Instruction::SGET, 7u, 1u), // Same as field #1.
1685 };
1686
1687 PrepareSFields(sfields);
1688 PrepareMIRs(mirs);
1689 PerformGVN();
1690 ASSERT_EQ(arraysize(mirs), value_names_.size());
1691 EXPECT_NE(value_names_[0], value_names_[2]);
1692 EXPECT_NE(value_names_[0], value_names_[4]);
1693 EXPECT_NE(value_names_[2], value_names_[4]);
1694 EXPECT_NE(value_names_[0], value_names_[6]);
1695 EXPECT_NE(value_names_[2], value_names_[6]);
1696 EXPECT_NE(value_names_[4], value_names_[6]);
1697 EXPECT_EQ(value_names_[6], value_names_[7]);
1698}
1699
1700TEST_F(GlobalValueNumberingTestCatch, Arrays) {
1701 static const MIRDef mirs[] = {
1702 DEF_UNIQUE_REF(3, Instruction::NEW_ARRAY, 200u),
1703 DEF_UNIQUE_REF(3, Instruction::NEW_ARRAY, 201u),
1704 DEF_AGET(3, Instruction::AGET, 2u, 100u, 101u),
1705 DEF_AGET(3, Instruction::AGET, 3u, 200u, 202u),
1706 DEF_AGET(3, Instruction::AGET, 4u, 200u, 203u),
1707 DEF_AGET(3, Instruction::AGET, 5u, 201u, 202u),
1708 DEF_AGET(3, Instruction::AGET, 6u, 201u, 203u),
1709 DEF_INVOKE1(4, Instruction::INVOKE_STATIC, 201u), // Clobbering catch, 201u escapes.
1710 DEF_AGET(4, Instruction::AGET, 8u, 100u, 101u), // Differs from AGET 2u.
1711 DEF_APUT(4, Instruction::APUT, 8u, 100u, 102u),
1712 DEF_APUT(4, Instruction::APUT, 8u, 200u, 202u),
1713 DEF_APUT(4, Instruction::APUT, 8u, 200u, 203u),
1714 DEF_APUT(4, Instruction::APUT, 8u, 201u, 202u),
1715 DEF_APUT(4, Instruction::APUT, 8u, 201u, 203u),
1716 DEF_AGET(5, Instruction::AGET, 14u, 100u, 101u), // Differs from AGETs 2u and 8u.
1717 DEF_AGET(5, Instruction::AGET, 15u, 200u, 202u), // Same as AGET 3u.
1718 DEF_AGET(5, Instruction::AGET, 16u, 200u, 203u), // Same as AGET 4u.
1719 DEF_AGET(5, Instruction::AGET, 17u, 201u, 202u), // Differs from AGET 5u.
1720 DEF_AGET(5, Instruction::AGET, 18u, 201u, 203u), // Differs from AGET 6u.
1721 DEF_APUT(5, Instruction::APUT, 14u, 100u, 102u),
1722 DEF_APUT(5, Instruction::APUT, 14u, 200u, 202u),
1723 DEF_APUT(5, Instruction::APUT, 14u, 200u, 203u),
1724 DEF_APUT(5, Instruction::APUT, 14u, 201u, 202u),
1725 DEF_APUT(5, Instruction::APUT, 14u, 201u, 203u),
1726 DEF_AGET(6, Instruction::AGET, 24u, 100u, 101u), // Differs from AGETs 2u, 8u and 14u.
1727 DEF_AGET(6, Instruction::AGET, 25u, 100u, 101u), // Same as AGET 24u.
1728 DEF_AGET(6, Instruction::AGET, 26u, 200u, 202u), // Same as AGET 24u.
1729 DEF_AGET(6, Instruction::AGET, 27u, 200u, 203u), // Same as AGET 24u.
1730 DEF_AGET(6, Instruction::AGET, 28u, 201u, 202u), // Same as AGET 24u.
1731 DEF_AGET(6, Instruction::AGET, 29u, 201u, 203u), // Same as AGET 24u.
1732 };
1733
1734 PrepareMIRs(mirs);
1735 PerformGVN();
1736 ASSERT_EQ(arraysize(mirs), value_names_.size());
1737 EXPECT_NE(value_names_[2], value_names_[8]);
1738 EXPECT_NE(value_names_[2], value_names_[14]);
1739 EXPECT_NE(value_names_[8], value_names_[14]);
1740 EXPECT_EQ(value_names_[3], value_names_[15]);
1741 EXPECT_EQ(value_names_[4], value_names_[16]);
1742 EXPECT_NE(value_names_[5], value_names_[17]);
1743 EXPECT_NE(value_names_[6], value_names_[18]);
1744 EXPECT_NE(value_names_[2], value_names_[24]);
1745 EXPECT_NE(value_names_[8], value_names_[24]);
1746 EXPECT_NE(value_names_[14], value_names_[24]);
1747 EXPECT_EQ(value_names_[24], value_names_[25]);
1748 EXPECT_EQ(value_names_[24], value_names_[26]);
1749 EXPECT_EQ(value_names_[24], value_names_[27]);
1750 EXPECT_EQ(value_names_[24], value_names_[28]);
1751 EXPECT_EQ(value_names_[24], value_names_[29]);
1752}
1753
1754TEST_F(GlobalValueNumberingTestCatch, Phi) {
1755 static const MIRDef mirs[] = {
1756 DEF_CONST(3, Instruction::CONST, 0u, 1000),
1757 DEF_CONST(3, Instruction::CONST, 1u, 2000),
1758 DEF_MOVE(3, Instruction::MOVE, 2u, 1u),
1759 DEF_INVOKE1(4, Instruction::INVOKE_STATIC, 100u), // Clobbering catch.
1760 DEF_CONST(5, Instruction::CONST, 4u, 1000),
1761 DEF_CONST(5, Instruction::CONST, 5u, 3000),
1762 DEF_MOVE(5, Instruction::MOVE, 6u, 5u),
1763 DEF_PHI2(6, 7u, 0u, 4u),
1764 DEF_PHI2(6, 8u, 0u, 5u),
1765 DEF_PHI2(6, 9u, 0u, 6u),
1766 DEF_PHI2(6, 10u, 1u, 4u),
1767 DEF_PHI2(6, 11u, 1u, 5u),
1768 DEF_PHI2(6, 12u, 1u, 6u),
1769 DEF_PHI2(6, 13u, 2u, 4u),
1770 DEF_PHI2(6, 14u, 2u, 5u),
1771 DEF_PHI2(6, 15u, 2u, 6u),
1772 };
1773 PrepareMIRs(mirs);
1774 PerformGVN();
1775 ASSERT_EQ(arraysize(mirs), value_names_.size());
1776 ASSERT_EQ(value_names_[4], value_names_[0]); // Both CONSTs are 1000.
1777 EXPECT_EQ(value_names_[7], value_names_[0]); // Merging CONST 0u and CONST 4u, both 1000.
1778 EXPECT_NE(value_names_[8], value_names_[0]);
1779 EXPECT_NE(value_names_[8], value_names_[5]);
1780 EXPECT_EQ(value_names_[9], value_names_[8]);
1781 EXPECT_NE(value_names_[10], value_names_[1]);
1782 EXPECT_NE(value_names_[10], value_names_[4]);
1783 EXPECT_NE(value_names_[10], value_names_[8]);
1784 EXPECT_NE(value_names_[11], value_names_[1]);
1785 EXPECT_NE(value_names_[11], value_names_[5]);
1786 EXPECT_NE(value_names_[11], value_names_[8]);
1787 EXPECT_NE(value_names_[11], value_names_[10]);
1788 EXPECT_EQ(value_names_[12], value_names_[11]);
1789 EXPECT_EQ(value_names_[13], value_names_[10]);
1790 EXPECT_EQ(value_names_[14], value_names_[11]);
1791 EXPECT_EQ(value_names_[15], value_names_[11]);
1792}
1793
1794TEST_F(GlobalValueNumberingTest, NullCheckIFields) {
1795 static const IFieldDef ifields[] = {
Vladimir Markoaf6925b2014-10-31 16:37:32 +00001796 { 0u, 1u, 0u, false, kDexMemAccessObject }, // Object.
1797 { 1u, 1u, 1u, false, kDexMemAccessObject }, // Object.
Vladimir Marko95a05972014-05-30 10:01:32 +01001798 };
1799 static const BBDef bbs[] = {
1800 DEF_BB(kNullBlock, DEF_SUCC0(), DEF_PRED0()),
1801 DEF_BB(kEntryBlock, DEF_SUCC1(3), DEF_PRED0()),
1802 DEF_BB(kExitBlock, DEF_SUCC0(), DEF_PRED1(5)),
1803 DEF_BB(kDalvikByteCode, DEF_SUCC2(4, 5), DEF_PRED1(1)), // 4 is fall-through, 5 is taken.
1804 DEF_BB(kDalvikByteCode, DEF_SUCC1(5), DEF_PRED1(3)),
1805 DEF_BB(kDalvikByteCode, DEF_SUCC1(2), DEF_PRED2(3, 4)),
1806 };
1807 static const MIRDef mirs[] = {
1808 DEF_IGET(3, Instruction::IGET_OBJECT, 0u, 100u, 0u),
1809 DEF_IGET(3, Instruction::IGET_OBJECT, 1u, 100u, 1u),
1810 DEF_IGET(3, Instruction::IGET_OBJECT, 2u, 101u, 0u),
1811 DEF_IFZ(3, Instruction::IF_NEZ, 0u), // Null-check for field #0 for taken.
1812 DEF_UNIQUE_REF(4, Instruction::NEW_ARRAY, 4u),
1813 DEF_IPUT(4, Instruction::IPUT_OBJECT, 4u, 100u, 0u),
1814 DEF_IPUT(4, Instruction::IPUT_OBJECT, 4u, 100u, 1u),
1815 DEF_IPUT(4, Instruction::IPUT_OBJECT, 4u, 101u, 0u),
1816 DEF_IGET(5, Instruction::IGET_OBJECT, 8u, 100u, 0u), // 100u/#0, IF_NEZ/NEW_ARRAY.
1817 DEF_IGET(5, Instruction::IGET_OBJECT, 9u, 100u, 1u), // 100u/#1, -/NEW_ARRAY.
1818 DEF_IGET(5, Instruction::IGET_OBJECT, 10u, 101u, 0u), // 101u/#0, -/NEW_ARRAY.
1819 DEF_CONST(5, Instruction::CONST, 11u, 0),
1820 DEF_AGET(5, Instruction::AGET, 12u, 8u, 11u), // Null-check eliminated.
1821 DEF_AGET(5, Instruction::AGET, 13u, 9u, 11u), // Null-check kept.
1822 DEF_AGET(5, Instruction::AGET, 14u, 10u, 11u), // Null-check kept.
1823 };
1824 static const bool expected_ignore_null_check[] = {
1825 false, true, false, false, // BB #3; unimportant.
1826 false, true, true, true, // BB #4; unimportant.
1827 true, true, true, false, true, false, false, // BB #5; only the last three are important.
1828 };
1829
1830 PrepareIFields(ifields);
1831 PrepareBasicBlocks(bbs);
1832 PrepareMIRs(mirs);
1833 PerformGVN();
1834 ASSERT_EQ(arraysize(mirs), value_names_.size());
1835 PerformGVNCodeModifications();
1836 ASSERT_EQ(arraysize(expected_ignore_null_check), mir_count_);
1837 for (size_t i = 0u; i != arraysize(mirs); ++i) {
1838 EXPECT_EQ(expected_ignore_null_check[i],
1839 (mirs_[i].optimization_flags & MIR_IGNORE_NULL_CHECK) != 0) << i;
1840 }
1841}
1842
1843TEST_F(GlobalValueNumberingTest, NullCheckSFields) {
1844 static const SFieldDef sfields[] = {
Vladimir Markoaf6925b2014-10-31 16:37:32 +00001845 { 0u, 1u, 0u, false, kDexMemAccessObject },
1846 { 1u, 1u, 1u, false, kDexMemAccessObject },
Vladimir Marko95a05972014-05-30 10:01:32 +01001847 };
1848 static const BBDef bbs[] = {
1849 DEF_BB(kNullBlock, DEF_SUCC0(), DEF_PRED0()),
1850 DEF_BB(kEntryBlock, DEF_SUCC1(3), DEF_PRED0()),
1851 DEF_BB(kExitBlock, DEF_SUCC0(), DEF_PRED1(5)),
1852 DEF_BB(kDalvikByteCode, DEF_SUCC2(4, 5), DEF_PRED1(1)), // 4 is fall-through, 5 is taken.
1853 DEF_BB(kDalvikByteCode, DEF_SUCC1(5), DEF_PRED1(3)),
1854 DEF_BB(kDalvikByteCode, DEF_SUCC1(2), DEF_PRED2(3, 4)),
1855 };
1856 static const MIRDef mirs[] = {
1857 DEF_SGET(3, Instruction::SGET_OBJECT, 0u, 0u),
1858 DEF_SGET(3, Instruction::SGET_OBJECT, 1u, 1u),
1859 DEF_IFZ(3, Instruction::IF_NEZ, 0u), // Null-check for field #0 for taken.
1860 DEF_UNIQUE_REF(4, Instruction::NEW_ARRAY, 3u),
1861 DEF_SPUT(4, Instruction::SPUT_OBJECT, 3u, 0u),
1862 DEF_SPUT(4, Instruction::SPUT_OBJECT, 3u, 1u),
1863 DEF_SGET(5, Instruction::SGET_OBJECT, 6u, 0u), // Field #0 is null-checked, IF_NEZ/NEW_ARRAY.
1864 DEF_SGET(5, Instruction::SGET_OBJECT, 7u, 1u), // Field #1 is not null-checked, -/NEW_ARRAY.
1865 DEF_CONST(5, Instruction::CONST, 8u, 0),
1866 DEF_AGET(5, Instruction::AGET, 9u, 6u, 8u), // Null-check eliminated.
1867 DEF_AGET(5, Instruction::AGET, 10u, 7u, 8u), // Null-check kept.
1868 };
1869 static const bool expected_ignore_null_check[] = {
1870 false, false, false, false, false, false, false, false, false, true, false
1871 };
1872
1873 PrepareSFields(sfields);
1874 PrepareBasicBlocks(bbs);
1875 PrepareMIRs(mirs);
1876 PerformGVN();
1877 ASSERT_EQ(arraysize(mirs), value_names_.size());
1878 PerformGVNCodeModifications();
1879 ASSERT_EQ(arraysize(expected_ignore_null_check), mir_count_);
1880 for (size_t i = 0u; i != arraysize(mirs); ++i) {
1881 EXPECT_EQ(expected_ignore_null_check[i],
1882 (mirs_[i].optimization_flags & MIR_IGNORE_NULL_CHECK) != 0) << i;
1883 }
1884}
1885
1886TEST_F(GlobalValueNumberingTest, NullCheckArrays) {
1887 static const BBDef bbs[] = {
1888 DEF_BB(kNullBlock, DEF_SUCC0(), DEF_PRED0()),
1889 DEF_BB(kEntryBlock, DEF_SUCC1(3), DEF_PRED0()),
1890 DEF_BB(kExitBlock, DEF_SUCC0(), DEF_PRED1(5)),
1891 DEF_BB(kDalvikByteCode, DEF_SUCC2(4, 5), DEF_PRED1(1)), // 4 is fall-through, 5 is taken.
1892 DEF_BB(kDalvikByteCode, DEF_SUCC1(5), DEF_PRED1(3)),
1893 DEF_BB(kDalvikByteCode, DEF_SUCC1(2), DEF_PRED2(3, 4)),
1894 };
1895 static const MIRDef mirs[] = {
1896 DEF_AGET(3, Instruction::AGET_OBJECT, 0u, 100u, 102u),
1897 DEF_AGET(3, Instruction::AGET_OBJECT, 1u, 100u, 103u),
1898 DEF_AGET(3, Instruction::AGET_OBJECT, 2u, 101u, 102u),
1899 DEF_IFZ(3, Instruction::IF_NEZ, 0u), // Null-check for field #0 for taken.
1900 DEF_UNIQUE_REF(4, Instruction::NEW_ARRAY, 4u),
1901 DEF_APUT(4, Instruction::APUT_OBJECT, 4u, 100u, 102u),
1902 DEF_APUT(4, Instruction::APUT_OBJECT, 4u, 100u, 103u),
1903 DEF_APUT(4, Instruction::APUT_OBJECT, 4u, 101u, 102u),
1904 DEF_AGET(5, Instruction::AGET_OBJECT, 8u, 100u, 102u), // Null-checked, IF_NEZ/NEW_ARRAY.
1905 DEF_AGET(5, Instruction::AGET_OBJECT, 9u, 100u, 103u), // Not null-checked, -/NEW_ARRAY.
1906 DEF_AGET(5, Instruction::AGET_OBJECT, 10u, 101u, 102u), // Not null-checked, -/NEW_ARRAY.
1907 DEF_CONST(5, Instruction::CONST, 11u, 0),
1908 DEF_AGET(5, Instruction::AGET, 12u, 8u, 11u), // Null-check eliminated.
1909 DEF_AGET(5, Instruction::AGET, 13u, 9u, 11u), // Null-check kept.
1910 DEF_AGET(5, Instruction::AGET, 14u, 10u, 11u), // Null-check kept.
1911 };
1912 static const bool expected_ignore_null_check[] = {
1913 false, true, false, false, // BB #3; unimportant.
1914 false, true, true, true, // BB #4; unimportant.
1915 true, true, true, false, true, false, false, // BB #5; only the last three are important.
1916 };
1917
1918 PrepareBasicBlocks(bbs);
1919 PrepareMIRs(mirs);
1920 PerformGVN();
1921 ASSERT_EQ(arraysize(mirs), value_names_.size());
1922 PerformGVNCodeModifications();
1923 ASSERT_EQ(arraysize(expected_ignore_null_check), mir_count_);
1924 for (size_t i = 0u; i != arraysize(mirs); ++i) {
1925 EXPECT_EQ(expected_ignore_null_check[i],
1926 (mirs_[i].optimization_flags & MIR_IGNORE_NULL_CHECK) != 0) << i;
1927 }
1928}
1929
1930TEST_F(GlobalValueNumberingTestDiamond, RangeCheckArrays) {
1931 // NOTE: We don't merge range checks when we merge value names for Phis or memory locations.
1932 static const MIRDef mirs[] = {
1933 DEF_AGET(4, Instruction::AGET, 0u, 100u, 101u),
1934 DEF_AGET(5, Instruction::AGET, 1u, 100u, 101u),
1935 DEF_APUT(6, Instruction::APUT, 2u, 100u, 101u),
1936
1937 DEF_AGET(4, Instruction::AGET, 3u, 200u, 201u),
1938 DEF_AGET(5, Instruction::AGET, 4u, 200u, 202u),
1939 DEF_APUT(6, Instruction::APUT, 5u, 200u, 201u),
1940
1941 DEF_AGET(4, Instruction::AGET, 6u, 300u, 302u),
1942 DEF_AGET(5, Instruction::AGET, 7u, 301u, 302u),
1943 DEF_APUT(6, Instruction::APUT, 8u, 300u, 302u),
1944 };
1945 static const bool expected_ignore_null_check[] = {
1946 false, false, true,
1947 false, false, true,
1948 false, false, false,
1949 };
1950 static const bool expected_ignore_range_check[] = {
1951 false, false, true,
1952 false, false, false,
1953 false, false, false,
1954 };
1955
1956 PrepareMIRs(mirs);
1957 PerformGVN();
1958 ASSERT_EQ(arraysize(mirs), value_names_.size());
1959 PerformGVNCodeModifications();
1960 ASSERT_EQ(arraysize(expected_ignore_null_check), mir_count_);
1961 ASSERT_EQ(arraysize(expected_ignore_range_check), mir_count_);
1962 for (size_t i = 0u; i != arraysize(mirs); ++i) {
1963 EXPECT_EQ(expected_ignore_null_check[i],
1964 (mirs_[i].optimization_flags & MIR_IGNORE_NULL_CHECK) != 0) << i;
1965 EXPECT_EQ(expected_ignore_range_check[i],
1966 (mirs_[i].optimization_flags & MIR_IGNORE_RANGE_CHECK) != 0) << i;
1967 }
1968}
1969
1970TEST_F(GlobalValueNumberingTestDiamond, MergeSameValueInDifferentMemoryLocations) {
1971 static const IFieldDef ifields[] = {
Vladimir Markoaf6925b2014-10-31 16:37:32 +00001972 { 0u, 1u, 0u, false, kDexMemAccessWord },
1973 { 1u, 1u, 1u, false, kDexMemAccessWord },
Vladimir Marko95a05972014-05-30 10:01:32 +01001974 };
1975 static const SFieldDef sfields[] = {
Vladimir Markoaf6925b2014-10-31 16:37:32 +00001976 { 0u, 1u, 0u, false, kDexMemAccessWord },
1977 { 1u, 1u, 1u, false, kDexMemAccessWord },
Vladimir Marko95a05972014-05-30 10:01:32 +01001978 };
1979 static const MIRDef mirs[] = {
1980 DEF_UNIQUE_REF(3, Instruction::NEW_INSTANCE, 100u),
1981 DEF_UNIQUE_REF(3, Instruction::NEW_ARRAY, 200u),
1982 DEF_CONST(4, Instruction::CONST, 2u, 1000),
1983 DEF_IPUT(4, Instruction::IPUT, 2u, 100u, 0u),
1984 DEF_IPUT(4, Instruction::IPUT, 2u, 100u, 1u),
1985 DEF_IPUT(4, Instruction::IPUT, 2u, 101u, 0u),
1986 DEF_APUT(4, Instruction::APUT, 2u, 200u, 202u),
1987 DEF_APUT(4, Instruction::APUT, 2u, 200u, 203u),
1988 DEF_APUT(4, Instruction::APUT, 2u, 201u, 202u),
1989 DEF_APUT(4, Instruction::APUT, 2u, 201u, 203u),
1990 DEF_SPUT(4, Instruction::SPUT, 2u, 0u),
1991 DEF_SPUT(4, Instruction::SPUT, 2u, 1u),
1992 DEF_CONST(5, Instruction::CONST, 12u, 2000),
1993 DEF_IPUT(5, Instruction::IPUT, 12u, 100u, 0u),
1994 DEF_IPUT(5, Instruction::IPUT, 12u, 100u, 1u),
1995 DEF_IPUT(5, Instruction::IPUT, 12u, 101u, 0u),
1996 DEF_APUT(5, Instruction::APUT, 12u, 200u, 202u),
1997 DEF_APUT(5, Instruction::APUT, 12u, 200u, 203u),
1998 DEF_APUT(5, Instruction::APUT, 12u, 201u, 202u),
1999 DEF_APUT(5, Instruction::APUT, 12u, 201u, 203u),
2000 DEF_SPUT(5, Instruction::SPUT, 12u, 0u),
2001 DEF_SPUT(5, Instruction::SPUT, 12u, 1u),
2002 DEF_PHI2(6, 22u, 2u, 12u),
2003 DEF_IGET(6, Instruction::IGET, 23u, 100u, 0u),
2004 DEF_IGET(6, Instruction::IGET, 24u, 100u, 1u),
2005 DEF_IGET(6, Instruction::IGET, 25u, 101u, 0u),
2006 DEF_AGET(6, Instruction::AGET, 26u, 200u, 202u),
2007 DEF_AGET(6, Instruction::AGET, 27u, 200u, 203u),
2008 DEF_AGET(6, Instruction::AGET, 28u, 201u, 202u),
2009 DEF_AGET(6, Instruction::AGET, 29u, 201u, 203u),
2010 DEF_SGET(6, Instruction::SGET, 30u, 0u),
2011 DEF_SGET(6, Instruction::SGET, 31u, 1u),
2012 };
2013 PrepareIFields(ifields);
2014 PrepareSFields(sfields);
2015 PrepareMIRs(mirs);
2016 PerformGVN();
2017 ASSERT_EQ(arraysize(mirs), value_names_.size());
2018 EXPECT_NE(value_names_[2], value_names_[12]);
2019 EXPECT_NE(value_names_[2], value_names_[22]);
2020 EXPECT_NE(value_names_[12], value_names_[22]);
2021 for (size_t i = 23; i != arraysize(mirs); ++i) {
2022 EXPECT_EQ(value_names_[22], value_names_[i]) << i;
2023 }
2024}
2025
2026TEST_F(GlobalValueNumberingTest, InfiniteLocationLoop) {
2027 // This is a pattern that lead to an infinite loop during the GVN development. This has been
2028 // fixed by rewriting the merging of AliasingValues to merge only locations read from or
2029 // written to in each incoming LVN rather than merging all locations read from or written to
2030 // in any incoming LVN. It also showed up only when the GVN used the DFS ordering instead of
2031 // the "topological" ordering but, since the "topological" ordering is not really topological
2032 // when there are cycles and an optimizing Java compiler (or a tool like proguard) could
2033 // theoretically create any sort of flow graph, this could have shown up in real code.
2034 //
2035 // While we were merging all the locations:
2036 // The first time the Phi evaluates to the same value name as CONST 0u. After the second
2037 // evaluation, when the BB #9 has been processed, the Phi receives its own value name.
2038 // However, the index from the first evaluation keeps disappearing and reappearing in the
2039 // LVN's aliasing_array_value_map_'s load_value_map for BBs #9, #4, #5, #7 because of the
2040 // DFS ordering of LVN evaluation.
2041 static const IFieldDef ifields[] = {
Vladimir Markoaf6925b2014-10-31 16:37:32 +00002042 { 0u, 1u, 0u, false, kDexMemAccessObject },
Vladimir Marko95a05972014-05-30 10:01:32 +01002043 };
2044 static const BBDef bbs[] = {
2045 DEF_BB(kNullBlock, DEF_SUCC0(), DEF_PRED0()),
2046 DEF_BB(kEntryBlock, DEF_SUCC1(3), DEF_PRED0()),
2047 DEF_BB(kExitBlock, DEF_SUCC0(), DEF_PRED1(4)),
2048 DEF_BB(kDalvikByteCode, DEF_SUCC1(4), DEF_PRED1(1)),
2049 DEF_BB(kDalvikByteCode, DEF_SUCC2(5, 2), DEF_PRED2(3, 9)),
2050 DEF_BB(kDalvikByteCode, DEF_SUCC2(6, 7), DEF_PRED1(4)),
2051 DEF_BB(kDalvikByteCode, DEF_SUCC1(9), DEF_PRED1(5)),
2052 DEF_BB(kDalvikByteCode, DEF_SUCC2(8, 9), DEF_PRED1(5)),
2053 DEF_BB(kDalvikByteCode, DEF_SUCC1(9), DEF_PRED1(7)),
2054 DEF_BB(kDalvikByteCode, DEF_SUCC1(4), DEF_PRED3(6, 7, 8)),
2055 };
2056 static const MIRDef mirs[] = {
2057 DEF_CONST(3, Instruction::CONST, 0u, 0),
2058 DEF_PHI2(4, 1u, 0u, 10u),
2059 DEF_INVOKE1(6, Instruction::INVOKE_STATIC, 100u),
2060 DEF_IGET(6, Instruction::IGET_OBJECT, 3u, 100u, 0u),
2061 DEF_CONST(6, Instruction::CONST, 4u, 1000),
2062 DEF_APUT(6, Instruction::APUT, 4u, 3u, 1u), // Index is Phi 1u.
2063 DEF_INVOKE1(8, Instruction::INVOKE_STATIC, 100u),
2064 DEF_IGET(8, Instruction::IGET_OBJECT, 7u, 100u, 0u),
2065 DEF_CONST(8, Instruction::CONST, 8u, 2000),
2066 DEF_APUT(8, Instruction::APUT, 9u, 7u, 1u), // Index is Phi 1u.
2067 DEF_CONST(9, Instruction::CONST, 10u, 3000),
2068 };
2069 PrepareIFields(ifields);
2070 PrepareBasicBlocks(bbs);
2071 PrepareMIRs(mirs);
2072 // Using DFS order for this test. The GVN result should not depend on the used ordering
2073 // once the GVN actually converges. But creating a test for this convergence issue with
2074 // the topological ordering could be a very challenging task.
2075 PerformPreOrderDfsGVN();
2076}
2077
Vladimir Marko55fff042014-07-10 12:42:52 +01002078TEST_F(GlobalValueNumberingTestTwoConsecutiveLoops, IFieldAndPhi) {
Vladimir Marko95a05972014-05-30 10:01:32 +01002079 static const IFieldDef ifields[] = {
Vladimir Markoaf6925b2014-10-31 16:37:32 +00002080 { 0u, 1u, 0u, false, kDexMemAccessObject },
Vladimir Marko95a05972014-05-30 10:01:32 +01002081 };
2082 static const MIRDef mirs[] = {
2083 DEF_MOVE(3, Instruction::MOVE_OBJECT, 0u, 100u),
2084 DEF_IPUT(3, Instruction::IPUT_OBJECT, 0u, 200u, 0u),
2085 DEF_PHI2(4, 2u, 0u, 3u),
2086 DEF_MOVE(5, Instruction::MOVE_OBJECT, 3u, 300u),
2087 DEF_IPUT(5, Instruction::IPUT_OBJECT, 3u, 200u, 0u),
2088 DEF_MOVE(6, Instruction::MOVE_OBJECT, 5u, 2u),
2089 DEF_IGET(6, Instruction::IGET_OBJECT, 6u, 200u, 0u),
2090 DEF_MOVE(7, Instruction::MOVE_OBJECT, 7u, 5u),
2091 DEF_IGET(7, Instruction::IGET_OBJECT, 8u, 200u, 0u),
2092 DEF_MOVE(8, Instruction::MOVE_OBJECT, 9u, 5u),
2093 DEF_IGET(8, Instruction::IGET_OBJECT, 10u, 200u, 0u),
2094 DEF_MOVE(9, Instruction::MOVE_OBJECT, 11u, 5u),
2095 DEF_IGET(9, Instruction::IGET_OBJECT, 12u, 200u, 0u),
2096 };
2097
2098 PrepareIFields(ifields);
2099 PrepareMIRs(mirs);
2100 PerformGVN();
2101 ASSERT_EQ(arraysize(mirs), value_names_.size());
2102 EXPECT_NE(value_names_[0], value_names_[3]);
2103 EXPECT_NE(value_names_[0], value_names_[2]);
2104 EXPECT_NE(value_names_[3], value_names_[2]);
2105 EXPECT_EQ(value_names_[2], value_names_[5]);
2106 EXPECT_EQ(value_names_[5], value_names_[6]);
2107 EXPECT_EQ(value_names_[5], value_names_[7]);
2108 EXPECT_EQ(value_names_[5], value_names_[8]);
2109 EXPECT_EQ(value_names_[5], value_names_[9]);
2110 EXPECT_EQ(value_names_[5], value_names_[10]);
2111 EXPECT_EQ(value_names_[5], value_names_[11]);
2112 EXPECT_EQ(value_names_[5], value_names_[12]);
2113}
2114
Vladimir Marko55fff042014-07-10 12:42:52 +01002115TEST_F(GlobalValueNumberingTestTwoConsecutiveLoops, NullCheck) {
Vladimir Marko95a05972014-05-30 10:01:32 +01002116 static const IFieldDef ifields[] = {
Vladimir Markoaf6925b2014-10-31 16:37:32 +00002117 { 0u, 1u, 0u, false, kDexMemAccessObject },
Vladimir Marko95a05972014-05-30 10:01:32 +01002118 };
2119 static const SFieldDef sfields[] = {
Vladimir Markoaf6925b2014-10-31 16:37:32 +00002120 { 0u, 1u, 0u, false, kDexMemAccessObject },
Vladimir Marko95a05972014-05-30 10:01:32 +01002121 };
2122 static const MIRDef mirs[] = {
2123 DEF_MOVE(3, Instruction::MOVE_OBJECT, 0u, 100u),
2124 DEF_IGET(3, Instruction::IGET_OBJECT, 1u, 200u, 0u),
2125 DEF_SGET(3, Instruction::SGET_OBJECT, 2u, 0u),
2126 DEF_AGET(3, Instruction::AGET_OBJECT, 3u, 300u, 201u),
2127 DEF_PHI2(4, 4u, 0u, 8u),
2128 DEF_IGET(5, Instruction::IGET_OBJECT, 5u, 200u, 0u),
2129 DEF_SGET(5, Instruction::SGET_OBJECT, 6u, 0u),
2130 DEF_AGET(5, Instruction::AGET_OBJECT, 7u, 300u, 201u),
2131 DEF_MOVE(5, Instruction::MOVE_OBJECT, 8u, 400u),
2132 DEF_IPUT(5, Instruction::IPUT_OBJECT, 4u, 200u, 0u), // PUT the Phi 4u.
2133 DEF_SPUT(5, Instruction::SPUT_OBJECT, 4u, 0u), // PUT the Phi 4u.
2134 DEF_APUT(5, Instruction::APUT_OBJECT, 4u, 300u, 201u), // PUT the Phi 4u.
2135 DEF_MOVE(6, Instruction::MOVE_OBJECT, 12u, 4u),
2136 DEF_IGET(6, Instruction::IGET_OBJECT, 13u, 200u, 0u),
2137 DEF_SGET(6, Instruction::SGET_OBJECT, 14u, 0u),
2138 DEF_AGET(6, Instruction::AGET_OBJECT, 15u, 300u, 201u),
2139 DEF_AGET(6, Instruction::AGET_OBJECT, 16u, 12u, 600u),
2140 DEF_AGET(6, Instruction::AGET_OBJECT, 17u, 13u, 600u),
2141 DEF_AGET(6, Instruction::AGET_OBJECT, 18u, 14u, 600u),
2142 DEF_AGET(6, Instruction::AGET_OBJECT, 19u, 15u, 600u),
2143 DEF_MOVE(8, Instruction::MOVE_OBJECT, 20u, 12u),
2144 DEF_IGET(8, Instruction::IGET_OBJECT, 21u, 200u, 0u),
2145 DEF_SGET(8, Instruction::SGET_OBJECT, 22u, 0u),
2146 DEF_AGET(8, Instruction::AGET_OBJECT, 23u, 300u, 201u),
2147 DEF_AGET(8, Instruction::AGET_OBJECT, 24u, 12u, 600u),
2148 DEF_AGET(8, Instruction::AGET_OBJECT, 25u, 13u, 600u),
2149 DEF_AGET(8, Instruction::AGET_OBJECT, 26u, 14u, 600u),
2150 DEF_AGET(8, Instruction::AGET_OBJECT, 27u, 15u, 600u),
2151 DEF_MOVE(9, Instruction::MOVE_OBJECT, 28u, 12u),
2152 DEF_IGET(9, Instruction::IGET_OBJECT, 29u, 200u, 0u),
2153 DEF_SGET(9, Instruction::SGET_OBJECT, 30u, 0u),
2154 DEF_AGET(9, Instruction::AGET_OBJECT, 31u, 300u, 201u),
2155 DEF_AGET(9, Instruction::AGET_OBJECT, 32u, 12u, 600u),
2156 DEF_AGET(9, Instruction::AGET_OBJECT, 33u, 13u, 600u),
2157 DEF_AGET(9, Instruction::AGET_OBJECT, 34u, 14u, 600u),
2158 DEF_AGET(9, Instruction::AGET_OBJECT, 35u, 15u, 600u),
2159 };
2160 static const bool expected_ignore_null_check[] = {
2161 false, false, false, false, // BB #3.
2162 false, true, false, true, false, true, false, true, // BBs #4 and #5.
2163 false, true, false, true, false, false, false, false, // BB #6.
2164 false, true, false, true, true, true, true, true, // BB #7.
2165 false, true, false, true, true, true, true, true, // BB #8.
2166 };
2167 static const bool expected_ignore_range_check[] = {
2168 false, false, false, false, // BB #3.
2169 false, false, false, true, false, false, false, true, // BBs #4 and #5.
2170 false, false, false, true, false, false, false, false, // BB #6.
2171 false, false, false, true, true, true, true, true, // BB #7.
2172 false, false, false, true, true, true, true, true, // BB #8.
2173 };
2174
2175 PrepareIFields(ifields);
2176 PrepareSFields(sfields);
2177 PrepareMIRs(mirs);
2178 PerformGVN();
2179 ASSERT_EQ(arraysize(mirs), value_names_.size());
2180 EXPECT_NE(value_names_[0], value_names_[4]);
2181 EXPECT_NE(value_names_[1], value_names_[5]);
2182 EXPECT_NE(value_names_[2], value_names_[6]);
2183 EXPECT_NE(value_names_[3], value_names_[7]);
2184 EXPECT_NE(value_names_[4], value_names_[8]);
Vladimir Marko95a05972014-05-30 10:01:32 +01002185 EXPECT_EQ(value_names_[4], value_names_[12]);
Vladimir Marko55fff042014-07-10 12:42:52 +01002186 EXPECT_EQ(value_names_[5], value_names_[13]);
2187 EXPECT_EQ(value_names_[6], value_names_[14]);
2188 EXPECT_EQ(value_names_[7], value_names_[15]);
Vladimir Marko95a05972014-05-30 10:01:32 +01002189 EXPECT_EQ(value_names_[12], value_names_[20]);
2190 EXPECT_EQ(value_names_[13], value_names_[21]);
2191 EXPECT_EQ(value_names_[14], value_names_[22]);
2192 EXPECT_EQ(value_names_[15], value_names_[23]);
2193 EXPECT_EQ(value_names_[12], value_names_[28]);
2194 EXPECT_EQ(value_names_[13], value_names_[29]);
2195 EXPECT_EQ(value_names_[14], value_names_[30]);
2196 EXPECT_EQ(value_names_[15], value_names_[31]);
2197 PerformGVNCodeModifications();
2198 for (size_t i = 0u; i != arraysize(mirs); ++i) {
2199 EXPECT_EQ(expected_ignore_null_check[i],
2200 (mirs_[i].optimization_flags & MIR_IGNORE_NULL_CHECK) != 0) << i;
2201 EXPECT_EQ(expected_ignore_range_check[i],
2202 (mirs_[i].optimization_flags & MIR_IGNORE_RANGE_CHECK) != 0) << i;
2203 }
2204}
2205
Vladimir Marko55fff042014-07-10 12:42:52 +01002206TEST_F(GlobalValueNumberingTestTwoNestedLoops, IFieldAndPhi) {
Vladimir Marko95a05972014-05-30 10:01:32 +01002207 static const IFieldDef ifields[] = {
Vladimir Markoaf6925b2014-10-31 16:37:32 +00002208 { 0u, 1u, 0u, false, kDexMemAccessObject },
Vladimir Marko95a05972014-05-30 10:01:32 +01002209 };
2210 static const MIRDef mirs[] = {
2211 DEF_MOVE(3, Instruction::MOVE_OBJECT, 0u, 100u),
2212 DEF_IPUT(3, Instruction::IPUT_OBJECT, 0u, 200u, 0u),
2213 DEF_PHI2(4, 2u, 0u, 11u),
2214 DEF_MOVE(4, Instruction::MOVE_OBJECT, 3u, 2u),
2215 DEF_IGET(4, Instruction::IGET_OBJECT, 4u, 200u, 0u),
2216 DEF_MOVE(5, Instruction::MOVE_OBJECT, 5u, 3u),
2217 DEF_IGET(5, Instruction::IGET_OBJECT, 6u, 200u, 0u),
2218 DEF_MOVE(6, Instruction::MOVE_OBJECT, 7u, 3u),
2219 DEF_IGET(6, Instruction::IGET_OBJECT, 8u, 200u, 0u),
2220 DEF_MOVE(7, Instruction::MOVE_OBJECT, 9u, 3u),
2221 DEF_IGET(7, Instruction::IGET_OBJECT, 10u, 200u, 0u),
2222 DEF_MOVE(7, Instruction::MOVE_OBJECT, 11u, 300u),
2223 DEF_IPUT(7, Instruction::IPUT_OBJECT, 11u, 200u, 0u),
2224 DEF_MOVE(8, Instruction::MOVE_OBJECT, 13u, 3u),
2225 DEF_IGET(8, Instruction::IGET_OBJECT, 14u, 200u, 0u),
2226 };
2227
2228 PrepareIFields(ifields);
2229 PrepareMIRs(mirs);
2230 PerformGVN();
2231 ASSERT_EQ(arraysize(mirs), value_names_.size());
2232 EXPECT_NE(value_names_[0], value_names_[11]);
2233 EXPECT_NE(value_names_[0], value_names_[2]);
2234 EXPECT_NE(value_names_[11], value_names_[2]);
2235 EXPECT_EQ(value_names_[2], value_names_[3]);
2236 EXPECT_EQ(value_names_[3], value_names_[4]);
2237 EXPECT_EQ(value_names_[3], value_names_[5]);
2238 EXPECT_EQ(value_names_[3], value_names_[6]);
2239 EXPECT_EQ(value_names_[3], value_names_[7]);
2240 EXPECT_EQ(value_names_[3], value_names_[8]);
2241 EXPECT_EQ(value_names_[3], value_names_[9]);
2242 EXPECT_EQ(value_names_[3], value_names_[10]);
2243 EXPECT_EQ(value_names_[3], value_names_[13]);
2244 EXPECT_EQ(value_names_[3], value_names_[14]);
2245}
2246
Vladimir Marko11ca6122014-07-17 20:50:07 +01002247TEST_F(GlobalValueNumberingTest, NormalPathToCatchEntry) {
2248 // When there's an empty catch block, all the exception paths lead to the next block in
2249 // the normal path and we can also have normal "taken" or "fall-through" branches to that
2250 // path. Check that LocalValueNumbering::PruneNonAliasingRefsForCatch() can handle it.
2251 static const BBDef bbs[] = {
2252 DEF_BB(kNullBlock, DEF_SUCC0(), DEF_PRED0()),
2253 DEF_BB(kEntryBlock, DEF_SUCC1(3), DEF_PRED0()),
Vladimir Marko55fff042014-07-10 12:42:52 +01002254 DEF_BB(kExitBlock, DEF_SUCC0(), DEF_PRED1(5)),
Vladimir Marko11ca6122014-07-17 20:50:07 +01002255 DEF_BB(kDalvikByteCode, DEF_SUCC1(4), DEF_PRED1(1)),
2256 DEF_BB(kDalvikByteCode, DEF_SUCC1(5), DEF_PRED1(3)),
2257 DEF_BB(kDalvikByteCode, DEF_SUCC1(2), DEF_PRED2(3, 4)),
2258 };
2259 static const MIRDef mirs[] = {
2260 DEF_INVOKE1(4, Instruction::INVOKE_STATIC, 100u),
2261 };
2262 PrepareBasicBlocks(bbs);
2263 BasicBlock* catch_handler = cu_.mir_graph->GetBasicBlock(5u);
2264 catch_handler->catch_entry = true;
Vladimir Marko55fff042014-07-10 12:42:52 +01002265 // Add successor block info to the check block.
2266 BasicBlock* check_bb = cu_.mir_graph->GetBasicBlock(3u);
2267 check_bb->successor_block_list_type = kCatch;
Vladimir Marko55fff042014-07-10 12:42:52 +01002268 SuccessorBlockInfo* successor_block_info = reinterpret_cast<SuccessorBlockInfo*>
2269 (cu_.arena.Alloc(sizeof(SuccessorBlockInfo), kArenaAllocSuccessor));
2270 successor_block_info->block = catch_handler->id;
Vladimir Markoe39c54e2014-09-22 14:50:02 +01002271 check_bb->successor_blocks.push_back(successor_block_info);
Vladimir Marko11ca6122014-07-17 20:50:07 +01002272 BasicBlock* merge_block = cu_.mir_graph->GetBasicBlock(4u);
2273 std::swap(merge_block->taken, merge_block->fall_through);
2274 PrepareMIRs(mirs);
2275 PerformGVN();
2276}
2277
Razvan A Lupusorue0951142014-11-14 14:36:55 -08002278TEST_F(GlobalValueNumberingTestDiamond, DivZeroCheckDiamond) {
2279 static const MIRDef mirs[] = {
Vladimir Marko7a01dc22015-01-02 17:00:44 +00002280 DEF_BINOP(3u, Instruction::DIV_INT, 1u, 20u, 21u),
2281 DEF_BINOP(3u, Instruction::DIV_INT, 2u, 24u, 21u),
2282 DEF_BINOP(3u, Instruction::DIV_INT, 3u, 20u, 23u),
2283 DEF_BINOP(4u, Instruction::DIV_INT, 4u, 24u, 22u),
2284 DEF_BINOP(4u, Instruction::DIV_INT, 9u, 24u, 25u),
2285 DEF_BINOP(5u, Instruction::DIV_INT, 5u, 24u, 21u),
2286 DEF_BINOP(5u, Instruction::DIV_INT, 10u, 24u, 26u),
Razvan A Lupusorue0951142014-11-14 14:36:55 -08002287 DEF_PHI2(6u, 27u, 25u, 26u),
Vladimir Marko7a01dc22015-01-02 17:00:44 +00002288 DEF_BINOP(6u, Instruction::DIV_INT, 12u, 20u, 27u),
2289 DEF_BINOP(6u, Instruction::DIV_INT, 6u, 24u, 21u),
2290 DEF_BINOP(6u, Instruction::DIV_INT, 7u, 20u, 23u),
2291 DEF_BINOP(6u, Instruction::DIV_INT, 8u, 20u, 22u),
Razvan A Lupusorue0951142014-11-14 14:36:55 -08002292 };
2293
2294 static const bool expected_ignore_div_zero_check[] = {
2295 false, // New divisor seen.
2296 true, // Eliminated since it has first divisor as first one.
2297 false, // New divisor seen.
2298 false, // New divisor seen.
2299 false, // New divisor seen.
2300 true, // Eliminated in dominating block.
2301 false, // New divisor seen.
2302 false, // Phi node.
2303 true, // Eliminated on both sides of diamond and merged via phi.
2304 true, // Eliminated in dominating block.
2305 true, // Eliminated in dominating block.
2306 false, // Only eliminated on one path of diamond.
2307 };
2308
2309 PrepareMIRs(mirs);
2310 PerformGVN();
2311 PerformGVNCodeModifications();
2312 ASSERT_EQ(arraysize(expected_ignore_div_zero_check), mir_count_);
2313 for (size_t i = 0u; i != mir_count_; ++i) {
2314 int expected = expected_ignore_div_zero_check[i] ? MIR_IGNORE_DIV_ZERO_CHECK : 0u;
2315 EXPECT_EQ(expected, mirs_[i].optimization_flags) << i;
2316 }
2317}
2318
Vladimir Marko22fe45d2015-03-18 11:33:58 +00002319TEST_F(GlobalValueNumberingTestDiamond, CheckCastDiamond) {
2320 static const MIRDef mirs[] = {
2321 DEF_UNOP(3u, Instruction::INSTANCE_OF, 0u, 100u),
2322 DEF_UNOP(3u, Instruction::INSTANCE_OF, 1u, 200u),
2323 DEF_IFZ(3u, Instruction::IF_NEZ, 0u),
2324 DEF_INVOKE1(4u, Instruction::CHECK_CAST, 100u),
2325 DEF_INVOKE1(5u, Instruction::CHECK_CAST, 100u),
2326 DEF_INVOKE1(5u, Instruction::CHECK_CAST, 200u),
2327 DEF_INVOKE1(5u, Instruction::CHECK_CAST, 100u),
2328 DEF_INVOKE1(6u, Instruction::CHECK_CAST, 100u),
2329 };
2330
2331 static const bool expected_ignore_check_cast[] = {
2332 false, // instance-of
2333 false, // instance-of
2334 false, // if-nez
2335 false, // Not eliminated, fall-through branch.
2336 true, // Eliminated.
2337 false, // Not eliminated, different value.
2338 false, // Not eliminated, different type.
2339 false, // Not eliminated, bottom block.
2340 };
2341
2342 PrepareMIRs(mirs);
2343 mirs_[0].dalvikInsn.vC = 1234; // type for instance-of
2344 mirs_[1].dalvikInsn.vC = 1234; // type for instance-of
2345 mirs_[3].dalvikInsn.vB = 1234; // type for check-cast
2346 mirs_[4].dalvikInsn.vB = 1234; // type for check-cast
2347 mirs_[5].dalvikInsn.vB = 1234; // type for check-cast
2348 mirs_[6].dalvikInsn.vB = 4321; // type for check-cast
2349 mirs_[7].dalvikInsn.vB = 1234; // type for check-cast
2350 PerformGVN();
2351 PerformGVNCodeModifications();
2352 ASSERT_EQ(arraysize(expected_ignore_check_cast), mir_count_);
2353 for (size_t i = 0u; i != mir_count_; ++i) {
2354 int expected = expected_ignore_check_cast[i] ? MIR_IGNORE_CHECK_CAST : 0u;
2355 EXPECT_EQ(expected, mirs_[i].optimization_flags) << i;
2356 }
2357}
2358
2359TEST_F(GlobalValueNumberingTest, CheckCastDominators) {
2360 const BBDef bbs[] = {
2361 DEF_BB(kNullBlock, DEF_SUCC0(), DEF_PRED0()),
2362 DEF_BB(kEntryBlock, DEF_SUCC1(3), DEF_PRED0()),
2363 DEF_BB(kExitBlock, DEF_SUCC0(), DEF_PRED1(7)),
2364 DEF_BB(kDalvikByteCode, DEF_SUCC2(4, 5), DEF_PRED1(1)), // Block #3, top of the diamond.
2365 DEF_BB(kDalvikByteCode, DEF_SUCC1(7), DEF_PRED1(3)), // Block #4, left side.
2366 DEF_BB(kDalvikByteCode, DEF_SUCC1(6), DEF_PRED1(3)), // Block #5, right side.
2367 DEF_BB(kDalvikByteCode, DEF_SUCC1(7), DEF_PRED1(5)), // Block #6, right side.
2368 DEF_BB(kDalvikByteCode, DEF_SUCC1(2), DEF_PRED2(4, 6)), // Block #7, bottom.
2369 };
2370 static const MIRDef mirs[] = {
2371 DEF_UNOP(3u, Instruction::INSTANCE_OF, 0u, 100u),
2372 DEF_UNOP(3u, Instruction::INSTANCE_OF, 1u, 200u),
2373 DEF_IFZ(3u, Instruction::IF_NEZ, 0u),
2374 DEF_INVOKE1(4u, Instruction::CHECK_CAST, 100u),
2375 DEF_INVOKE1(6u, Instruction::CHECK_CAST, 100u),
2376 DEF_INVOKE1(6u, Instruction::CHECK_CAST, 200u),
2377 DEF_INVOKE1(6u, Instruction::CHECK_CAST, 100u),
2378 DEF_INVOKE1(7u, Instruction::CHECK_CAST, 100u),
2379 };
2380
2381 static const bool expected_ignore_check_cast[] = {
2382 false, // instance-of
2383 false, // instance-of
2384 false, // if-nez
2385 false, // Not eliminated, fall-through branch.
2386 true, // Eliminated.
2387 false, // Not eliminated, different value.
2388 false, // Not eliminated, different type.
2389 false, // Not eliminated, bottom block.
2390 };
2391
2392 PrepareBasicBlocks(bbs);
2393 PrepareMIRs(mirs);
2394 mirs_[0].dalvikInsn.vC = 1234; // type for instance-of
2395 mirs_[1].dalvikInsn.vC = 1234; // type for instance-of
2396 mirs_[3].dalvikInsn.vB = 1234; // type for check-cast
2397 mirs_[4].dalvikInsn.vB = 1234; // type for check-cast
2398 mirs_[5].dalvikInsn.vB = 1234; // type for check-cast
2399 mirs_[6].dalvikInsn.vB = 4321; // type for check-cast
2400 mirs_[7].dalvikInsn.vB = 1234; // type for check-cast
2401 PerformGVN();
2402 PerformGVNCodeModifications();
2403 ASSERT_EQ(arraysize(expected_ignore_check_cast), mir_count_);
2404 for (size_t i = 0u; i != mir_count_; ++i) {
2405 int expected = expected_ignore_check_cast[i] ? MIR_IGNORE_CHECK_CAST : 0u;
2406 EXPECT_EQ(expected, mirs_[i].optimization_flags) << i;
2407 }
2408}
2409
Vladimir Marko95a05972014-05-30 10:01:32 +01002410} // namespace art