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