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