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