ssa_transformation.cc revision 0665fe0966d9591c5378a5d598c6eb6cab67e74a
167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee/* 267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * Copyright (C) 2011 The Android Open Source Project 367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * 467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * Licensed under the Apache License, Version 2.0 (the "License"); 567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * you may not use this file except in compliance with the License. 667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * You may obtain a copy of the License at 767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * 867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * http://www.apache.org/licenses/LICENSE-2.0 967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * 1067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * Unless required by applicable law or agreed to in writing, software 1167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * distributed under the License is distributed on an "AS IS" BASIS, 1267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * See the License for the specific language governing permissions and 1467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * limitations under the License. 1567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee */ 1667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 17eaf09bc65f9a10d12befcdb239156938c9bceef2buzbee#include "compiler_internals.h" 18311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#include "dataflow_iterator.h" 1967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 2011d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughesnamespace art { 2111d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes 22311ca169f4727d46a55bdc8dfa0059719fa72b65buzbeeBasicBlock* MIRGraph::NeedsVisit(BasicBlock* bb) { 23e5f01223ae03b89767dc7881d75dca061121ee36buzbee if (bb != NULL) { 24e5f01223ae03b89767dc7881d75dca061121ee36buzbee if (bb->visited || bb->hidden) { 25e5f01223ae03b89767dc7881d75dca061121ee36buzbee bb = NULL; 26e5f01223ae03b89767dc7881d75dca061121ee36buzbee } 27e5f01223ae03b89767dc7881d75dca061121ee36buzbee } 28e5f01223ae03b89767dc7881d75dca061121ee36buzbee return bb; 29e5f01223ae03b89767dc7881d75dca061121ee36buzbee} 30e5f01223ae03b89767dc7881d75dca061121ee36buzbee 31311ca169f4727d46a55bdc8dfa0059719fa72b65buzbeeBasicBlock* MIRGraph::NextUnvisitedSuccessor(BasicBlock* bb) 32e5f01223ae03b89767dc7881d75dca061121ee36buzbee{ 33fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee BasicBlock* res = NeedsVisit(bb->fall_through); 34e5f01223ae03b89767dc7881d75dca061121ee36buzbee if (res == NULL) { 3552a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee res = NeedsVisit(bb->taken); 36e5f01223ae03b89767dc7881d75dca061121ee36buzbee if (res == NULL) { 37fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (bb->successor_block_list.block_list_type != kNotUsed) { 38e5f01223ae03b89767dc7881d75dca061121ee36buzbee GrowableListIterator iterator; 39fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee GrowableListIteratorInit(&bb->successor_block_list.blocks, 40e5f01223ae03b89767dc7881d75dca061121ee36buzbee &iterator); 41e5f01223ae03b89767dc7881d75dca061121ee36buzbee while (true) { 42cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee SuccessorBlockInfo *sbi = reinterpret_cast<SuccessorBlockInfo*> 4352a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee (GrowableListIteratorNext(&iterator)); 44e5f01223ae03b89767dc7881d75dca061121ee36buzbee if (sbi == NULL) break; 4552a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee res = NeedsVisit(sbi->block); 46e5f01223ae03b89767dc7881d75dca061121ee36buzbee if (res != NULL) break; 47e5f01223ae03b89767dc7881d75dca061121ee36buzbee } 48e5f01223ae03b89767dc7881d75dca061121ee36buzbee } 49e5f01223ae03b89767dc7881d75dca061121ee36buzbee } 50e5f01223ae03b89767dc7881d75dca061121ee36buzbee } 51e5f01223ae03b89767dc7881d75dca061121ee36buzbee return res; 52e5f01223ae03b89767dc7881d75dca061121ee36buzbee} 53e5f01223ae03b89767dc7881d75dca061121ee36buzbee 54311ca169f4727d46a55bdc8dfa0059719fa72b65buzbeevoid MIRGraph::MarkPreOrder(BasicBlock* block) 55e5f01223ae03b89767dc7881d75dca061121ee36buzbee{ 56e5f01223ae03b89767dc7881d75dca061121ee36buzbee block->visited = true; 57fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee /* Enqueue the pre_order block id */ 58311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee InsertGrowableList(cu_, &dfs_order_, block->id); 59e5f01223ae03b89767dc7881d75dca061121ee36buzbee} 60e5f01223ae03b89767dc7881d75dca061121ee36buzbee 61311ca169f4727d46a55bdc8dfa0059719fa72b65buzbeevoid MIRGraph::RecordDFSOrders(BasicBlock* block) 6267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee{ 63e5f01223ae03b89767dc7881d75dca061121ee36buzbee std::vector<BasicBlock*> succ; 64311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee MarkPreOrder(block); 65e5f01223ae03b89767dc7881d75dca061121ee36buzbee succ.push_back(block); 66e5f01223ae03b89767dc7881d75dca061121ee36buzbee while (!succ.empty()) { 67e5f01223ae03b89767dc7881d75dca061121ee36buzbee BasicBlock* curr = succ.back(); 68fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee BasicBlock* next_successor = NextUnvisitedSuccessor(curr); 69fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (next_successor != NULL) { 70311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee MarkPreOrder(next_successor); 71fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee succ.push_back(next_successor); 72e5f01223ae03b89767dc7881d75dca061121ee36buzbee continue; 73e5f01223ae03b89767dc7881d75dca061121ee36buzbee } 74311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee curr->dfs_id = dfs_post_order_.num_used; 75311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee InsertGrowableList(cu_, &dfs_post_order_, curr->id); 76e5f01223ae03b89767dc7881d75dca061121ee36buzbee succ.pop_back(); 77e5f01223ae03b89767dc7881d75dca061121ee36buzbee } 78e5f01223ae03b89767dc7881d75dca061121ee36buzbee} 79e5f01223ae03b89767dc7881d75dca061121ee36buzbee 805b53710b4abcf8f35c91a963a475b72cb34757e6buzbee/* Sort the blocks by the Depth-First-Search */ 81311ca169f4727d46a55bdc8dfa0059719fa72b65buzbeevoid MIRGraph::ComputeDFSOrders() 8267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee{ 83fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee /* Initialize or reset the DFS pre_order list */ 84311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (dfs_order_.elem_list == NULL) { 85311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee CompilerInitGrowableList(cu_, &dfs_order_, GetNumBlocks(), kListDfsOrder); 86a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 87a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Just reset the used length on the counter */ 88311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee dfs_order_.num_used = 0; 89a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 90a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 91fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee /* Initialize or reset the DFS post_order list */ 92311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (dfs_post_order_.elem_list == NULL) { 93311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee CompilerInitGrowableList(cu_, &dfs_post_order_, GetNumBlocks(), kListDfsPostOrder); 94a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 95a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Just reset the used length on the counter */ 96311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee dfs_post_order_.num_used = 0; 97311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 98a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 99e5f01223ae03b89767dc7881d75dca061121ee36buzbee // Reset visited flags from all nodes 1000665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee AllNodesIterator iter(this, false /* not iterative */); 101311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee for (BasicBlock* bb = iter.Next(); bb != NULL; bb = iter.Next()) { 102311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee ClearVisitedFlag(bb); 103e5f01223ae03b89767dc7881d75dca061121ee36buzbee } 104311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee // Record dfs orders 105311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee RecordDFSOrders(GetEntryBlock()); 106e5f01223ae03b89767dc7881d75dca061121ee36buzbee 107311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee num_reachable_blocks_ = dfs_order_.num_used; 10867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 10967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 11067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee/* 11167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * Mark block bit on the per-Dalvik register vector to denote that Dalvik 11267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * register idx is defined in BasicBlock bb. 11367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee */ 114311ca169f4727d46a55bdc8dfa0059719fa72b65buzbeebool MIRGraph::FillDefBlockMatrix(BasicBlock* bb) 11567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee{ 116fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (bb->data_flow_info == NULL) return false; 117a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 118a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee ArenaBitVectorIterator iterator; 119a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 120fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee BitVectorIteratorInit(bb->data_flow_info->def_v, &iterator); 121a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee while (true) { 12252a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee int idx = BitVectorIteratorNext(&iterator); 123a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee if (idx == -1) break; 124a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Block bb defines register idx */ 125311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee SetBit(cu_, def_block_matrix_[idx], bb->id); 126a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 127a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return true; 12867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 12967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 130311ca169f4727d46a55bdc8dfa0059719fa72b65buzbeevoid MIRGraph::ComputeDefBlockMatrix() 13167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee{ 132311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee int num_registers = cu_->num_dalvik_registers; 133fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee /* Allocate num_dalvik_registers bit vector pointers */ 134311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee def_block_matrix_ = static_cast<ArenaBitVector**> 135311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee (NewMem(cu_, sizeof(ArenaBitVector *) * num_registers, true, kAllocDFInfo)); 136a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int i; 137a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 138fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee /* Initialize num_register vectors with num_blocks bits each */ 139fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee for (i = 0; i < num_registers; i++) { 140311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee def_block_matrix_[i] = AllocBitVector(cu_, GetNumBlocks(), false, kBitMapBMatrix); 141311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 1420665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee AllNodesIterator iter(this, false /* not iterative */); 143311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee for (BasicBlock* bb = iter.Next(); bb != NULL; bb = iter.Next()) { 144311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee FindLocalLiveIn(bb); 145311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 1460665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee AllNodesIterator iter2(this, false /* not iterative */); 147311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee for (BasicBlock* bb = iter2.Next(); bb != NULL; bb = iter2.Next()) { 148311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee FillDefBlockMatrix(bb); 149a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 150a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 151a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* 152a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * Also set the incoming parameters as defs in the entry block. 153a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * Only need to handle the parameters for the outer method. 154a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee */ 155311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee int num_regs = cu_->num_dalvik_registers; 156311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee int in_reg = num_regs - cu_->num_ins; 157fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee for (; in_reg < num_regs; in_reg++) { 158311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee SetBit(cu_, def_block_matrix_[in_reg], GetEntryBlock()->id); 159a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 16067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 16167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 16267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee/* Compute the post-order traversal of the CFG */ 163311ca169f4727d46a55bdc8dfa0059719fa72b65buzbeevoid MIRGraph::ComputeDomPostOrderTraversal(BasicBlock* bb) 16467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee{ 165fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee ArenaBitVectorIterator bv_iterator; 166fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee BitVectorIteratorInit(bb->i_dominated, &bv_iterator); 167a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 168a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Iterate through the dominated blocks first */ 169a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee while (true) { 17052a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee //TUNING: hot call to BitVectorIteratorNext 171fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int bb_idx = BitVectorIteratorNext(&bv_iterator); 172fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (bb_idx == -1) break; 173311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee BasicBlock* dominated_bb = GetBasicBlock(bb_idx); 174311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee ComputeDomPostOrderTraversal(dominated_bb); 175a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 176a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 177a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Enter the current block id */ 178311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee InsertGrowableList(cu_, &dom_post_order_traversal_, bb->id); 179a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 180a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* hacky loop detection */ 18152a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee if (bb->taken && IsBitSet(bb->dominators, bb->taken->id)) { 182311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee cu_->attributes |= METHOD_HAS_LOOP; 183a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 18467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 18567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 186311ca169f4727d46a55bdc8dfa0059719fa72b65buzbeevoid MIRGraph::CheckForDominanceFrontier(BasicBlock* dom_bb, 187311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee const BasicBlock* succ_bb) 18867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee{ 189a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* 190a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * TODO - evaluate whether phi will ever need to be inserted into exit 191a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * blocks. 192a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee */ 193fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (succ_bb->i_dom != dom_bb && 194fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee succ_bb->block_type == kDalvikByteCode && 195fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee succ_bb->hidden == false) { 196311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee SetBit(cu_, dom_bb->dom_frontier, succ_bb->id); 197a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 19867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 19967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 20067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee/* Worker function to compute the dominance frontier */ 201311ca169f4727d46a55bdc8dfa0059719fa72b65buzbeebool MIRGraph::ComputeDominanceFrontier(BasicBlock* bb) 20267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee{ 203a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Calculate DF_local */ 204a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee if (bb->taken) { 205311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee CheckForDominanceFrontier(bb, bb->taken); 206a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 207fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (bb->fall_through) { 208311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee CheckForDominanceFrontier(bb, bb->fall_through); 209a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 210fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (bb->successor_block_list.block_list_type != kNotUsed) { 211a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee GrowableListIterator iterator; 212fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee GrowableListIteratorInit(&bb->successor_block_list.blocks, 213a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee &iterator); 214a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee while (true) { 215fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee SuccessorBlockInfo *successor_block_info = 21652a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee reinterpret_cast<SuccessorBlockInfo*>(GrowableListIteratorNext(&iterator)); 217fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (successor_block_info == NULL) break; 218fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee BasicBlock* succ_bb = successor_block_info->block; 219311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee CheckForDominanceFrontier(bb, succ_bb); 220a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 221a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 222a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 223a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Calculate DF_up */ 224fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee ArenaBitVectorIterator bv_iterator; 225fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee BitVectorIteratorInit(bb->i_dominated, &bv_iterator); 226a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee while (true) { 22752a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee //TUNING: hot call to BitVectorIteratorNext 228fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int dominated_idx = BitVectorIteratorNext(&bv_iterator); 229fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (dominated_idx == -1) break; 230311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee BasicBlock* dominated_bb = GetBasicBlock(dominated_idx); 231fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee ArenaBitVectorIterator df_iterator; 232fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee BitVectorIteratorInit(dominated_bb->dom_frontier, &df_iterator); 23367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee while (true) { 23452a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee //TUNING: hot call to BitVectorIteratorNext 235fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int df_up_idx = BitVectorIteratorNext(&df_iterator); 236fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (df_up_idx == -1) break; 237311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee BasicBlock* df_up_block = GetBasicBlock(df_up_idx); 238311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee CheckForDominanceFrontier(bb, df_up_block); 23967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee } 240a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 24167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 242a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return true; 24367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 24467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 24567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee/* Worker function for initializing domination-related data structures */ 246311ca169f4727d46a55bdc8dfa0059719fa72b65buzbeebool MIRGraph::InitializeDominationInfo(BasicBlock* bb) 24767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee{ 248311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee int num_total_blocks = GetBasicBlockListCount(); 249a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 250a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee if (bb->dominators == NULL ) { 251311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee bb->dominators = AllocBitVector(cu_, num_total_blocks, 252a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee false /* expandable */, 253a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee kBitMapDominators); 254311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee bb->i_dominated = AllocBitVector(cu_, num_total_blocks, 255a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee false /* expandable */, 256a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee kBitMapIDominated); 257311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee bb->dom_frontier = AllocBitVector(cu_, num_total_blocks, 258a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee false /* expandable */, 259a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee kBitMapDomFrontier); 260a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 26152a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee ClearAllBits(bb->dominators); 262fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee ClearAllBits(bb->i_dominated); 263fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee ClearAllBits(bb->dom_frontier); 264a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 265a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Set all bits in the dominator vector */ 266fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee SetInitialBits(bb->dominators, num_total_blocks); 267a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 268a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return true; 26967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 27067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 2715b53710b4abcf8f35c91a963a475b72cb34757e6buzbee/* 272fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee * Walk through the ordered i_dom list until we reach common parent. 273fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee * Given the ordering of i_dom_list, this common parent represents the 2745b53710b4abcf8f35c91a963a475b72cb34757e6buzbee * last element of the intersection of block1 and block2 dominators. 2755b53710b4abcf8f35c91a963a475b72cb34757e6buzbee */ 276311ca169f4727d46a55bdc8dfa0059719fa72b65buzbeeint MIRGraph::FindCommonParent(int block1, int block2) 2775b53710b4abcf8f35c91a963a475b72cb34757e6buzbee{ 278a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee while (block1 != block2) { 279a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee while (block1 < block2) { 280311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee block1 = i_dom_list_[block1]; 281a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee DCHECK_NE(block1, NOTVISITED); 282a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 283a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee while (block2 < block1) { 284311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee block2 = i_dom_list_[block2]; 285a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee DCHECK_NE(block2, NOTVISITED); 2865b53710b4abcf8f35c91a963a475b72cb34757e6buzbee } 287a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 288a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return block1; 2895b53710b4abcf8f35c91a963a475b72cb34757e6buzbee} 2905b53710b4abcf8f35c91a963a475b72cb34757e6buzbee 2915b53710b4abcf8f35c91a963a475b72cb34757e6buzbee/* Worker function to compute each block's immediate dominator */ 292311ca169f4727d46a55bdc8dfa0059719fa72b65buzbeebool MIRGraph::ComputeblockIDom(BasicBlock* bb) 2935b53710b4abcf8f35c91a963a475b72cb34757e6buzbee{ 294a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee GrowableListIterator iter; 295a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int idom = -1; 2965b53710b4abcf8f35c91a963a475b72cb34757e6buzbee 297a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Special-case entry block */ 298311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (bb == GetEntryBlock()) { 2995b53710b4abcf8f35c91a963a475b72cb34757e6buzbee return false; 300a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 301a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 302a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Iterate through the predecessors */ 30352a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee GrowableListIteratorInit(bb->predecessors, &iter); 304a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 305a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Find the first processed predecessor */ 306a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee while (true) { 307fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee BasicBlock* pred_bb = reinterpret_cast<BasicBlock*>(GrowableListIteratorNext(&iter)); 308fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee CHECK(pred_bb != NULL); 309311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (i_dom_list_[pred_bb->dfs_id] != NOTVISITED) { 310fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee idom = pred_bb->dfs_id; 311a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 312a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 313a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 314a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 315a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Scan the rest of the predecessors */ 316a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee while (true) { 317fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee BasicBlock* pred_bb = reinterpret_cast<BasicBlock*>(GrowableListIteratorNext(&iter)); 318fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (!pred_bb) break; 319311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (i_dom_list_[pred_bb->dfs_id] == NOTVISITED) { 320a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee continue; 321a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 322311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee idom = FindCommonParent(pred_bb->dfs_id, idom); 323a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 324a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 325a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 326a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee DCHECK_NE(idom, NOTVISITED); 327a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 328a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Did something change? */ 329311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (i_dom_list_[bb->dfs_id] != idom) { 330311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee i_dom_list_[bb->dfs_id] = idom; 331a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return true; 332a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 333a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return false; 3345b53710b4abcf8f35c91a963a475b72cb34757e6buzbee} 3355b53710b4abcf8f35c91a963a475b72cb34757e6buzbee 3365b53710b4abcf8f35c91a963a475b72cb34757e6buzbee/* Worker function to compute each block's domintors */ 337311ca169f4727d46a55bdc8dfa0059719fa72b65buzbeebool MIRGraph::ComputeBlockDominators(BasicBlock* bb) 3385b53710b4abcf8f35c91a963a475b72cb34757e6buzbee{ 339311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (bb == GetEntryBlock()) { 34052a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee ClearAllBits(bb->dominators); 341a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 342fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee CopyBitVector(bb->dominators, bb->i_dom->dominators); 343a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 344311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee SetBit(cu_, bb->dominators, bb->id); 345a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return false; 3465b53710b4abcf8f35c91a963a475b72cb34757e6buzbee} 3475b53710b4abcf8f35c91a963a475b72cb34757e6buzbee 348311ca169f4727d46a55bdc8dfa0059719fa72b65buzbeebool MIRGraph::SetDominators(BasicBlock* bb) 3495b53710b4abcf8f35c91a963a475b72cb34757e6buzbee{ 350311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (bb != GetEntryBlock()) { 351311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee int idom_dfs_idx = i_dom_list_[bb->dfs_id]; 352fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK_NE(idom_dfs_idx, NOTVISITED); 353311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee int i_dom_idx = dfs_post_order_.elem_list[idom_dfs_idx]; 354311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee BasicBlock* i_dom = GetBasicBlock(i_dom_idx); 355311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (cu_->enable_debug & (1 << kDebugVerifyDataflow)) { 356fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK_EQ(bb->i_dom->id, i_dom->id); 3575b53710b4abcf8f35c91a963a475b72cb34757e6buzbee } 358fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bb->i_dom = i_dom; 359fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee /* Add bb to the i_dominated set of the immediate dominator block */ 360311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee SetBit(cu_, i_dom->i_dominated, bb->id); 361a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 362a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return false; 3635b53710b4abcf8f35c91a963a475b72cb34757e6buzbee} 3645b53710b4abcf8f35c91a963a475b72cb34757e6buzbee 36567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee/* Compute dominators, immediate dominator, and dominance fronter */ 366311ca169f4727d46a55bdc8dfa0059719fa72b65buzbeevoid MIRGraph::ComputeDominators() 36767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee{ 368311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee int num_reachable_blocks = num_reachable_blocks_; 369311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee int num_total_blocks = GetBasicBlockListCount(); 370a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 371a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Initialize domination-related data structures */ 3720665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee ReachableNodesIterator iter(this, false /* not iterative */); 373311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee for (BasicBlock* bb = iter.Next(); bb != NULL; bb = iter.Next()) { 374311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee InitializeDominationInfo(bb); 375311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 376a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 377fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee /* Initalize & Clear i_dom_list */ 378311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (i_dom_list_ == NULL) { 379311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee i_dom_list_ = static_cast<int*>(NewMem(cu_, sizeof(int) * num_reachable_blocks, 380cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee false, kAllocDFInfo)); 381a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 382fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee for (int i = 0; i < num_reachable_blocks; i++) { 383311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee i_dom_list_[i] = NOTVISITED; 384a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 385a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 386fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee /* For post-order, last block is entry block. Set its i_dom to istelf */ 387311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee DCHECK_EQ(GetEntryBlock()->dfs_id, num_reachable_blocks-1); 388311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee i_dom_list_[GetEntryBlock()->dfs_id] = GetEntryBlock()->dfs_id; 389a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 390a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Compute the immediate dominators */ 3910665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee ReversePostOrderDfsIterator iter2(this, true /* iterative */); 392311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee bool change = false; 393311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee for (BasicBlock* bb = iter2.Next(false); bb != NULL; bb = iter2.Next(change)) { 394311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee change = ComputeblockIDom(bb); 395311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 396a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 397a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Set the dominator for the root node */ 398311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee ClearAllBits(GetEntryBlock()->dominators); 399311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee SetBit(cu_, GetEntryBlock()->dominators, GetEntryBlock()->id); 400a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 401311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (temp_block_v_ == NULL) { 402311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee temp_block_v_ = AllocBitVector(cu_, num_total_blocks, false /* expandable */, kBitMapTmpBlockV); 403a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 404311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee ClearAllBits(temp_block_v_); 405a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 406311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee GetEntryBlock()->i_dom = NULL; 4075b53710b4abcf8f35c91a963a475b72cb34757e6buzbee 4080665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee ReachableNodesIterator iter3(this, false /* not iterative */); 409311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee for (BasicBlock* bb = iter3.Next(); bb != NULL; bb = iter3.Next()) { 410311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee SetDominators(bb); 411a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 412a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 4130665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee ReversePostOrderDfsIterator iter4(this, false /* not iterative */); 414311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee for (BasicBlock* bb = iter4.Next(); bb != NULL; bb = iter4.Next()) { 415311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee ComputeBlockDominators(bb); 416311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 417a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 418a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* 419a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * Now go ahead and compute the post order traversal based on the 420fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee * i_dominated sets. 421a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee */ 422311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (dom_post_order_traversal_.elem_list == NULL) { 423311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee CompilerInitGrowableList(cu_, &dom_post_order_traversal_, 424fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee num_reachable_blocks, kListDomPostOrderTraversal); 425a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 426311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee dom_post_order_traversal_.num_used = 0; 427a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 428a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 429311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee ComputeDomPostOrderTraversal(GetEntryBlock()); 430311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee DCHECK_EQ(dom_post_order_traversal_.num_used, static_cast<unsigned>(num_reachable_blocks_)); 431a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 432a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Now compute the dominance frontier for each block */ 4330665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee PostOrderDOMIterator iter5(this, false /* not iterative */); 434311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee for (BasicBlock* bb = iter5.Next(); bb != NULL; bb = iter5.Next()) { 435311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee ComputeDominanceFrontier(bb); 436311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 43767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 43867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 43967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee/* 44067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * Perform dest U= src1 ^ ~src2 44167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * This is probably not general enough to be placed in BitVector.[ch]. 44267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee */ 443311ca169f4727d46a55bdc8dfa0059719fa72b65buzbeevoid MIRGraph::ComputeSuccLineIn(ArenaBitVector* dest, const ArenaBitVector* src1, 444311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee const ArenaBitVector* src2) 44567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee{ 446fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (dest->storage_size != src1->storage_size || 447fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee dest->storage_size != src2->storage_size || 448a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee dest->expandable != src1->expandable || 449a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee dest->expandable != src2->expandable) { 450a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(FATAL) << "Incompatible set properties"; 451a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 452a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 453a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee unsigned int idx; 454fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee for (idx = 0; idx < dest->storage_size; idx++) { 455a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee dest->storage[idx] |= src1->storage[idx] & ~src2->storage[idx]; 456a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 45767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 45867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 45967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee/* 46067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * Iterate through all successor blocks and propagate up the live-in sets. 46167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * The calculated result is used for phi-node pruning - where we only need to 46267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * insert a phi node if the variable is live-in to the block. 46367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee */ 464311ca169f4727d46a55bdc8dfa0059719fa72b65buzbeebool MIRGraph::ComputeBlockLiveIns(BasicBlock* bb) 46567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee{ 466311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee ArenaBitVector* temp_dalvik_register_v = temp_dalvik_register_v_; 467fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee 468fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (bb->data_flow_info == NULL) return false; 469fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee CopyBitVector(temp_dalvik_register_v, bb->data_flow_info->live_in_v); 470fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (bb->taken && bb->taken->data_flow_info) 471fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee ComputeSuccLineIn(temp_dalvik_register_v, bb->taken->data_flow_info->live_in_v, 472fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bb->data_flow_info->def_v); 473fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (bb->fall_through && bb->fall_through->data_flow_info) 474311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee ComputeSuccLineIn(temp_dalvik_register_v, bb->fall_through->data_flow_info->live_in_v, 475fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bb->data_flow_info->def_v); 476fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (bb->successor_block_list.block_list_type != kNotUsed) { 477a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee GrowableListIterator iterator; 478fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee GrowableListIteratorInit(&bb->successor_block_list.blocks, 479a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee &iterator); 480a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee while (true) { 481fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee SuccessorBlockInfo *successor_block_info = 48252a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee reinterpret_cast<SuccessorBlockInfo*>(GrowableListIteratorNext(&iterator)); 483fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (successor_block_info == NULL) break; 484fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee BasicBlock* succ_bb = successor_block_info->block; 485fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (succ_bb->data_flow_info) { 486311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee ComputeSuccLineIn(temp_dalvik_register_v, succ_bb->data_flow_info->live_in_v, 487fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bb->data_flow_info->def_v); 488a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 48967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee } 490a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 491fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (CompareBitVectors(temp_dalvik_register_v, bb->data_flow_info->live_in_v)) { 492fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee CopyBitVector(bb->data_flow_info->live_in_v, temp_dalvik_register_v); 493a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return true; 494a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 495a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return false; 49667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 49767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 49867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee/* Insert phi nodes to for each variable to the dominance frontiers */ 499311ca169f4727d46a55bdc8dfa0059719fa72b65buzbeevoid MIRGraph::InsertPhiNodes() 50067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee{ 501fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int dalvik_reg; 502311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee ArenaBitVector* phi_blocks = AllocBitVector(cu_, GetNumBlocks(), false, kBitMapPhi); 503311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee ArenaBitVector* tmp_blocks = AllocBitVector(cu_, GetNumBlocks(), false, kBitMapTmpBlocks); 504311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee ArenaBitVector* input_blocks = AllocBitVector(cu_, GetNumBlocks(), false, kBitMapInputBlocks); 505fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee 506311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee temp_dalvik_register_v_ = 507311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee AllocBitVector(cu_, cu_->num_dalvik_registers, false, kBitMapRegisterV); 508a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 5090665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee PostOrderDfsIterator iter(this, true /* iterative */); 510311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee bool change = false; 511311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee for (BasicBlock* bb = iter.Next(false); bb != NULL; bb = iter.Next(change)) { 512311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee change = ComputeBlockLiveIns(bb); 513311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 514a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 515a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Iterate through each Dalvik register */ 516311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee for (dalvik_reg = cu_->num_dalvik_registers - 1; dalvik_reg >= 0; dalvik_reg--) { 517a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee bool change; 518a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee ArenaBitVectorIterator iterator; 519a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 520311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee CopyBitVector(input_blocks, def_block_matrix_[dalvik_reg]); 521fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee ClearAllBits(phi_blocks); 522a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 523a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Calculate the phi blocks for each Dalvik register */ 524a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee do { 525a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee change = false; 526fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee ClearAllBits(tmp_blocks); 527fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee BitVectorIteratorInit(input_blocks, &iterator); 528a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 529a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee while (true) { 53052a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee int idx = BitVectorIteratorNext(&iterator); 531a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee if (idx == -1) break; 532311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee BasicBlock* def_bb = GetBasicBlock(idx); 533a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 534fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee /* Merge the dominance frontier to tmp_blocks */ 53552a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee //TUNING: hot call to UnifyBitVetors 536fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (def_bb->dom_frontier != NULL) { 537fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee UnifyBitVetors(tmp_blocks, tmp_blocks, def_bb->dom_frontier); 538a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 53967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee } 540fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (CompareBitVectors(phi_blocks, tmp_blocks)) { 541a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee change = true; 542fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee CopyBitVector(phi_blocks, tmp_blocks); 543a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 544a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* 545a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * Iterate through the original blocks plus the new ones in 546a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * the dominance frontier. 547a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee */ 548fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee CopyBitVector(input_blocks, phi_blocks); 549311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee UnifyBitVetors(input_blocks, input_blocks, def_block_matrix_[dalvik_reg]); 550a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 551a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } while (change); 552a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 553a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* 554fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee * Insert a phi node for dalvik_reg in the phi_blocks if the Dalvik 555a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * register is in the live-in set. 556a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee */ 557fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee BitVectorIteratorInit(phi_blocks, &iterator); 558a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee while (true) { 55952a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee int idx = BitVectorIteratorNext(&iterator); 560a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee if (idx == -1) break; 561311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee BasicBlock* phi_bb = GetBasicBlock(idx); 562a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Variable will be clobbered before being used - no need for phi */ 563fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (!IsBitSet(phi_bb->data_flow_info->live_in_v, dalvik_reg)) continue; 564311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee MIR *phi = static_cast<MIR*>(NewMem(cu_, sizeof(MIR), true, kAllocDFInfo)); 565cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee phi->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpPhi); 566fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee phi->dalvikInsn.vA = dalvik_reg; 567fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee phi->offset = phi_bb->start_offset; 568311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee phi->m_unit_index = 0; // Arbitrarily assign all Phi nodes to outermost method. 569fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee PrependMIR(phi_bb, phi); 570a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 571a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 57267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 57367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 57467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee/* 57567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * Worker function to insert phi-operands with latest SSA names from 57667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * predecessor blocks 57767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee */ 578311ca169f4727d46a55bdc8dfa0059719fa72b65buzbeebool MIRGraph::InsertPhiNodeOperands(BasicBlock* bb) 57967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee{ 580a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee GrowableListIterator iter; 581a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee MIR *mir; 5826969d50c820bd63043940b0e0f0ddc6e6ac763b0buzbee std::vector<int> uses; 583fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee std::vector<int> incoming_arc; 584a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 585a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Phi nodes are at the beginning of each block */ 58628c9a83398a6e48eefb9b79a390920629bbb8519buzbee for (mir = bb->first_mir_insn; mir != NULL; mir = mir->next) { 587cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee if (mir->dalvikInsn.opcode != static_cast<Instruction::Code>(kMirOpPhi)) 588a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return true; 589fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int ssa_reg = mir->ssa_rep->defs[0]; 590fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK_GE(ssa_reg, 0); // Shouldn't see compiler temps here 591311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee int v_reg = SRegToVReg(ssa_reg); 59267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 5936969d50c820bd63043940b0e0f0ddc6e6ac763b0buzbee uses.clear(); 594fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee incoming_arc.clear(); 59567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 596a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Iterate through the predecessors */ 59752a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee GrowableListIteratorInit(bb->predecessors, &iter); 598a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee while (true) { 599fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee BasicBlock* pred_bb = 60052a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee reinterpret_cast<BasicBlock*>(GrowableListIteratorNext(&iter)); 601fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (!pred_bb) break; 602fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int ssa_reg = pred_bb->data_flow_info->vreg_to_ssa_map[v_reg]; 603fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee uses.push_back(ssa_reg); 604fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee incoming_arc.push_back(pred_bb->id); 605a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 60667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 607a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Count the number of SSA registers for a Dalvik register */ 608fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int num_uses = uses.size(); 609fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee mir->ssa_rep->num_uses = num_uses; 610fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee mir->ssa_rep->uses = 611311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee static_cast<int*>(NewMem(cu_, sizeof(int) * num_uses, false, kAllocDFInfo)); 612fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee mir->ssa_rep->fp_use = 613311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee static_cast<bool*>(NewMem(cu_, sizeof(bool) * num_uses, true, kAllocDFInfo)); 6142cfc639fc803bf67e3d2a961f2b637220c86d5f7buzbee int* incoming = 615311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee static_cast<int*>(NewMem(cu_, sizeof(int) * num_uses, false, kAllocDFInfo)); 6162cfc639fc803bf67e3d2a961f2b637220c86d5f7buzbee // TODO: Ugly, rework (but don't burden each MIR/LIR for Phi-only needs) 617cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee mir->dalvikInsn.vB = reinterpret_cast<uintptr_t>(incoming); 61867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 619a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Set the uses array for the phi node */ 620fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int *use_ptr = mir->ssa_rep->uses; 621fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee for (int i = 0; i < num_uses; i++) { 622fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee *use_ptr++ = uses[i]; 623fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee *incoming++ = incoming_arc[i]; 62467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee } 625a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 62667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 627a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return true; 62867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 62967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 630311ca169f4727d46a55bdc8dfa0059719fa72b65buzbeevoid MIRGraph::DoDFSPreOrderSSARename(BasicBlock* block) 631f0cde549bed96e16401a347a4511b59130c61e84buzbee{ 632f0cde549bed96e16401a347a4511b59130c61e84buzbee 633a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee if (block->visited || block->hidden) return; 634a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee block->visited = true; 635a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 636a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Process this block */ 637311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee DoSSAConversion(block); 638311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee int map_size = sizeof(int) * cu_->num_dalvik_registers; 639a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 640a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Save SSA map snapshot */ 641311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee int* saved_ssa_map = static_cast<int*>(NewMem(cu_, map_size, false, kAllocDalvikToSSAMap)); 642311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee memcpy(saved_ssa_map, vreg_to_ssa_map_, map_size); 643a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 644fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (block->fall_through) { 645311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee DoDFSPreOrderSSARename(block->fall_through); 646a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Restore SSA map snapshot */ 647311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee memcpy(vreg_to_ssa_map_, saved_ssa_map, map_size); 648a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 649a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee if (block->taken) { 650311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee DoDFSPreOrderSSARename(block->taken); 651a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Restore SSA map snapshot */ 652311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee memcpy(vreg_to_ssa_map_, saved_ssa_map, map_size); 653a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 654fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (block->successor_block_list.block_list_type != kNotUsed) { 655a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee GrowableListIterator iterator; 656fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee GrowableListIteratorInit(&block->successor_block_list.blocks, &iterator); 657a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee while (true) { 658fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee SuccessorBlockInfo *successor_block_info = 65952a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee reinterpret_cast<SuccessorBlockInfo*>(GrowableListIteratorNext(&iterator)); 660fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (successor_block_info == NULL) break; 661fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee BasicBlock* succ_bb = successor_block_info->block; 662311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee DoDFSPreOrderSSARename(succ_bb); 663a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Restore SSA map snapshot */ 664311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee memcpy(vreg_to_ssa_map_, saved_ssa_map, map_size); 665a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 666a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 667311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee vreg_to_ssa_map_ = saved_ssa_map; 668a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return; 669f0cde549bed96e16401a347a4511b59130c61e84buzbee} 670f0cde549bed96e16401a347a4511b59130c61e84buzbee 67167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee/* Perform SSA transformation for the whole method */ 672311ca169f4727d46a55bdc8dfa0059719fa72b65buzbeevoid MIRGraph::SSATransformation() 67367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee{ 674a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Compute the DFS order */ 675311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee ComputeDFSOrders(); 67667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 677311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (!cu_->disable_dataflow) { 678a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Compute the dominator info */ 679311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee ComputeDominators(); 680a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 68167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 682a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Allocate data structures in preparation for SSA conversion */ 683311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee CompilerInitializeSSAConversion(); 68467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 685311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (!cu_->disable_dataflow) { 686a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Find out the "Dalvik reg def x block" relation */ 687311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee ComputeDefBlockMatrix(); 68867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 689a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Insert phi nodes to dominance frontiers for all variables */ 690311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee InsertPhiNodes(); 691a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 69267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 693a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Rename register names by local defs and phi nodes */ 6940665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee AllNodesIterator iter(this, false /* not iterative */); 695311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee for (BasicBlock* bb = iter.Next(); bb != NULL; bb = iter.Next()) { 696311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee ClearVisitedFlag(bb); 697311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 698311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee DoDFSPreOrderSSARename(GetEntryBlock()); 699a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 700311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (!cu_->disable_dataflow) { 701a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* 702a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * Shared temp bit vector used by each block to count the number of defs 703a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * from all the predecessor blocks. 704a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee */ 705311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee temp_ssa_register_v_ = AllocBitVector(cu_, GetNumSSARegs(), false, kBitMapTempSSARegisterV); 7062cfc639fc803bf67e3d2a961f2b637220c86d5f7buzbee 707a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Insert phi-operands with latest SSA names from predecessor blocks */ 7080665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee ReachableNodesIterator iter(this, false /* not iterative */); 709311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee for (BasicBlock* bb = iter.Next(); bb != NULL; bb = iter.Next()) { 710311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee InsertPhiNodeOperands(bb); 711311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 712311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 713311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (cu_->enable_debug & (1 << kDebugDumpCFG)) { 714311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee DumpCFG("/sdcard/3_post_ssa_cfg/", false); 715a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 71667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 71711d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes 71811d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes} // namespace art 719