ssa_test.cc revision ec7e4727e99aa1416398ac5a684f5024817a25c7
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 17c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray#include "base/stringprintf.h" 18c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray#include "builder.h" 19c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray#include "dex_file.h" 20c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray#include "dex_instruction.h" 21c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray#include "nodes.h" 22c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray#include "optimizing_unit_test.h" 23c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray#include "pretty_printer.h" 24c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray#include "ssa_builder.h" 25c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray#include "utils/arena_allocator.h" 26c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 27c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray#include "gtest/gtest.h" 28c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 29c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffraynamespace art { 30c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 310d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffrayclass SsaPrettyPrinter : public HPrettyPrinter { 32c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray public: 330d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray explicit SsaPrettyPrinter(HGraph* graph) : HPrettyPrinter(graph), str_("") {} 34c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 35c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray virtual void PrintInt(int value) { 36c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray str_ += StringPrintf("%d", value); 37c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray } 38c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 39c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray virtual void PrintString(const char* value) { 40c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray str_ += value; 41c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray } 42c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 43c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray virtual void PrintNewLine() { 44c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray str_ += '\n'; 45c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray } 46c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 47c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray void Clear() { str_.clear(); } 48c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 49c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray std::string str() const { return str_; } 50c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 51c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray virtual void VisitIntConstant(HIntConstant* constant) { 52c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray PrintPreInstruction(constant); 53c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray str_ += constant->DebugName(); 54c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray str_ += " "; 55c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray PrintInt(constant->GetValue()); 56c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray PrintPostInstruction(constant); 57c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray } 58c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 59c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray private: 60c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray std::string str_; 61c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 620d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray DISALLOW_COPY_AND_ASSIGN(SsaPrettyPrinter); 63c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray}; 64c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 65c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffraystatic void ReNumberInstructions(HGraph* graph) { 66c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray int id = 0; 67804d09372cc3d80d537da1489da4a45e0e19aa5dNicolas Geoffray for (size_t i = 0, e = graph->GetBlocks().Size(); i < e; ++i) { 68804d09372cc3d80d537da1489da4a45e0e19aa5dNicolas Geoffray HBasicBlock* block = graph->GetBlocks().Get(i); 69f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) { 70c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray it.Current()->SetId(id++); 71c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray } 72f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray for (HInstructionIterator it(block->GetInstructions()); !it.Done(); it.Advance()) { 73c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray it.Current()->SetId(id++); 74c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray } 75c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray } 76c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray} 77c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 78c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffraystatic void TestCode(const uint16_t* data, const char* expected) { 79c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray ArenaPool pool; 80c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray ArenaAllocator allocator(&pool); 81c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray HGraphBuilder builder(&allocator); 82c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const DexFile::CodeItem* item = reinterpret_cast<const DexFile::CodeItem*>(data); 83c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray HGraph* graph = builder.BuildGraph(*item); 84c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray ASSERT_NE(graph, nullptr); 850d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray 86c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray graph->BuildDominatorTree(); 87c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray graph->TransformToSSA(); 88c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray ReNumberInstructions(graph); 89c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 900d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray SsaPrettyPrinter printer(graph); 91c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray printer.VisitInsertionOrder(); 92c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 93c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray ASSERT_STREQ(expected, printer.str().c_str()); 94c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray} 95c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 96c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas GeoffrayTEST(SsaTest, CFG1) { 97c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray // Test that we get rid of loads and stores. 98c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const char* expected = 99c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 0, succ: 1\n" 100c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 0: IntConstant 0 [2, 2]\n" 101c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 1: Goto\n" 102ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray "BasicBlock 1, pred: 0, succ: 5, 2\n" 103c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 2: Equal(0, 0) [3]\n" 104c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 3: If(2)\n" 105c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 2, pred: 1, succ: 3\n" 106c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 4: Goto\n" 107622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray "BasicBlock 3, pred: 2, 5, succ: 4\n" 108c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 5: ReturnVoid\n" 109c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 4, pred: 3\n" 110622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray " 6: Exit\n" 111622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray // Synthesized block to avoid critical edge. 112622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray "BasicBlock 5, pred: 1, succ: 3\n" 113622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray " 7: Goto\n"; 114c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 115c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 116c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 0 | 0, 117c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::IF_EQ, 3, 118c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::GOTO | 0x100, 119c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::RETURN_VOID); 120c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 121c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray TestCode(data, expected); 122c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray} 123c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 124c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas GeoffrayTEST(SsaTest, CFG2) { 125c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray // Test that we create a phi for the join block of an if control flow instruction 126c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray // when there is only code in the else branch. 127c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const char* expected = 128c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 0, succ: 1\n" 129c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 0: IntConstant 0 [6, 3, 3]\n" 130c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 1: IntConstant 4 [6]\n" 131c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 2: Goto\n" 132ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray "BasicBlock 1, pred: 0, succ: 5, 2\n" 133c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 3: Equal(0, 0) [4]\n" 134c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 4: If(3)\n" 135c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 2, pred: 1, succ: 3\n" 136c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 5: Goto\n" 137622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray "BasicBlock 3, pred: 2, 5, succ: 4\n" 138622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray " 6: Phi(1, 0) [7]\n" 139c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 7: Return(6)\n" 140c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 4, pred: 3\n" 141622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray " 8: Exit\n" 142622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray // Synthesized block to avoid critical edge. 143622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray "BasicBlock 5, pred: 1, succ: 3\n" 144622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray " 9: Goto\n"; 145c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 146c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 147c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 0 | 0, 148c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::IF_EQ, 3, 149c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 4 << 12 | 0, 150c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::RETURN | 0 << 8); 151c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 152c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray TestCode(data, expected); 153c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray} 154c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 155c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas GeoffrayTEST(SsaTest, CFG3) { 156c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray // Test that we create a phi for the join block of an if control flow instruction 157804d09372cc3d80d537da1489da4a45e0e19aa5dNicolas Geoffray // when both branches update a local. 158c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const char* expected = 159c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 0, succ: 1\n" 160c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 0: IntConstant 0 [4, 4]\n" 161c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 1: IntConstant 4 [8]\n" 162c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 2: IntConstant 5 [8]\n" 163c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 3: Goto\n" 164c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 1, pred: 0, succ: 3, 2\n" 165c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 4: Equal(0, 0) [5]\n" 166c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 5: If(4)\n" 167c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 2, pred: 1, succ: 4\n" 168c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 6: Goto\n" 169c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 3, pred: 1, succ: 4\n" 170c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 7: Goto\n" 171c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 4, pred: 2, 3, succ: 5\n" 172c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 8: Phi(1, 2) [9]\n" 173c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 9: Return(8)\n" 174c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 5, pred: 4\n" 175c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 10: Exit\n"; 176c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 177c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 178c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 0 | 0, 179c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::IF_EQ, 4, 180c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 4 << 12 | 0, 181c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::GOTO | 0x200, 182c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 5 << 12 | 0, 183c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::RETURN | 0 << 8); 184c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 185c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray TestCode(data, expected); 186c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray} 187c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 188c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas GeoffrayTEST(SsaTest, Loop1) { 189c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray // Test that we create a phi for an initialized local at entry of a loop. 190c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const char* expected = 191c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 0, succ: 1\n" 192c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 0: IntConstant 0 [6, 4, 2, 2]\n" 193c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 1: Goto\n" 194622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray "BasicBlock 1, pred: 0, succ: 5, 6\n" 195c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 2: Equal(0, 0) [3]\n" 196c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 3: If(2)\n" 197622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray "BasicBlock 2, pred: 3, 6, succ: 3\n" 198622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray " 4: Phi(6, 0) [6]\n" 199c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 5: Goto\n" 200622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray "BasicBlock 3, pred: 2, 5, succ: 2\n" 201622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray " 6: Phi(4, 0) [4]\n" 202c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 7: Goto\n" 203622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray "BasicBlock 4\n" 204622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray // Synthesized blocks to avoid critical edge. 205622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray "BasicBlock 5, pred: 1, succ: 3\n" 206622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray " 8: Goto\n" 207622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray "BasicBlock 6, pred: 1, succ: 2\n" 208622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray " 9: Goto\n"; 209c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 210c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 211c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 0 | 0, 212c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::IF_EQ, 3, 213c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::GOTO | 0x100, 214c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::GOTO | 0xFF00); 215c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 216c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray TestCode(data, expected); 217c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray} 218c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 219c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas GeoffrayTEST(SsaTest, Loop2) { 220c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray // Simple loop with one preheader and one back edge. 221c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const char* expected = 222c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 0, succ: 1\n" 223c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 0: IntConstant 0 [4]\n" 224c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 1: IntConstant 4 [4]\n" 225c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 2: Goto\n" 226c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 1, pred: 0, succ: 2\n" 227c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 3: Goto\n" 228c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 2, pred: 1, 3, succ: 4, 3\n" 229c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 4: Phi(0, 1) [5, 5]\n" 230c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 5: Equal(4, 4) [6]\n" 231c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 6: If(5)\n" 232c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 3, pred: 2, succ: 2\n" 233c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 7: Goto\n" 234c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 4, pred: 2, succ: 5\n" 235c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 8: ReturnVoid\n" 236c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 5, pred: 4\n" 237c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 9: Exit\n"; 238c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 239c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 240c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 0 | 0, 241c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::IF_EQ, 4, 242c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 4 << 12 | 0, 243c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::GOTO | 0xFD00, 244c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::RETURN_VOID); 245c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 246c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray TestCode(data, expected); 247c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray} 248c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 249c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas GeoffrayTEST(SsaTest, Loop3) { 250c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray // Test that a local not yet defined at the entry of a loop is handled properly. 251c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const char* expected = 252c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 0, succ: 1\n" 253c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 0: IntConstant 0 [5]\n" 254c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 1: IntConstant 4 [5]\n" 255c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 2: IntConstant 5 [9]\n" 256c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 3: Goto\n" 257c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 1, pred: 0, succ: 2\n" 258c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 4: Goto\n" 259c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 2, pred: 1, 3, succ: 4, 3\n" 260c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 5: Phi(0, 1) [6, 6]\n" 261c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 6: Equal(5, 5) [7]\n" 262c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 7: If(6)\n" 263c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 3, pred: 2, succ: 2\n" 264c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 8: Goto\n" 265c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 4, pred: 2, succ: 5\n" 266c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 9: Return(2)\n" 267c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 5, pred: 4\n" 268c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 10: Exit\n"; 269c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 270c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const uint16_t data[] = TWO_REGISTERS_CODE_ITEM( 271c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 0 | 0, 272c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::IF_EQ, 4, 273c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 4 << 12 | 0, 274c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::GOTO | 0xFD00, 275c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 5 << 12 | 1 << 8, 276c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::RETURN | 1 << 8); 277c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 278c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray TestCode(data, expected); 279c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray} 280c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 281c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas GeoffrayTEST(SsaTest, Loop4) { 282c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray // Make sure we support a preheader of a loop not being the first predecessor 283c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray // in the predecessor list of the header. 284c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const char* expected = 285c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 0, succ: 1\n" 286c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 0: IntConstant 0 [4]\n" 287c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 1: IntConstant 4 [4]\n" 288c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 2: Goto\n" 289c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 1, pred: 0, succ: 4\n" 290c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 3: Goto\n" 291c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 2, pred: 3, 4, succ: 5, 3\n" 292c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 4: Phi(1, 0) [9, 5, 5]\n" 293c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 5: Equal(4, 4) [6]\n" 294c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 6: If(5)\n" 295c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 3, pred: 2, succ: 2\n" 296c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 7: Goto\n" 297c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 4, pred: 1, succ: 2\n" 298c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 8: Goto\n" 299c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 5, pred: 2, succ: 6\n" 300c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 9: Return(4)\n" 301c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 6, pred: 5\n" 302c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 10: Exit\n"; 303c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 304c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 305c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 0 | 0, 306c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::GOTO | 0x500, 307c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::IF_EQ, 5, 308c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 4 << 12 | 0, 309c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::GOTO | 0xFD00, 310c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::GOTO | 0xFC00, 311c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::RETURN | 0 << 8); 312c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 313c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray TestCode(data, expected); 314c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray} 315c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 316c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas GeoffrayTEST(SsaTest, Loop5) { 317c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray // Make sure we create a preheader of a loop when a header originally has two 318c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray // incoming blocks and one back edge. 319c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const char* expected = 320c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 0, succ: 1\n" 321c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 0: IntConstant 0 [4, 4]\n" 322c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 1: IntConstant 4 [14]\n" 323c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 2: IntConstant 5 [14]\n" 324c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 3: Goto\n" 325c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 1, pred: 0, succ: 3, 2\n" 326c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 4: Equal(0, 0) [5]\n" 327c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 5: If(4)\n" 328c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 2, pred: 1, succ: 8\n" 329c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 6: Goto\n" 330c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 3, pred: 1, succ: 8\n" 331c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 7: Goto\n" 332c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 4, pred: 5, 8, succ: 6, 5\n" 333c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 8: Phi(8, 14) [8, 12, 9, 9]\n" 334c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 9: Equal(8, 8) [10]\n" 335c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 10: If(9)\n" 336c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 5, pred: 4, succ: 4\n" 337c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 11: Goto\n" 338c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 6, pred: 4, succ: 7\n" 339c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 12: Return(8)\n" 340c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 7, pred: 6\n" 341c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 13: Exit\n" 342c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 8, pred: 2, 3, succ: 4\n" 343c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 14: Phi(1, 2) [8]\n" 344c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 15: Goto\n"; 345c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 346c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 347c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 0 | 0, 348c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::IF_EQ, 4, 349c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 4 << 12 | 0, 350c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::GOTO | 0x200, 351c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 5 << 12 | 0, 352c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::IF_EQ, 3, 353c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::GOTO | 0xFE00, 354c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::RETURN | 0 << 8); 355c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 356c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray TestCode(data, expected); 357c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray} 358c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 359c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas GeoffrayTEST(SsaTest, Loop6) { 360c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray // Test a loop with one preheader and two back edges (e.g. continue). 361c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const char* expected = 362c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 0, succ: 1\n" 363c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 0: IntConstant 0 [5]\n" 364622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray " 1: IntConstant 4 [14, 8, 8]\n" 365622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray " 2: IntConstant 5 [14]\n" 366c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 3: Goto\n" 367c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 1, pred: 0, succ: 2\n" 368c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 4: Goto\n" 369622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray "BasicBlock 2, pred: 1, 8, succ: 6, 3\n" 370622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray " 5: Phi(0, 14) [12, 6, 6]\n" 371c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 6: Equal(5, 5) [7]\n" 372c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 7: If(6)\n" 373c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 3, pred: 2, succ: 5, 4\n" 374c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 8: Equal(1, 1) [9]\n" 375c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 9: If(8)\n" 376622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray "BasicBlock 4, pred: 3, succ: 8\n" 377c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 10: Goto\n" 378622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray "BasicBlock 5, pred: 3, succ: 8\n" 379c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 11: Goto\n" 380c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 6, pred: 2, succ: 7\n" 381c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 12: Return(5)\n" 382c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 7, pred: 6\n" 383622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray " 13: Exit\n" 384622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray // Synthesized single back edge of loop. 385622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray "BasicBlock 8, pred: 5, 4, succ: 2\n" 386622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray " 14: Phi(1, 2) [5]\n" 387622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray " 15: Goto\n"; 388c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 389c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 390c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 0 | 0, 391c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::IF_EQ, 8, 392c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 4 << 12 | 0, 393c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::IF_EQ, 4, 394c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 5 << 12 | 0, 395c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::GOTO | 0xFA00, 396c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::GOTO | 0xF900, 397c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::RETURN | 0 << 8); 398c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 399c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray TestCode(data, expected); 400c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray} 401c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 402c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas GeoffrayTEST(SsaTest, Loop7) { 403c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray // Test a loop with one preheader, one back edge, and two exit edges (e.g. break). 404c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const char* expected = 405c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 0, succ: 1\n" 406c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 0: IntConstant 0 [5]\n" 407c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 1: IntConstant 4 [5, 8, 8]\n" 408c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 2: IntConstant 5 [12]\n" 409c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 3: Goto\n" 410c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 1, pred: 0, succ: 2\n" 411c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 4: Goto\n" 412ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray "BasicBlock 2, pred: 1, 5, succ: 8, 3\n" 413c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 5: Phi(0, 1) [12, 6, 6]\n" 414c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 6: Equal(5, 5) [7]\n" 415c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 7: If(6)\n" 416c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 3, pred: 2, succ: 5, 4\n" 417c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 8: Equal(1, 1) [9]\n" 418c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 9: If(8)\n" 419c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 4, pred: 3, succ: 6\n" 420c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 10: Goto\n" 421c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 5, pred: 3, succ: 2\n" 422c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 11: Goto\n" 423622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray "BasicBlock 6, pred: 4, 8, succ: 7\n" 424622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray " 12: Phi(2, 5) [13]\n" 425c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 13: Return(12)\n" 426c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 7, pred: 6\n" 427622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray " 14: Exit\n" 428622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray "BasicBlock 8, pred: 2, succ: 6\n" 429622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray " 15: Goto\n"; 430c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 431c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 432c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 0 | 0, 433c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::IF_EQ, 8, 434c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 4 << 12 | 0, 435c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::IF_EQ, 4, 436c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 5 << 12 | 0, 437c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::GOTO | 0x0200, 438c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::GOTO | 0xF900, 439c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::RETURN | 0 << 8); 440c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 441c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray TestCode(data, expected); 442c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray} 443c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 444c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas GeoffrayTEST(SsaTest, DeadLocal) { 445c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray // Test that we correctly handle a local not being used. 446c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const char* expected = 447c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 0, succ: 1\n" 448c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 0: IntConstant 0\n" 449c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 1: Goto\n" 450c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 1, pred: 0, succ: 2\n" 451c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 2: ReturnVoid\n" 452c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray "BasicBlock 2, pred: 1\n" 453c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray " 3: Exit\n"; 454c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 455c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 456c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::CONST_4 | 0 | 0, 457c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray Instruction::RETURN_VOID); 458c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 459c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray TestCode(data, expected); 460c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray} 461c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray 4627c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas GeoffrayTEST(SsaTest, LocalInIf) { 4637c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray // Test that we do not create a phi in the join block when one predecessor 4647c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray // does not update the local. 4657c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray const char* expected = 4667c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray "BasicBlock 0, succ: 1\n" 4677c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray " 0: IntConstant 0 [3, 3]\n" 4687c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray " 1: IntConstant 4\n" 4697c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray " 2: Goto\n" 470ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray "BasicBlock 1, pred: 0, succ: 5, 2\n" 4717c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray " 3: Equal(0, 0) [4]\n" 4727c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray " 4: If(3)\n" 4737c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray "BasicBlock 2, pred: 1, succ: 3\n" 4747c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray " 5: Goto\n" 4757c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray "BasicBlock 3, pred: 2, 5, succ: 4\n" 4767c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray " 6: ReturnVoid\n" 4777c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray "BasicBlock 4, pred: 3\n" 4787c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray " 7: Exit\n" 4797c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray // Synthesized block to avoid critical edge. 4807c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray "BasicBlock 5, pred: 1, succ: 3\n" 4817c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray " 8: Goto\n"; 4827c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray 4837c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray const uint16_t data[] = TWO_REGISTERS_CODE_ITEM( 4847c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray Instruction::CONST_4 | 0 | 0, 4857c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray Instruction::IF_EQ, 3, 4867c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray Instruction::CONST_4 | 4 << 12 | 1 << 8, 4877c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray Instruction::RETURN_VOID); 4887c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray 4897c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray TestCode(data, expected); 4907c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray} 4917c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray 492ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas GeoffrayTEST(SsaTest, MultiplePredecessors) { 493ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray // Test that we do not create a phi when one predecessor 494ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray // does not update the local. 495ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray const char* expected = 496ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray "BasicBlock 0, succ: 1\n" 497ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray " 0: IntConstant 0 [4, 8, 6, 6, 2, 2, 8, 4]\n" 498ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray " 1: Goto\n" 499ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray "BasicBlock 1, pred: 0, succ: 3, 2\n" 500ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray " 2: Equal(0, 0) [3]\n" 501ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray " 3: If(2)\n" 502ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray "BasicBlock 2, pred: 1, succ: 5\n" 503ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray " 4: Add(0, 0)\n" 504ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray " 5: Goto\n" 505ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray "BasicBlock 3, pred: 1, succ: 7, 4\n" 506ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray " 6: Equal(0, 0) [7]\n" 507ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray " 7: If(6)\n" 508ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray "BasicBlock 4, pred: 3, succ: 5\n" 509ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray " 8: Add(0, 0)\n" 510ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray " 9: Goto\n" 511ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray // This block should not get a phi for local 1. 512ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray "BasicBlock 5, pred: 2, 4, 7, succ: 6\n" 513ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray " 10: ReturnVoid\n" 514ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray "BasicBlock 6, pred: 5\n" 515ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray " 11: Exit\n" 516ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray "BasicBlock 7, pred: 3, succ: 5\n" 517ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray " 12: Goto\n"; 518ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray 519ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray const uint16_t data[] = TWO_REGISTERS_CODE_ITEM( 520ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray Instruction::CONST_4 | 0 | 0, 521ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray Instruction::IF_EQ, 5, 522ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray Instruction::ADD_INT_LIT8 | 1 << 8, 0 << 8, 523ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray Instruction::GOTO | 0x0500, 524ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray Instruction::IF_EQ, 4, 525ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray Instruction::ADD_INT_LIT8 | 1 << 8, 0 << 8, 526ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray Instruction::RETURN_VOID); 527ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray 528ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray TestCode(data, expected); 529ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray} 530ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray 531c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray} // namespace art 532