ssa_test.cc revision 4833f5a1990c76bc2be89504225fb13cca22bedf
1c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray/* 2c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray * Copyright (C) 2014 The Android Open Source Project 3c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray * 4c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray * Licensed under the Apache License, Version 2.0 (the "License"); 5c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray * you may not use this file except in compliance with the License. 6c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray * You may obtain a copy of the License at 7c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray * 8c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray * http://www.apache.org/licenses/LICENSE-2.0 9c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray * 10c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray * Unless required by applicable law or agreed to in writing, software 11c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray * distributed under the License is distributed on an "AS IS" BASIS, 12c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray * See the License for the specific language governing permissions and 14c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray * limitations under the License. 15c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray */ 16c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 17b666f4805c8ae707ea6fd7f6c7f375e0b000dba8Mathieu Chartier#include "base/arena_allocator.h" 18c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray#include "base/stringprintf.h" 19c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray#include "builder.h" 20c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray#include "dex_file.h" 21c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray#include "dex_instruction.h" 22c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray#include "nodes.h" 23c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray#include "optimizing_unit_test.h" 24c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray#include "pretty_printer.h" 25c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray#include "ssa_builder.h" 26c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 27c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray#include "gtest/gtest.h" 28c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 29c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffraynamespace art { 30c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 314833f5a1990c76bc2be89504225fb13cca22bedfDavid Brazdilclass SsaTest : public CommonCompilerTest {}; 324833f5a1990c76bc2be89504225fb13cca22bedfDavid Brazdil 330d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffrayclass SsaPrettyPrinter : public HPrettyPrinter { 34c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray public: 350d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray explicit SsaPrettyPrinter(HGraph* graph) : HPrettyPrinter(graph), str_("") {} 36c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 372ed20afc6a1032e9e0cf919cb8d1b2b41e147182Alexandre Rames void PrintInt(int value) OVERRIDE { 38c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray str_ += StringPrintf("%d", value); 39c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray } 40c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 412ed20afc6a1032e9e0cf919cb8d1b2b41e147182Alexandre Rames void PrintString(const char* value) OVERRIDE { 42c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray str_ += value; 43c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray } 44c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 452ed20afc6a1032e9e0cf919cb8d1b2b41e147182Alexandre Rames void PrintNewLine() OVERRIDE { 46c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray str_ += '\n'; 47c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray } 48c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 49c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray void Clear() { str_.clear(); } 50c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 51c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray std::string str() const { return str_; } 52c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 532ed20afc6a1032e9e0cf919cb8d1b2b41e147182Alexandre Rames void VisitIntConstant(HIntConstant* constant) OVERRIDE { 54c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray PrintPreInstruction(constant); 55c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray str_ += constant->DebugName(); 56c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray str_ += " "; 57c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray PrintInt(constant->GetValue()); 58c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray PrintPostInstruction(constant); 59c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray } 60c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 61c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray private: 62c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray std::string str_; 63c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 640d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray DISALLOW_COPY_AND_ASSIGN(SsaPrettyPrinter); 65c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray}; 66c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 67c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffraystatic void ReNumberInstructions(HGraph* graph) { 68c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray int id = 0; 69fa6b93c4b69e6d7ddfa2a4ed0aff01b0608c5a3aVladimir Marko for (HBasicBlock* block : graph->GetBlocks()) { 70f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) { 71c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray it.Current()->SetId(id++); 72c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray } 73f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray for (HInstructionIterator it(block->GetInstructions()); !it.Done(); it.Advance()) { 74c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray it.Current()->SetId(id++); 75c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray } 76c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray } 77c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray} 78c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 79c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffraystatic void TestCode(const uint16_t* data, const char* expected) { 80c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray ArenaPool pool; 81c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray ArenaAllocator allocator(&pool); 820a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray HGraph* graph = CreateGraph(&allocator); 835e8b137d28c840b128e2488f954cccee3e86db14David Brazdil HGraphBuilder builder(graph); 84c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const DexFile::CodeItem* item = reinterpret_cast<const DexFile::CodeItem*>(data); 855e8b137d28c840b128e2488f954cccee3e86db14David Brazdil bool graph_built = builder.BuildGraph(*item); 865e8b137d28c840b128e2488f954cccee3e86db14David Brazdil ASSERT_TRUE(graph_built); 870d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray 884833f5a1990c76bc2be89504225fb13cca22bedfDavid Brazdil TransformToSsa(graph); 89fbc695f9b8e2084697e19c1355ab925f99f0d235Nicolas Geoffray // Suspend checks implementation may change in the future, and this test relies 90fbc695f9b8e2084697e19c1355ab925f99f0d235Nicolas Geoffray // on how instructions are ordered. 91fbc695f9b8e2084697e19c1355ab925f99f0d235Nicolas Geoffray RemoveSuspendChecks(graph); 92c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray ReNumberInstructions(graph); 93c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 94184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray // Test that phis had their type set. 95fa6b93c4b69e6d7ddfa2a4ed0aff01b0608c5a3aVladimir Marko for (HBasicBlock* block : graph->GetBlocks()) { 96fa6b93c4b69e6d7ddfa2a4ed0aff01b0608c5a3aVladimir Marko for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) { 97184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray ASSERT_NE(it.Current()->GetType(), Primitive::kPrimVoid); 98184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray } 99184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray } 100184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray 1010d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray SsaPrettyPrinter printer(graph); 102c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray printer.VisitInsertionOrder(); 103c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 104c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray ASSERT_STREQ(expected, printer.str().c_str()); 105c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray} 106c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 1074833f5a1990c76bc2be89504225fb13cca22bedfDavid BrazdilTEST_F(SsaTest, CFG1) { 108c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray // Test that we get rid of loads and stores. 109c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const char* expected = 110c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 0, succ: 1\n" 111c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 0: IntConstant 0 [2, 2]\n" 112c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 1: Goto\n" 113ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray "BasicBlock 1, pred: 0, succ: 5, 2\n" 114c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 2: Equal(0, 0) [3]\n" 115c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 3: If(2)\n" 116c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 2, pred: 1, succ: 3\n" 117c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 4: Goto\n" 1188b20f88b0a8d1b374dd5eaae289d19734c77b8f8Nicolas Geoffray "BasicBlock 3, pred: 5, 2, succ: 4\n" 119c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 5: ReturnVoid\n" 120c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 4, pred: 3\n" 121622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray " 6: Exit\n" 122622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray // Synthesized block to avoid critical edge. 123622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray "BasicBlock 5, pred: 1, succ: 3\n" 124622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray " 7: Goto\n"; 125c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 126c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 127c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 0 | 0, 128c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::IF_EQ, 3, 129c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::GOTO | 0x100, 130c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::RETURN_VOID); 131c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 132c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray TestCode(data, expected); 133c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray} 134c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 1354833f5a1990c76bc2be89504225fb13cca22bedfDavid BrazdilTEST_F(SsaTest, CFG2) { 136c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray // Test that we create a phi for the join block of an if control flow instruction 137c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray // when there is only code in the else branch. 138c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const char* expected = 139c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 0, succ: 1\n" 140c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 0: IntConstant 0 [6, 3, 3]\n" 141c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 1: IntConstant 4 [6]\n" 142c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 2: Goto\n" 143ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray "BasicBlock 1, pred: 0, succ: 5, 2\n" 144c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 3: Equal(0, 0) [4]\n" 145c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 4: If(3)\n" 146c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 2, pred: 1, succ: 3\n" 147c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 5: Goto\n" 1488b20f88b0a8d1b374dd5eaae289d19734c77b8f8Nicolas Geoffray "BasicBlock 3, pred: 5, 2, succ: 4\n" 1498b20f88b0a8d1b374dd5eaae289d19734c77b8f8Nicolas Geoffray " 6: Phi(0, 1) [7]\n" 150c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 7: Return(6)\n" 151c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 4, pred: 3\n" 152622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray " 8: Exit\n" 153622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray // Synthesized block to avoid critical edge. 154622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray "BasicBlock 5, pred: 1, succ: 3\n" 155622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray " 9: Goto\n"; 156c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 157c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 158c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 0 | 0, 159c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::IF_EQ, 3, 160c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 4 << 12 | 0, 161c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::RETURN | 0 << 8); 162c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 163c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray TestCode(data, expected); 164c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray} 165c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 1664833f5a1990c76bc2be89504225fb13cca22bedfDavid BrazdilTEST_F(SsaTest, CFG3) { 167c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray // Test that we create a phi for the join block of an if control flow instruction 168804d09372cc3d80d537da1489da4a45e0e19aa5dNicolas Geoffray // when both branches update a local. 169c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const char* expected = 170c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 0, succ: 1\n" 171c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 0: IntConstant 0 [4, 4]\n" 172c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 1: IntConstant 4 [8]\n" 173c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 2: IntConstant 5 [8]\n" 174c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 3: Goto\n" 175c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 1, pred: 0, succ: 3, 2\n" 176c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 4: Equal(0, 0) [5]\n" 177c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 5: If(4)\n" 178c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 2, pred: 1, succ: 4\n" 179c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 6: Goto\n" 180c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 3, pred: 1, succ: 4\n" 181c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 7: Goto\n" 182c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 4, pred: 2, 3, succ: 5\n" 183c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 8: Phi(1, 2) [9]\n" 184c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 9: Return(8)\n" 185c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 5, pred: 4\n" 186c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 10: Exit\n"; 187c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 188c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 189c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 0 | 0, 190c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::IF_EQ, 4, 191c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 4 << 12 | 0, 192c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::GOTO | 0x200, 193c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 5 << 12 | 0, 194c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::RETURN | 0 << 8); 195c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 196c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray TestCode(data, expected); 197c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray} 198c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 1994833f5a1990c76bc2be89504225fb13cca22bedfDavid BrazdilTEST_F(SsaTest, Loop1) { 200c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray // Test that we create a phi for an initialized local at entry of a loop. 201c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const char* expected = 202c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 0, succ: 1\n" 203a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray " 0: IntConstant 0 [6, 3, 3]\n" 204a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray " 1: IntConstant 4 [6]\n" 205a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray " 2: Goto\n" 206a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray "BasicBlock 1, pred: 0, succ: 4, 2\n" 207a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray " 3: Equal(0, 0) [4]\n" 208a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray " 4: If(3)\n" 209a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray "BasicBlock 2, pred: 1, succ: 3\n" 210c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 5: Goto\n" 211a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray "BasicBlock 3, pred: 2, 4, succ: 5\n" 212a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray " 6: Phi(1, 0) [9]\n" 213c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 7: Goto\n" 214a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray "BasicBlock 4, pred: 1, succ: 3\n" 215622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray " 8: Goto\n" 216a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray "BasicBlock 5, pred: 3, succ: 6\n" 217a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray " 9: Return(6)\n" 218a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray "BasicBlock 6, pred: 5\n" 219a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray " 10: Exit\n"; 220c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 221c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 222c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 0 | 0, 223a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray Instruction::IF_EQ, 4, 224a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray Instruction::CONST_4 | 4 << 12 | 0, 225a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray Instruction::GOTO | 0x200, 226a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray Instruction::GOTO | 0xFF00, 227a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray Instruction::RETURN | 0 << 8); 228c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 229c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray TestCode(data, expected); 230c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray} 231c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 2324833f5a1990c76bc2be89504225fb13cca22bedfDavid BrazdilTEST_F(SsaTest, Loop2) { 233c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray // Simple loop with one preheader and one back edge. 234c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const char* expected = 235c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 0, succ: 1\n" 236c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 0: IntConstant 0 [4]\n" 237c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 1: IntConstant 4 [4]\n" 238c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 2: Goto\n" 239c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 1, pred: 0, succ: 2\n" 240c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 3: Goto\n" 241c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 2, pred: 1, 3, succ: 4, 3\n" 242c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 4: Phi(0, 1) [5, 5]\n" 243c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 5: Equal(4, 4) [6]\n" 244c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 6: If(5)\n" 245c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 3, pred: 2, succ: 2\n" 246c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 7: Goto\n" 247c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 4, pred: 2, succ: 5\n" 248c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 8: ReturnVoid\n" 249c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 5, pred: 4\n" 250c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 9: Exit\n"; 251c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 252c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 253c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 0 | 0, 254c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::IF_EQ, 4, 255c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 4 << 12 | 0, 256c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::GOTO | 0xFD00, 257c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::RETURN_VOID); 258c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 259c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray TestCode(data, expected); 260c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray} 261c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 2624833f5a1990c76bc2be89504225fb13cca22bedfDavid BrazdilTEST_F(SsaTest, Loop3) { 263c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray // Test that a local not yet defined at the entry of a loop is handled properly. 264c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const char* expected = 265c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 0, succ: 1\n" 266c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 0: IntConstant 0 [5]\n" 267c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 1: IntConstant 4 [5]\n" 268c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 2: IntConstant 5 [9]\n" 269c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 3: Goto\n" 270c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 1, pred: 0, succ: 2\n" 271c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 4: Goto\n" 272c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 2, pred: 1, 3, succ: 4, 3\n" 273c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 5: Phi(0, 1) [6, 6]\n" 274c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 6: Equal(5, 5) [7]\n" 275c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 7: If(6)\n" 276c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 3, pred: 2, succ: 2\n" 277c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 8: Goto\n" 278c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 4, pred: 2, succ: 5\n" 279c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 9: Return(2)\n" 280c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 5, pred: 4\n" 281c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 10: Exit\n"; 282c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 283c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const uint16_t data[] = TWO_REGISTERS_CODE_ITEM( 284c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 0 | 0, 285c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::IF_EQ, 4, 286c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 4 << 12 | 0, 287c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::GOTO | 0xFD00, 288c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 5 << 12 | 1 << 8, 289c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::RETURN | 1 << 8); 290c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 291c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray TestCode(data, expected); 292c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray} 293c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 2944833f5a1990c76bc2be89504225fb13cca22bedfDavid BrazdilTEST_F(SsaTest, Loop4) { 295c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray // Make sure we support a preheader of a loop not being the first predecessor 296c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray // in the predecessor list of the header. 297c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const char* expected = 298c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 0, succ: 1\n" 299c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 0: IntConstant 0 [4]\n" 300c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 1: IntConstant 4 [4]\n" 301c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 2: Goto\n" 302c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 1, pred: 0, succ: 4\n" 303c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 3: Goto\n" 304c83d441a722f0afb510c9cd0e69e09d65652143cNicolas Geoffray "BasicBlock 2, pred: 4, 3, succ: 5, 3\n" 305c83d441a722f0afb510c9cd0e69e09d65652143cNicolas Geoffray " 4: Phi(0, 1) [9, 5, 5]\n" 306c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 5: Equal(4, 4) [6]\n" 307c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 6: If(5)\n" 308c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 3, pred: 2, succ: 2\n" 309c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 7: Goto\n" 310c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 4, pred: 1, succ: 2\n" 311c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 8: Goto\n" 312c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 5, pred: 2, succ: 6\n" 313c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 9: Return(4)\n" 314c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 6, pred: 5\n" 315c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 10: Exit\n"; 316c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 317c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 318c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 0 | 0, 319c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::GOTO | 0x500, 320c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::IF_EQ, 5, 321c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 4 << 12 | 0, 322c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::GOTO | 0xFD00, 323c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::GOTO | 0xFC00, 324c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::RETURN | 0 << 8); 325c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 326c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray TestCode(data, expected); 327c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray} 328c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 3294833f5a1990c76bc2be89504225fb13cca22bedfDavid BrazdilTEST_F(SsaTest, Loop5) { 330c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray // Make sure we create a preheader of a loop when a header originally has two 331c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray // incoming blocks and one back edge. 332c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const char* expected = 333c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 0, succ: 1\n" 334c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 0: IntConstant 0 [4, 4]\n" 3353afca781086699e60a8941fb9474d4607c5909cbNicolas Geoffray " 1: IntConstant 4 [13]\n" 3363afca781086699e60a8941fb9474d4607c5909cbNicolas Geoffray " 2: IntConstant 5 [13]\n" 337c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 3: Goto\n" 338c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 1, pred: 0, succ: 3, 2\n" 339c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 4: Equal(0, 0) [5]\n" 340c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 5: If(4)\n" 341c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 2, pred: 1, succ: 8\n" 342c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 6: Goto\n" 343c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 3, pred: 1, succ: 8\n" 344c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 7: Goto\n" 345c83d441a722f0afb510c9cd0e69e09d65652143cNicolas Geoffray "BasicBlock 4, pred: 8, 5, succ: 6, 5\n" 3463afca781086699e60a8941fb9474d4607c5909cbNicolas Geoffray " 8: Equal(13, 13) [9]\n" 3473afca781086699e60a8941fb9474d4607c5909cbNicolas Geoffray " 9: If(8)\n" 348c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 5, pred: 4, succ: 4\n" 3493afca781086699e60a8941fb9474d4607c5909cbNicolas Geoffray " 10: Goto\n" 350c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 6, pred: 4, succ: 7\n" 3513afca781086699e60a8941fb9474d4607c5909cbNicolas Geoffray " 11: Return(13)\n" 352c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 7, pred: 6\n" 3533afca781086699e60a8941fb9474d4607c5909cbNicolas Geoffray " 12: Exit\n" 354c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 8, pred: 2, 3, succ: 4\n" 3553afca781086699e60a8941fb9474d4607c5909cbNicolas Geoffray " 13: Phi(1, 2) [8, 8, 11]\n" 3563afca781086699e60a8941fb9474d4607c5909cbNicolas Geoffray " 14: Goto\n"; 357c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 358c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 359c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 0 | 0, 360c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::IF_EQ, 4, 361c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 4 << 12 | 0, 362c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::GOTO | 0x200, 363c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 5 << 12 | 0, 364c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::IF_EQ, 3, 365c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::GOTO | 0xFE00, 366c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::RETURN | 0 << 8); 367c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 368c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray TestCode(data, expected); 369c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray} 370c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 3714833f5a1990c76bc2be89504225fb13cca22bedfDavid BrazdilTEST_F(SsaTest, Loop6) { 372c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray // Test a loop with one preheader and two back edges (e.g. continue). 373c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const char* expected = 374c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 0, succ: 1\n" 375c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 0: IntConstant 0 [5]\n" 376db216f4d49ea1561a74261c29f1264952232728aNicolas Geoffray " 1: IntConstant 4 [5, 8, 8]\n" 377db216f4d49ea1561a74261c29f1264952232728aNicolas Geoffray " 2: IntConstant 5 [5]\n" 378c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 3: Goto\n" 379c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 1, pred: 0, succ: 2\n" 380c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 4: Goto\n" 381db216f4d49ea1561a74261c29f1264952232728aNicolas Geoffray "BasicBlock 2, pred: 1, 4, 5, succ: 6, 3\n" 382db216f4d49ea1561a74261c29f1264952232728aNicolas Geoffray " 5: Phi(0, 2, 1) [12, 6, 6]\n" 383c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 6: Equal(5, 5) [7]\n" 384c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 7: If(6)\n" 385c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 3, pred: 2, succ: 5, 4\n" 386c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 8: Equal(1, 1) [9]\n" 387c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 9: If(8)\n" 388db216f4d49ea1561a74261c29f1264952232728aNicolas Geoffray "BasicBlock 4, pred: 3, succ: 2\n" 389c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 10: Goto\n" 390db216f4d49ea1561a74261c29f1264952232728aNicolas Geoffray "BasicBlock 5, pred: 3, succ: 2\n" 391c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 11: Goto\n" 392c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 6, pred: 2, succ: 7\n" 393c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 12: Return(5)\n" 394c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 7, pred: 6\n" 395db216f4d49ea1561a74261c29f1264952232728aNicolas Geoffray " 13: Exit\n"; 396c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 397c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 398c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 0 | 0, 399c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::IF_EQ, 8, 400c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 4 << 12 | 0, 401c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::IF_EQ, 4, 402c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 5 << 12 | 0, 403c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::GOTO | 0xFA00, 404c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::GOTO | 0xF900, 405c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::RETURN | 0 << 8); 406c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 407c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray TestCode(data, expected); 408c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray} 409c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 4104833f5a1990c76bc2be89504225fb13cca22bedfDavid BrazdilTEST_F(SsaTest, Loop7) { 411c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray // Test a loop with one preheader, one back edge, and two exit edges (e.g. break). 412c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const char* expected = 413c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 0, succ: 1\n" 414c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 0: IntConstant 0 [5]\n" 415c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 1: IntConstant 4 [5, 8, 8]\n" 416c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 2: IntConstant 5 [12]\n" 417c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 3: Goto\n" 418c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 1, pred: 0, succ: 2\n" 419c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 4: Goto\n" 420ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray "BasicBlock 2, pred: 1, 5, succ: 8, 3\n" 421c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 5: Phi(0, 1) [12, 6, 6]\n" 422c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 6: Equal(5, 5) [7]\n" 423c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 7: If(6)\n" 424c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 3, pred: 2, succ: 5, 4\n" 425c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 8: Equal(1, 1) [9]\n" 426c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 9: If(8)\n" 427c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 4, pred: 3, succ: 6\n" 428c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 10: Goto\n" 429c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 5, pred: 3, succ: 2\n" 430c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 11: Goto\n" 4318b20f88b0a8d1b374dd5eaae289d19734c77b8f8Nicolas Geoffray "BasicBlock 6, pred: 8, 4, succ: 7\n" 4328b20f88b0a8d1b374dd5eaae289d19734c77b8f8Nicolas Geoffray " 12: Phi(5, 2) [13]\n" 433c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 13: Return(12)\n" 434c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 7, pred: 6\n" 435622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray " 14: Exit\n" 436622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray "BasicBlock 8, pred: 2, succ: 6\n" 437622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray " 15: Goto\n"; 438c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 439c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 440c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 0 | 0, 441c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::IF_EQ, 8, 442c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 4 << 12 | 0, 443c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::IF_EQ, 4, 444c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 5 << 12 | 0, 445c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::GOTO | 0x0200, 446c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::GOTO | 0xF900, 447c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::RETURN | 0 << 8); 448c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 449c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray TestCode(data, expected); 450c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray} 451c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 4524833f5a1990c76bc2be89504225fb13cca22bedfDavid BrazdilTEST_F(SsaTest, DeadLocal) { 453c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray // Test that we correctly handle a local not being used. 454c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const char* expected = 455c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 0, succ: 1\n" 456c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 0: IntConstant 0\n" 457c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 1: Goto\n" 458c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 1, pred: 0, succ: 2\n" 459c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 2: ReturnVoid\n" 460c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 2, pred: 1\n" 461c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 3: Exit\n"; 462c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 463c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 464c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 0 | 0, 465c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::RETURN_VOID); 466c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 467c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray TestCode(data, expected); 468c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray} 469c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 4704833f5a1990c76bc2be89504225fb13cca22bedfDavid BrazdilTEST_F(SsaTest, LocalInIf) { 4717c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray // Test that we do not create a phi in the join block when one predecessor 4727c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray // does not update the local. 4737c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray const char* expected = 4747c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray "BasicBlock 0, succ: 1\n" 4757c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray " 0: IntConstant 0 [3, 3]\n" 4767c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray " 1: IntConstant 4\n" 4777c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray " 2: Goto\n" 478ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray "BasicBlock 1, pred: 0, succ: 5, 2\n" 4797c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray " 3: Equal(0, 0) [4]\n" 4807c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray " 4: If(3)\n" 4817c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray "BasicBlock 2, pred: 1, succ: 3\n" 4827c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray " 5: Goto\n" 4838b20f88b0a8d1b374dd5eaae289d19734c77b8f8Nicolas Geoffray "BasicBlock 3, pred: 5, 2, succ: 4\n" 4847c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray " 6: ReturnVoid\n" 4857c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray "BasicBlock 4, pred: 3\n" 4867c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray " 7: Exit\n" 4877c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray // Synthesized block to avoid critical edge. 4887c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray "BasicBlock 5, pred: 1, succ: 3\n" 4897c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray " 8: Goto\n"; 4907c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray 4917c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray const uint16_t data[] = TWO_REGISTERS_CODE_ITEM( 4927c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray Instruction::CONST_4 | 0 | 0, 4937c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray Instruction::IF_EQ, 3, 4947c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray Instruction::CONST_4 | 4 << 12 | 1 << 8, 4957c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray Instruction::RETURN_VOID); 4967c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray 4977c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray TestCode(data, expected); 4987c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray} 4997c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray 5004833f5a1990c76bc2be89504225fb13cca22bedfDavid BrazdilTEST_F(SsaTest, MultiplePredecessors) { 501ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray // Test that we do not create a phi when one predecessor 502ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray // does not update the local. 503ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray const char* expected = 504ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray "BasicBlock 0, succ: 1\n" 505ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray " 0: IntConstant 0 [4, 8, 6, 6, 2, 2, 8, 4]\n" 506ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray " 1: Goto\n" 507ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray "BasicBlock 1, pred: 0, succ: 3, 2\n" 508ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray " 2: Equal(0, 0) [3]\n" 509ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray " 3: If(2)\n" 510ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray "BasicBlock 2, pred: 1, succ: 5\n" 511ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray " 4: Add(0, 0)\n" 512ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray " 5: Goto\n" 513ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray "BasicBlock 3, pred: 1, succ: 7, 4\n" 514ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray " 6: Equal(0, 0) [7]\n" 515ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray " 7: If(6)\n" 516ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray "BasicBlock 4, pred: 3, succ: 5\n" 517ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray " 8: Add(0, 0)\n" 518ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray " 9: Goto\n" 519ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray // This block should not get a phi for local 1. 5208b20f88b0a8d1b374dd5eaae289d19734c77b8f8Nicolas Geoffray "BasicBlock 5, pred: 2, 7, 4, succ: 6\n" 521ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray " 10: ReturnVoid\n" 522ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray "BasicBlock 6, pred: 5\n" 523ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray " 11: Exit\n" 524ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray "BasicBlock 7, pred: 3, succ: 5\n" 525ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray " 12: Goto\n"; 526ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray 527ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray const uint16_t data[] = TWO_REGISTERS_CODE_ITEM( 528ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray Instruction::CONST_4 | 0 | 0, 529ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray Instruction::IF_EQ, 5, 530ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray Instruction::ADD_INT_LIT8 | 1 << 8, 0 << 8, 531ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray Instruction::GOTO | 0x0500, 532ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray Instruction::IF_EQ, 4, 533ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray Instruction::ADD_INT_LIT8 | 1 << 8, 0 << 8, 534ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray Instruction::RETURN_VOID); 535ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray 536ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray TestCode(data, expected); 537ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray} 538ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray 539c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray} // namespace art 540