1ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray/*
2ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray * Copyright (C) 2014 The Android Open Source Project
3ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray *
4ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray * Licensed under the Apache License, Version 2.0 (the "License");
5ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray * you may not use this file except in compliance with the License.
6ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray * You may obtain a copy of the License at
7ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray *
8ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray *      http://www.apache.org/licenses/LICENSE-2.0
9ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray *
10ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray * Unless required by applicable law or agreed to in writing, software
11ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray * distributed under the License is distributed on an "AS IS" BASIS,
12ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray * See the License for the specific language governing permissions and
14ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray * limitations under the License.
15ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray */
16ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray
17fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell#include "arch/x86/instruction_set_features_x86.h"
18b666f4805c8ae707ea6fd7f6c7f375e0b000dba8Mathieu Chartier#include "base/arena_allocator.h"
19ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray#include "builder.h"
2031d76b42ef5165351499da3f8ee0ac147428c5edNicolas Geoffray#include "code_generator.h"
218a16d97fb8f031822b206e65f9109a071da40563Nicolas Geoffray#include "code_generator_x86.h"
22ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray#include "dex_file.h"
23ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray#include "dex_instruction.h"
24cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle#include "driver/compiler_options.h"
25ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray#include "nodes.h"
26ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray#include "optimizing_unit_test.h"
27360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray#include "prepare_for_register_allocation.h"
28ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray#include "ssa_liveness_analysis.h"
29ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray
3068289a531484d26214e09f1eadd9833531a3bc3cAlex Lightnamespace art {
31d9510dfc32349eeb4f2145c801f7ba1d5bccfb12David Brazdil
324833f5a1990c76bc2be89504225fb13cca22bedfDavid Brazdilclass LiveRangesTest : public CommonCompilerTest {};
334833f5a1990c76bc2be89504225fb13cca22bedfDavid Brazdil
34ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffraystatic HGraph* BuildGraph(const uint16_t* data, ArenaAllocator* allocator) {
35badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil  HGraph* graph = CreateCFG(allocator, data);
36fbc695f9b8e2084697e19c1355ab925f99f0d235Nicolas Geoffray  // Suspend checks implementation may change in the future, and this test relies
37fbc695f9b8e2084697e19c1355ab925f99f0d235Nicolas Geoffray  // on how instructions are ordered.
38fbc695f9b8e2084697e19c1355ab925f99f0d235Nicolas Geoffray  RemoveSuspendChecks(graph);
39360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray  // `Inline` conditions into ifs.
40360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray  PrepareForRegisterAllocation(graph).Run();
41ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  return graph;
42ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray}
43ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray
444833f5a1990c76bc2be89504225fb13cca22bedfDavid BrazdilTEST_F(LiveRangesTest, CFG1) {
45ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  /*
46ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   * Test the following snippet:
47ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   *  return 0;
48ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   *
49ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   * Which becomes the following graph (numbered by lifetime position):
50ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   *       2: constant0
51a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray   *       4: goto
52ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   *           |
53a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray   *       8: return
54ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   *           |
55a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray   *       12: exit
56ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   */
57ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
58ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray    Instruction::CONST_4 | 0 | 0,
59ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray    Instruction::RETURN);
60ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray
61ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  ArenaPool pool;
62ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  ArenaAllocator allocator(&pool);
63ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  HGraph* graph = BuildGraph(data, &allocator);
6431d76b42ef5165351499da3f8ee0ac147428c5edNicolas Geoffray
65fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  std::unique_ptr<const X86InstructionSetFeatures> features_x86(
66fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell      X86InstructionSetFeatures::FromCppDefines());
67fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  x86::CodeGeneratorX86 codegen(graph, *features_x86.get(), CompilerOptions());
680d9f17de8f21a10702de1510b73e89d07b3b9bbfNicolas Geoffray  SsaLivenessAnalysis liveness(graph, &codegen);
69ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  liveness.Analyze();
70ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray
71ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  LiveInterval* interval = liveness.GetInstructionFromSsaIndex(0)->GetLiveInterval();
72a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray  LiveRange* range = interval->GetFirstRange();
73a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray  ASSERT_EQ(2u, range->GetStart());
74ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  // Last use is the return instruction.
758e3964b766652a0478e8e0e303e8556c997675f1Nicolas Geoffray  ASSERT_EQ(8u, range->GetEnd());
76ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko  HBasicBlock* block = graph->GetBlocks()[1];
77476df557fed5f0b3f32f8d11a654674bb403a8f8Roland Levillain  ASSERT_TRUE(block->GetLastInstruction()->IsReturn());
78a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray  ASSERT_EQ(8u, block->GetLastInstruction()->GetLifetimePosition());
79a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray  ASSERT_TRUE(range->GetNext() == nullptr);
80ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray}
81ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray
824833f5a1990c76bc2be89504225fb13cca22bedfDavid BrazdilTEST_F(LiveRangesTest, CFG2) {
83ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  /*
84ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   * Test the following snippet:
85ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   *  var a = 0;
86ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   *  if (0 == 0) {
87ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   *  } else {
88ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   *  }
89ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   *  return a;
90ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   *
91ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   * Which becomes the following graph (numbered by lifetime position):
92ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   *       2: constant0
93a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray   *       4: goto
94ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   *           |
95a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray   *       8: equal
96a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray   *       10: if
97ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   *       /       \
98a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray   *   14: goto   18: goto
99ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   *       \       /
100a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray   *       22: return
101ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   *         |
102a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray   *       26: exit
103ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   */
104ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
105ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray    Instruction::CONST_4 | 0 | 0,
106ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray    Instruction::IF_EQ, 3,
107ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray    Instruction::GOTO | 0x100,
108ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray    Instruction::RETURN | 0 << 8);
109ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray
110ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  ArenaPool pool;
111ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  ArenaAllocator allocator(&pool);
112ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  HGraph* graph = BuildGraph(data, &allocator);
113fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  std::unique_ptr<const X86InstructionSetFeatures> features_x86(
114fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell      X86InstructionSetFeatures::FromCppDefines());
115fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  x86::CodeGeneratorX86 codegen(graph, *features_x86.get(), CompilerOptions());
1160d9f17de8f21a10702de1510b73e89d07b3b9bbfNicolas Geoffray  SsaLivenessAnalysis liveness(graph, &codegen);
117ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  liveness.Analyze();
118ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray
119ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  LiveInterval* interval = liveness.GetInstructionFromSsaIndex(0)->GetLiveInterval();
120a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray  LiveRange* range = interval->GetFirstRange();
121a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray  ASSERT_EQ(2u, range->GetStart());
122ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  // Last use is the return instruction.
1238e3964b766652a0478e8e0e303e8556c997675f1Nicolas Geoffray  ASSERT_EQ(22u, range->GetEnd());
124ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko  HBasicBlock* block = graph->GetBlocks()[3];
125476df557fed5f0b3f32f8d11a654674bb403a8f8Roland Levillain  ASSERT_TRUE(block->GetLastInstruction()->IsReturn());
126a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray  ASSERT_EQ(22u, block->GetLastInstruction()->GetLifetimePosition());
127a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray  ASSERT_TRUE(range->GetNext() == nullptr);
128ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray}
129ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray
1304833f5a1990c76bc2be89504225fb13cca22bedfDavid BrazdilTEST_F(LiveRangesTest, CFG3) {
131ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  /*
132ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   * Test the following snippet:
133ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   *  var a = 0;
134ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   *  if (0 == 0) {
135ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   *  } else {
136ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   *    a = 4;
137ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   *  }
138ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   *  return a;
139ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   *
140ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   * Which becomes the following graph (numbered by lifetime position):
141ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   *       2: constant0
142a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray   *       4: constant4
143a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray   *       6: goto
144ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   *           |
145a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray   *       10: equal
146a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray   *       12: if
147ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   *       /       \
148a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray   *   16: goto   20: goto
149ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   *       \       /
150a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray   *       22: phi
151a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray   *       24: return
152ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   *         |
1538ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *       28: exit
154ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   */
155ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
156ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray    Instruction::CONST_4 | 0 | 0,
157ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray    Instruction::IF_EQ, 3,
158ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray    Instruction::CONST_4 | 4 << 12 | 0,
159ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray    Instruction::RETURN | 0 << 8);
160ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray
161ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  ArenaPool pool;
162ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  ArenaAllocator allocator(&pool);
163ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  HGraph* graph = BuildGraph(data, &allocator);
164fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  std::unique_ptr<const X86InstructionSetFeatures> features_x86(
165fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell      X86InstructionSetFeatures::FromCppDefines());
166fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  x86::CodeGeneratorX86 codegen(graph, *features_x86.get(), CompilerOptions());
1670d9f17de8f21a10702de1510b73e89d07b3b9bbfNicolas Geoffray  SsaLivenessAnalysis liveness(graph, &codegen);
168ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  liveness.Analyze();
169ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray
170ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray  // Test for the 4 constant.
171ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray  LiveInterval* interval = liveness.GetInstructionFromSsaIndex(1)->GetLiveInterval();
172a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray  LiveRange* range = interval->GetFirstRange();
173ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray  ASSERT_EQ(4u, range->GetStart());
174ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  // Last use is the phi at the return block so instruction is live until
175ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  // the end of the then block.
176a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray  ASSERT_EQ(18u, range->GetEnd());
177a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray  ASSERT_TRUE(range->GetNext() == nullptr);
178ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray
179ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray  // Test for the 0 constant.
180ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray  interval = liveness.GetInstructionFromSsaIndex(0)->GetLiveInterval();
181ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  // The then branch is a hole for this constant, therefore its interval has 2 ranges.
182a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray  // First range starts from the definition and ends at the if block.
183a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray  range = interval->GetFirstRange();
184ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray  ASSERT_EQ(2u, range->GetStart());
185ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray  // 14 is the end of the if block.
186a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray  ASSERT_EQ(14u, range->GetEnd());
187a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray  // Second range is the else block.
188a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray  range = range->GetNext();
189a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray  ASSERT_EQ(18u, range->GetStart());
190a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray  // Last use is the phi at the return block.
191a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray  ASSERT_EQ(22u, range->GetEnd());
192a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray  ASSERT_TRUE(range->GetNext() == nullptr);
193ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray
194ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  // Test for the phi.
195e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray  interval = liveness.GetInstructionFromSsaIndex(2)->GetLiveInterval();
196a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray  range = interval->GetFirstRange();
197e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray  ASSERT_EQ(22u, liveness.GetInstructionFromSsaIndex(2)->GetLifetimePosition());
198a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray  ASSERT_EQ(22u, range->GetStart());
1998e3964b766652a0478e8e0e303e8556c997675f1Nicolas Geoffray  ASSERT_EQ(24u, range->GetEnd());
200a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray  ASSERT_TRUE(range->GetNext() == nullptr);
201ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray}
202ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray
2034833f5a1990c76bc2be89504225fb13cca22bedfDavid BrazdilTEST_F(LiveRangesTest, Loop1) {
204ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  /*
205ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   * Test the following snippet:
206ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   *  var a = 0;
207ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   *  while (a == a) {
208ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   *    a = 4;
209ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   *  }
210ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   *  return 5;
211ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   *
212ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   * Which becomes the following graph (numbered by lifetime position):
213ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   *       2: constant0
214dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil   *       4: constant5
215dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil   *       6: constant4
216ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   *       8: goto
217ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   *           |
218a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray   *       12: goto
219a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray   *           |
220a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray   *       14: phi
221a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray   *       16: equal
222a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray   *       18: if +++++
223ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   *        |       \ +
224a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray   *        |     22: goto
225ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   *        |
226a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray   *       26: return
227ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   *         |
228a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray   *       30: exit
229ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray   */
230ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray
231ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  const uint16_t data[] = TWO_REGISTERS_CODE_ITEM(
232ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray    Instruction::CONST_4 | 0 | 0,
233ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray    Instruction::IF_EQ, 4,
234ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray    Instruction::CONST_4 | 4 << 12 | 0,
235ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray    Instruction::GOTO | 0xFD00,
236ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray    Instruction::CONST_4 | 5 << 12 | 1 << 8,
237ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray    Instruction::RETURN | 1 << 8);
238ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray
239ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  ArenaPool pool;
240ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  ArenaAllocator allocator(&pool);
241ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  HGraph* graph = BuildGraph(data, &allocator);
2429ebc72c99e6b703bda611d7c918c9cf3dfb43e55Nicolas Geoffray  RemoveSuspendChecks(graph);
243fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  std::unique_ptr<const X86InstructionSetFeatures> features_x86(
244fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell      X86InstructionSetFeatures::FromCppDefines());
245fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  x86::CodeGeneratorX86 codegen(graph, *features_x86.get(), CompilerOptions());
2460d9f17de8f21a10702de1510b73e89d07b3b9bbfNicolas Geoffray  SsaLivenessAnalysis liveness(graph, &codegen);
247ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  liveness.Analyze();
248ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray
249ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  // Test for the 0 constant.
250dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil  LiveInterval* interval = graph->GetIntConstant(0)->GetLiveInterval();
251a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray  LiveRange* range = interval->GetFirstRange();
252a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray  ASSERT_EQ(2u, range->GetStart());
253ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  // Last use is the loop phi so instruction is live until
254ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  // the end of the pre loop header.
255a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray  ASSERT_EQ(14u, range->GetEnd());
256a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray  ASSERT_TRUE(range->GetNext() == nullptr);
257ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray
258ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  // Test for the 4 constant.
259dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil  interval = graph->GetIntConstant(4)->GetLiveInterval();
260a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray  range = interval->GetFirstRange();
261ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  // The instruction is live until the end of the loop.
262dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil  ASSERT_EQ(6u, range->GetStart());
263a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray  ASSERT_EQ(24u, range->GetEnd());
264a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray  ASSERT_TRUE(range->GetNext() == nullptr);
265ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray
266ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  // Test for the 5 constant.
267dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil  interval = graph->GetIntConstant(5)->GetLiveInterval();
268a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray  range = interval->GetFirstRange();
269a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray  // The instruction is live until the return instruction after the loop.
270dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil  ASSERT_EQ(4u, range->GetStart());
2718e3964b766652a0478e8e0e303e8556c997675f1Nicolas Geoffray  ASSERT_EQ(26u, range->GetEnd());
272a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray  ASSERT_TRUE(range->GetNext() == nullptr);
273ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray
274ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  // Test for the phi.
275ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray  interval = liveness.GetInstructionFromSsaIndex(3)->GetLiveInterval();
276a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray  range = interval->GetFirstRange();
277b3e773eea39a156b3eacf915ba84e3af1a5c14faDavid Brazdil  // Instruction is input of non-materialized Equal and hence live until If.
278a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray  ASSERT_EQ(14u, range->GetStart());
279b3e773eea39a156b3eacf915ba84e3af1a5c14faDavid Brazdil  ASSERT_EQ(19u, range->GetEnd());
280a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray  ASSERT_TRUE(range->GetNext() == nullptr);
281ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray}
282ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray
2834833f5a1990c76bc2be89504225fb13cca22bedfDavid BrazdilTEST_F(LiveRangesTest, Loop2) {
2848ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  /*
2858ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   * Test the following snippet:
2868ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *  var a = 0;
2878ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *  while (a == a) {
2888ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *    a = a + a;
2898ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *  }
2908ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *  return a;
2918ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *
2928ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   * Which becomes the following graph (numbered by lifetime position):
2938ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *       2: constant0
2948ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *       4: goto
2958ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *           |
2968ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *       8: goto
2978ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *           |
2988ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *       10: phi
2998ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *       12: equal
3008ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *       14: if +++++
3018ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *        |       \ +
302badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil   *        |     18: add
303badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil   *        |     20: goto
3048ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *        |
305badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil   *       24: return
3068ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *         |
307badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil   *       28: exit
3088ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *
3098ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   * We want to make sure the phi at 10 has a lifetime hole after the add at 20.
3108ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   */
3118ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray
3128ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
3138ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray    Instruction::CONST_4 | 0 | 0,
3148ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray    Instruction::IF_EQ, 6,
3158ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray    Instruction::ADD_INT, 0, 0,
3168ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray    Instruction::GOTO | 0xFB00,
3178ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray    Instruction::RETURN | 0 << 8);
3188ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray
3198ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  ArenaPool pool;
3208ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  ArenaAllocator allocator(&pool);
3218ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  HGraph* graph = BuildGraph(data, &allocator);
322fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  std::unique_ptr<const X86InstructionSetFeatures> features_x86(
323fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell      X86InstructionSetFeatures::FromCppDefines());
324fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  x86::CodeGeneratorX86 codegen(graph, *features_x86.get(), CompilerOptions());
3250d9f17de8f21a10702de1510b73e89d07b3b9bbfNicolas Geoffray  SsaLivenessAnalysis liveness(graph, &codegen);
3268ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  liveness.Analyze();
3278ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray
3288ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  // Test for the 0 constant.
3298ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  HIntConstant* constant = liveness.GetInstructionFromSsaIndex(0)->AsIntConstant();
3308ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  LiveInterval* interval = constant->GetLiveInterval();
3318ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  LiveRange* range = interval->GetFirstRange();
3328ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  ASSERT_EQ(2u, range->GetStart());
3338ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  // Last use is the loop phi so instruction is live until
3348ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  // the end of the pre loop header.
3358ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  ASSERT_EQ(10u, range->GetEnd());
3368ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  ASSERT_TRUE(range->GetNext() == nullptr);
3378ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray
3388ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  // Test for the loop phi.
3398ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  HPhi* phi = liveness.GetInstructionFromSsaIndex(1)->AsPhi();
3408ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  interval = phi->GetLiveInterval();
3418ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  range = interval->GetFirstRange();
3428ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  ASSERT_EQ(10u, range->GetStart());
343badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil  ASSERT_EQ(19u, range->GetEnd());
3448ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  range = range->GetNext();
3458ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  ASSERT_TRUE(range != nullptr);
346badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil  ASSERT_EQ(22u, range->GetStart());
347badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil  ASSERT_EQ(24u, range->GetEnd());
3488ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray
3498ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  // Test for the add instruction.
3508ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  HAdd* add = liveness.GetInstructionFromSsaIndex(2)->AsAdd();
3518ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  interval = add->GetLiveInterval();
3528ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  range = interval->GetFirstRange();
353badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil  ASSERT_EQ(18u, range->GetStart());
354badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil  ASSERT_EQ(22u, range->GetEnd());
3558ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  ASSERT_TRUE(range->GetNext() == nullptr);
3568ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray}
3578ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray
3584833f5a1990c76bc2be89504225fb13cca22bedfDavid BrazdilTEST_F(LiveRangesTest, CFG4) {
3598ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  /*
3608ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   * Test the following snippet:
3618ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *  var a = 0;
3628ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *  var b = 4;
3638ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *  if (a == a) {
3648ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *    a = b + a;
3658ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *  } else {
3668ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *    a = b + a
3678ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *  }
3688ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *  return b;
3698ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *
3708ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   * Which becomes the following graph (numbered by lifetime position):
3718ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *       2: constant0
3728ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *       4: constant4
3738ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *       6: goto
3748ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *           |
3758ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *       10: equal
3768ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *       12: if
3778ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *       /       \
3788ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *   16: add    22: add
3798ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *   18: goto   24: goto
3808ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *       \       /
3818ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *       26: phi
3828ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *       28: return
3838ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *         |
3848ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *       32: exit
3858ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   *
3868ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   * We want to make sure the constant0 has a lifetime hole after the 16: add.
3878ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray   */
3888ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  const uint16_t data[] = TWO_REGISTERS_CODE_ITEM(
3898ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray    Instruction::CONST_4 | 0 | 0,
3908ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray    Instruction::CONST_4 | 4 << 12 | 1 << 8,
3918ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray    Instruction::IF_EQ, 5,
3928ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray    Instruction::ADD_INT, 1 << 8,
3938ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray    Instruction::GOTO | 0x300,
3948ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray    Instruction::ADD_INT, 1 << 8,
395a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray    Instruction::RETURN);
3968ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray
3978ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  ArenaPool pool;
3988ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  ArenaAllocator allocator(&pool);
3998ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  HGraph* graph = BuildGraph(data, &allocator);
400fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  std::unique_ptr<const X86InstructionSetFeatures> features_x86(
401fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell      X86InstructionSetFeatures::FromCppDefines());
402fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell  x86::CodeGeneratorX86 codegen(graph, *features_x86.get(), CompilerOptions());
4030d9f17de8f21a10702de1510b73e89d07b3b9bbfNicolas Geoffray  SsaLivenessAnalysis liveness(graph, &codegen);
4048ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  liveness.Analyze();
4058ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray
4068ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  // Test for the 0 constant.
4078ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  LiveInterval* interval = liveness.GetInstructionFromSsaIndex(0)->GetLiveInterval();
4088ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  LiveRange* range = interval->GetFirstRange();
4098ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  ASSERT_EQ(2u, range->GetStart());
41009b8463493aeb6ea2bce05f67d3457d5fcc8a7d9Mark Mendell  ASSERT_EQ(17u, range->GetEnd());
4118ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  range = range->GetNext();
4128ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  ASSERT_TRUE(range != nullptr);
4138ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  ASSERT_EQ(20u, range->GetStart());
41409b8463493aeb6ea2bce05f67d3457d5fcc8a7d9Mark Mendell  ASSERT_EQ(23u, range->GetEnd());
4158ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  ASSERT_TRUE(range->GetNext() == nullptr);
4168ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray
4178ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  // Test for the 4 constant.
4188ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  interval = liveness.GetInstructionFromSsaIndex(1)->GetLiveInterval();
4198ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  range = interval->GetFirstRange();
4208ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  ASSERT_EQ(4u, range->GetStart());
421a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray  ASSERT_EQ(17u, range->GetEnd());
422a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray  range = range->GetNext();
423a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray  ASSERT_EQ(20u, range->GetStart());
424a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray  ASSERT_EQ(23u, range->GetEnd());
4258ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  ASSERT_TRUE(range->GetNext() == nullptr);
4268ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray
4278ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  // Test for the first add.
4288ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  HAdd* add = liveness.GetInstructionFromSsaIndex(2)->AsAdd();
4298ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  interval = add->GetLiveInterval();
4308ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  range = interval->GetFirstRange();
4318ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  ASSERT_EQ(16u, range->GetStart());
4328ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  ASSERT_EQ(20u, range->GetEnd());
4338ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  ASSERT_TRUE(range->GetNext() == nullptr);
4348ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray
4358ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  // Test for the second add.
4368ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  add = liveness.GetInstructionFromSsaIndex(3)->AsAdd();
4378ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  interval = add->GetLiveInterval();
4388ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  range = interval->GetFirstRange();
4398ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  ASSERT_EQ(22u, range->GetStart());
4408ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  ASSERT_EQ(26u, range->GetEnd());
4418ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  ASSERT_TRUE(range->GetNext() == nullptr);
4428ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray
4438ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  HPhi* phi = liveness.GetInstructionFromSsaIndex(4)->AsPhi();
444d59f3b1b7f5c1ab9f0731ff9dc60611e8d9a6edeVladimir Marko  ASSERT_TRUE(phi->GetUses().HasExactlyOneElement());
4458ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  interval = phi->GetLiveInterval();
4468ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  range = interval->GetFirstRange();
4478ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  ASSERT_EQ(26u, range->GetStart());
4488ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  ASSERT_EQ(28u, range->GetEnd());
4498ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray  ASSERT_TRUE(range->GetNext() == nullptr);
4508ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray}
4518ddb00ca935733f5d3b07816e5bb33d6cabe6ec4Nicolas Geoffray
452ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray}  // namespace art
453