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