| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  * Copyright (C) 2011 The Android Open Source Project | 
 | 3 |  * | 
 | 4 |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
 | 5 |  * you may not use this file except in compliance with the License. | 
 | 6 |  * You may obtain a copy of the License at | 
 | 7 |  * | 
 | 8 |  *      http://www.apache.org/licenses/LICENSE-2.0 | 
 | 9 |  * | 
 | 10 |  * Unless required by applicable law or agreed to in writing, software | 
 | 11 |  * distributed under the License is distributed on an "AS IS" BASIS, | 
 | 12 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 | 13 |  * See the License for the specific language governing permissions and | 
 | 14 |  * limitations under the License. | 
 | 15 |  */ | 
 | 16 |  | 
| Ian Rogers | e77493c | 2014-08-20 15:08:45 -0700 | [diff] [blame] | 17 | #include "base/bit_vector-inl.h" | 
| buzbee | eaf09bc | 2012-11-15 14:51:41 -0800 | [diff] [blame] | 18 | #include "compiler_internals.h" | 
| Ian Rogers | 8d3a117 | 2013-06-04 01:13:28 -0700 | [diff] [blame] | 19 | #include "dataflow_iterator-inl.h" | 
| Vladimir Marko | c9360ce | 2014-06-05 20:09:47 +0100 | [diff] [blame] | 20 | #include "utils/scoped_arena_containers.h" | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 21 |  | 
| buzbee | 1fd3346 | 2013-03-25 13:40:45 -0700 | [diff] [blame] | 22 | #define NOTVISITED (-1) | 
 | 23 |  | 
| Elliott Hughes | 11d1b0c | 2012-01-23 16:57:47 -0800 | [diff] [blame] | 24 | namespace art { | 
 | 25 |  | 
| buzbee | a5abf70 | 2013-04-12 14:39:29 -0700 | [diff] [blame] | 26 | void MIRGraph::ClearAllVisitedFlags() { | 
| buzbee | 56c7178 | 2013-09-05 17:13:19 -0700 | [diff] [blame] | 27 |   AllNodesIterator iter(this); | 
| buzbee | a5abf70 | 2013-04-12 14:39:29 -0700 | [diff] [blame] | 28 |   for (BasicBlock* bb = iter.Next(); bb != NULL; bb = iter.Next()) { | 
 | 29 |     bb->visited = false; | 
 | 30 |   } | 
 | 31 | } | 
 | 32 |  | 
| buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 33 | BasicBlock* MIRGraph::NeedsVisit(BasicBlock* bb) { | 
| buzbee | e5f0122 | 2012-06-14 15:19:35 -0700 | [diff] [blame] | 34 |   if (bb != NULL) { | 
 | 35 |     if (bb->visited || bb->hidden) { | 
 | 36 |       bb = NULL; | 
 | 37 |     } | 
 | 38 |   } | 
 | 39 |   return bb; | 
 | 40 | } | 
 | 41 |  | 
| Brian Carlstrom | 2ce745c | 2013-07-17 17:44:30 -0700 | [diff] [blame] | 42 | BasicBlock* MIRGraph::NextUnvisitedSuccessor(BasicBlock* bb) { | 
| buzbee | 0d82948 | 2013-10-11 15:24:55 -0700 | [diff] [blame] | 43 |   BasicBlock* res = NeedsVisit(GetBasicBlock(bb->fall_through)); | 
| buzbee | e5f0122 | 2012-06-14 15:19:35 -0700 | [diff] [blame] | 44 |   if (res == NULL) { | 
| buzbee | 0d82948 | 2013-10-11 15:24:55 -0700 | [diff] [blame] | 45 |     res = NeedsVisit(GetBasicBlock(bb->taken)); | 
| buzbee | e5f0122 | 2012-06-14 15:19:35 -0700 | [diff] [blame] | 46 |     if (res == NULL) { | 
| buzbee | 0d82948 | 2013-10-11 15:24:55 -0700 | [diff] [blame] | 47 |       if (bb->successor_block_list_type != kNotUsed) { | 
 | 48 |         GrowableArray<SuccessorBlockInfo*>::Iterator iterator(bb->successor_blocks); | 
| buzbee | e5f0122 | 2012-06-14 15:19:35 -0700 | [diff] [blame] | 49 |         while (true) { | 
| buzbee | 862a760 | 2013-04-05 10:58:54 -0700 | [diff] [blame] | 50 |           SuccessorBlockInfo *sbi = iterator.Next(); | 
| Brian Carlstrom | 0cd7ec2 | 2013-07-17 23:40:20 -0700 | [diff] [blame] | 51 |           if (sbi == NULL) { | 
 | 52 |             break; | 
 | 53 |           } | 
| buzbee | 0d82948 | 2013-10-11 15:24:55 -0700 | [diff] [blame] | 54 |           res = NeedsVisit(GetBasicBlock(sbi->block)); | 
| Brian Carlstrom | 0cd7ec2 | 2013-07-17 23:40:20 -0700 | [diff] [blame] | 55 |           if (res != NULL) { | 
 | 56 |             break; | 
 | 57 |           } | 
| buzbee | e5f0122 | 2012-06-14 15:19:35 -0700 | [diff] [blame] | 58 |         } | 
 | 59 |       } | 
 | 60 |     } | 
 | 61 |   } | 
 | 62 |   return res; | 
 | 63 | } | 
 | 64 |  | 
| Brian Carlstrom | 2ce745c | 2013-07-17 17:44:30 -0700 | [diff] [blame] | 65 | void MIRGraph::MarkPreOrder(BasicBlock* block) { | 
| buzbee | e5f0122 | 2012-06-14 15:19:35 -0700 | [diff] [blame] | 66 |   block->visited = true; | 
| buzbee | fa57c47 | 2012-11-21 12:06:18 -0800 | [diff] [blame] | 67 |   /* Enqueue the pre_order block id */ | 
| buzbee | 0d82948 | 2013-10-11 15:24:55 -0700 | [diff] [blame] | 68 |   if (block->id != NullBasicBlockId) { | 
 | 69 |     dfs_order_->Insert(block->id); | 
 | 70 |   } | 
| buzbee | e5f0122 | 2012-06-14 15:19:35 -0700 | [diff] [blame] | 71 | } | 
 | 72 |  | 
| Brian Carlstrom | 2ce745c | 2013-07-17 17:44:30 -0700 | [diff] [blame] | 73 | void MIRGraph::RecordDFSOrders(BasicBlock* block) { | 
| Vladimir Marko | c9360ce | 2014-06-05 20:09:47 +0100 | [diff] [blame] | 74 |   DCHECK(temp_scoped_alloc_.get() != nullptr); | 
 | 75 |   ScopedArenaVector<BasicBlock*> succ(temp_scoped_alloc_->Adapter()); | 
| buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 76 |   MarkPreOrder(block); | 
| buzbee | e5f0122 | 2012-06-14 15:19:35 -0700 | [diff] [blame] | 77 |   succ.push_back(block); | 
 | 78 |   while (!succ.empty()) { | 
 | 79 |     BasicBlock* curr = succ.back(); | 
| buzbee | fa57c47 | 2012-11-21 12:06:18 -0800 | [diff] [blame] | 80 |     BasicBlock* next_successor = NextUnvisitedSuccessor(curr); | 
 | 81 |     if (next_successor != NULL) { | 
| buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 82 |       MarkPreOrder(next_successor); | 
| buzbee | fa57c47 | 2012-11-21 12:06:18 -0800 | [diff] [blame] | 83 |       succ.push_back(next_successor); | 
| buzbee | e5f0122 | 2012-06-14 15:19:35 -0700 | [diff] [blame] | 84 |       continue; | 
 | 85 |     } | 
| buzbee | 862a760 | 2013-04-05 10:58:54 -0700 | [diff] [blame] | 86 |     curr->dfs_id = dfs_post_order_->Size(); | 
| buzbee | 0d82948 | 2013-10-11 15:24:55 -0700 | [diff] [blame] | 87 |     if (curr->id != NullBasicBlockId) { | 
 | 88 |       dfs_post_order_->Insert(curr->id); | 
 | 89 |     } | 
| buzbee | e5f0122 | 2012-06-14 15:19:35 -0700 | [diff] [blame] | 90 |     succ.pop_back(); | 
 | 91 |   } | 
 | 92 | } | 
 | 93 |  | 
| buzbee | 5b53710 | 2012-01-17 17:33:47 -0800 | [diff] [blame] | 94 | /* Sort the blocks by the Depth-First-Search */ | 
| Brian Carlstrom | 2ce745c | 2013-07-17 17:44:30 -0700 | [diff] [blame] | 95 | void MIRGraph::ComputeDFSOrders() { | 
| buzbee | fa57c47 | 2012-11-21 12:06:18 -0800 | [diff] [blame] | 96 |   /* Initialize or reset the DFS pre_order list */ | 
| buzbee | 862a760 | 2013-04-05 10:58:54 -0700 | [diff] [blame] | 97 |   if (dfs_order_ == NULL) { | 
| buzbee | 0d82948 | 2013-10-11 15:24:55 -0700 | [diff] [blame] | 98 |     dfs_order_ = new (arena_) GrowableArray<BasicBlockId>(arena_, GetNumBlocks(), | 
 | 99 |                                                           kGrowableArrayDfsOrder); | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 100 |   } else { | 
 | 101 |     /* Just reset the used length on the counter */ | 
| buzbee | 862a760 | 2013-04-05 10:58:54 -0700 | [diff] [blame] | 102 |     dfs_order_->Reset(); | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 103 |   } | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 104 |  | 
| buzbee | fa57c47 | 2012-11-21 12:06:18 -0800 | [diff] [blame] | 105 |   /* Initialize or reset the DFS post_order list */ | 
| buzbee | 862a760 | 2013-04-05 10:58:54 -0700 | [diff] [blame] | 106 |   if (dfs_post_order_ == NULL) { | 
| buzbee | 0d82948 | 2013-10-11 15:24:55 -0700 | [diff] [blame] | 107 |     dfs_post_order_ = new (arena_) GrowableArray<BasicBlockId>(arena_, GetNumBlocks(), | 
 | 108 |                                                                kGrowableArrayDfsPostOrder); | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 109 |   } else { | 
 | 110 |     /* Just reset the used length on the counter */ | 
| buzbee | 862a760 | 2013-04-05 10:58:54 -0700 | [diff] [blame] | 111 |     dfs_post_order_->Reset(); | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 112 |   } | 
| buzbee | 5b53710 | 2012-01-17 17:33:47 -0800 | [diff] [blame] | 113 |  | 
| buzbee | e5f0122 | 2012-06-14 15:19:35 -0700 | [diff] [blame] | 114 |   // Reset visited flags from all nodes | 
| buzbee | a5abf70 | 2013-04-12 14:39:29 -0700 | [diff] [blame] | 115 |   ClearAllVisitedFlags(); | 
 | 116 |  | 
| buzbee | e5f0122 | 2012-06-14 15:19:35 -0700 | [diff] [blame] | 117 |   // Record dfs orders | 
| buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 118 |   RecordDFSOrders(GetEntryBlock()); | 
| buzbee | e5f0122 | 2012-06-14 15:19:35 -0700 | [diff] [blame] | 119 |  | 
| buzbee | 862a760 | 2013-04-05 10:58:54 -0700 | [diff] [blame] | 120 |   num_reachable_blocks_ = dfs_order_->Size(); | 
| Andreas Gampe | 4439596 | 2014-06-13 13:44:40 -0700 | [diff] [blame] | 121 |  | 
 | 122 |   if (num_reachable_blocks_ != num_blocks_) { | 
 | 123 |     // Hide all unreachable blocks. | 
 | 124 |     AllNodesIterator iter(this); | 
 | 125 |     for (BasicBlock* bb = iter.Next(); bb != NULL; bb = iter.Next()) { | 
 | 126 |       if (!bb->visited) { | 
 | 127 |         bb->Hide(cu_); | 
 | 128 |       } | 
 | 129 |     } | 
 | 130 |   } | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 131 | } | 
 | 132 |  | 
 | 133 | /* | 
 | 134 |  * Mark block bit on the per-Dalvik register vector to denote that Dalvik | 
 | 135 |  * register idx is defined in BasicBlock bb. | 
 | 136 |  */ | 
| Brian Carlstrom | 2ce745c | 2013-07-17 17:44:30 -0700 | [diff] [blame] | 137 | bool MIRGraph::FillDefBlockMatrix(BasicBlock* bb) { | 
| Brian Carlstrom | 0cd7ec2 | 2013-07-17 23:40:20 -0700 | [diff] [blame] | 138 |   if (bb->data_flow_info == NULL) { | 
 | 139 |     return false; | 
 | 140 |   } | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 141 |  | 
| Vladimir Marko | a5b8fde | 2014-05-23 15:16:44 +0100 | [diff] [blame] | 142 |   for (uint32_t idx : bb->data_flow_info->def_v->Indexes()) { | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 143 |     /* Block bb defines register idx */ | 
| buzbee | 862a760 | 2013-04-05 10:58:54 -0700 | [diff] [blame] | 144 |     def_block_matrix_[idx]->SetBit(bb->id); | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 145 |   } | 
 | 146 |   return true; | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 147 | } | 
 | 148 |  | 
| Brian Carlstrom | 2ce745c | 2013-07-17 17:44:30 -0700 | [diff] [blame] | 149 | void MIRGraph::ComputeDefBlockMatrix() { | 
| Razvan A Lupusoru | 8d0d03e | 2014-06-06 17:04:52 -0700 | [diff] [blame^] | 150 |   int num_registers = GetNumOfCodeAndTempVRs(); | 
 | 151 |   /* Allocate num_registers bit vector pointers */ | 
| buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 152 |   def_block_matrix_ = static_cast<ArenaBitVector**> | 
| Mathieu Chartier | f6c4b3b | 2013-08-24 16:11:37 -0700 | [diff] [blame] | 153 |       (arena_->Alloc(sizeof(ArenaBitVector *) * num_registers, | 
| Vladimir Marko | 83cc7ae | 2014-02-12 18:02:05 +0000 | [diff] [blame] | 154 |                      kArenaAllocDFInfo)); | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 155 |   int i; | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 156 |  | 
| buzbee | fa57c47 | 2012-11-21 12:06:18 -0800 | [diff] [blame] | 157 |   /* Initialize num_register vectors with num_blocks bits each */ | 
 | 158 |   for (i = 0; i < num_registers; i++) { | 
| buzbee | 862a760 | 2013-04-05 10:58:54 -0700 | [diff] [blame] | 159 |     def_block_matrix_[i] = | 
 | 160 |         new (arena_) ArenaBitVector(arena_, GetNumBlocks(), false, kBitMapBMatrix); | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 161 |   } | 
| Razvan A Lupusoru | 8d0d03e | 2014-06-06 17:04:52 -0700 | [diff] [blame^] | 162 |  | 
| buzbee | 56c7178 | 2013-09-05 17:13:19 -0700 | [diff] [blame] | 163 |   AllNodesIterator iter(this); | 
| buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 164 |   for (BasicBlock* bb = iter.Next(); bb != NULL; bb = iter.Next()) { | 
 | 165 |     FindLocalLiveIn(bb); | 
 | 166 |   } | 
| buzbee | 56c7178 | 2013-09-05 17:13:19 -0700 | [diff] [blame] | 167 |   AllNodesIterator iter2(this); | 
| buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 168 |   for (BasicBlock* bb = iter2.Next(); bb != NULL; bb = iter2.Next()) { | 
 | 169 |     FillDefBlockMatrix(bb); | 
 | 170 |   } | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 171 |  | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 172 |   /* | 
 | 173 |    * Also set the incoming parameters as defs in the entry block. | 
 | 174 |    * Only need to handle the parameters for the outer method. | 
 | 175 |    */ | 
| Razvan A Lupusoru | 8d0d03e | 2014-06-06 17:04:52 -0700 | [diff] [blame^] | 176 |   int num_regs = GetNumOfCodeVRs(); | 
 | 177 |   int in_reg = GetFirstInVR(); | 
| buzbee | fa57c47 | 2012-11-21 12:06:18 -0800 | [diff] [blame] | 178 |   for (; in_reg < num_regs; in_reg++) { | 
| buzbee | 862a760 | 2013-04-05 10:58:54 -0700 | [diff] [blame] | 179 |     def_block_matrix_[in_reg]->SetBit(GetEntryBlock()->id); | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 180 |   } | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 181 | } | 
 | 182 |  | 
| buzbee | a5abf70 | 2013-04-12 14:39:29 -0700 | [diff] [blame] | 183 | void MIRGraph::ComputeDomPostOrderTraversal(BasicBlock* bb) { | 
| Jean Christophe Beyler | 4896d7b | 2014-05-01 15:36:22 -0700 | [diff] [blame] | 184 |   if (dom_post_order_traversal_ == NULL || max_num_reachable_blocks_ < num_reachable_blocks_) { | 
 | 185 |     // First time or too small - create the array. | 
| buzbee | a5abf70 | 2013-04-12 14:39:29 -0700 | [diff] [blame] | 186 |     dom_post_order_traversal_ = | 
| buzbee | 0d82948 | 2013-10-11 15:24:55 -0700 | [diff] [blame] | 187 |         new (arena_) GrowableArray<BasicBlockId>(arena_, num_reachable_blocks_, | 
| buzbee | a5abf70 | 2013-04-12 14:39:29 -0700 | [diff] [blame] | 188 |                                         kGrowableArrayDomPostOrderTraversal); | 
 | 189 |   } else { | 
 | 190 |     dom_post_order_traversal_->Reset(); | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 191 |   } | 
| buzbee | a5abf70 | 2013-04-12 14:39:29 -0700 | [diff] [blame] | 192 |   ClearAllVisitedFlags(); | 
| Vladimir Marko | c9360ce | 2014-06-05 20:09:47 +0100 | [diff] [blame] | 193 |   DCHECK(temp_scoped_alloc_.get() != nullptr); | 
 | 194 |   ScopedArenaVector<std::pair<BasicBlock*, ArenaBitVector::IndexIterator>> work_stack( | 
 | 195 |       temp_scoped_alloc_->Adapter()); | 
| buzbee | a5abf70 | 2013-04-12 14:39:29 -0700 | [diff] [blame] | 196 |   bb->visited = true; | 
| Vladimir Marko | a5b8fde | 2014-05-23 15:16:44 +0100 | [diff] [blame] | 197 |   work_stack.push_back(std::make_pair(bb, bb->i_dominated->Indexes().begin())); | 
| buzbee | a5abf70 | 2013-04-12 14:39:29 -0700 | [diff] [blame] | 198 |   while (!work_stack.empty()) { | 
| Vladimir Marko | a5b8fde | 2014-05-23 15:16:44 +0100 | [diff] [blame] | 199 |     std::pair<BasicBlock*, ArenaBitVector::IndexIterator>* curr = &work_stack.back(); | 
 | 200 |     BasicBlock* curr_bb = curr->first; | 
 | 201 |     ArenaBitVector::IndexIterator* curr_idom_iter = &curr->second; | 
 | 202 |     while (!curr_idom_iter->Done() && (NeedsVisit(GetBasicBlock(**curr_idom_iter)) == nullptr)) { | 
 | 203 |       ++*curr_idom_iter; | 
| buzbee | a5abf70 | 2013-04-12 14:39:29 -0700 | [diff] [blame] | 204 |     } | 
| Vladimir Marko | a5b8fde | 2014-05-23 15:16:44 +0100 | [diff] [blame] | 205 |     // NOTE: work_stack.push_back()/pop_back() invalidate curr and curr_idom_iter. | 
 | 206 |     if (!curr_idom_iter->Done()) { | 
 | 207 |       BasicBlock* new_bb = GetBasicBlock(**curr_idom_iter); | 
 | 208 |       ++*curr_idom_iter; | 
| buzbee | a5abf70 | 2013-04-12 14:39:29 -0700 | [diff] [blame] | 209 |       new_bb->visited = true; | 
| Vladimir Marko | a5b8fde | 2014-05-23 15:16:44 +0100 | [diff] [blame] | 210 |       work_stack.push_back(std::make_pair(new_bb, new_bb->i_dominated->Indexes().begin())); | 
| buzbee | a5abf70 | 2013-04-12 14:39:29 -0700 | [diff] [blame] | 211 |     } else { | 
 | 212 |       // no successor/next | 
| buzbee | 0d82948 | 2013-10-11 15:24:55 -0700 | [diff] [blame] | 213 |       if (curr_bb->id != NullBasicBlockId) { | 
 | 214 |         dom_post_order_traversal_->Insert(curr_bb->id); | 
 | 215 |       } | 
| buzbee | a5abf70 | 2013-04-12 14:39:29 -0700 | [diff] [blame] | 216 |       work_stack.pop_back(); | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 217 |  | 
| buzbee | a5abf70 | 2013-04-12 14:39:29 -0700 | [diff] [blame] | 218 |       /* hacky loop detection */ | 
| buzbee | 0d82948 | 2013-10-11 15:24:55 -0700 | [diff] [blame] | 219 |       if ((curr_bb->taken != NullBasicBlockId) && curr_bb->dominators->IsBitSet(curr_bb->taken)) { | 
| Bill Buzbee | 0b1191c | 2013-10-28 22:11:59 +0000 | [diff] [blame] | 220 |         curr_bb->nesting_depth++; | 
| buzbee | a5abf70 | 2013-04-12 14:39:29 -0700 | [diff] [blame] | 221 |         attributes_ |= METHOD_HAS_LOOP; | 
 | 222 |       } | 
 | 223 |     } | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 224 |   } | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 225 | } | 
 | 226 |  | 
| buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 227 | void MIRGraph::CheckForDominanceFrontier(BasicBlock* dom_bb, | 
| Brian Carlstrom | 2ce745c | 2013-07-17 17:44:30 -0700 | [diff] [blame] | 228 |                                          const BasicBlock* succ_bb) { | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 229 |   /* | 
 | 230 |    * TODO - evaluate whether phi will ever need to be inserted into exit | 
 | 231 |    * blocks. | 
 | 232 |    */ | 
| buzbee | 0d82948 | 2013-10-11 15:24:55 -0700 | [diff] [blame] | 233 |   if (succ_bb->i_dom != dom_bb->id && | 
| buzbee | fa57c47 | 2012-11-21 12:06:18 -0800 | [diff] [blame] | 234 |     succ_bb->block_type == kDalvikByteCode && | 
 | 235 |     succ_bb->hidden == false) { | 
| buzbee | 862a760 | 2013-04-05 10:58:54 -0700 | [diff] [blame] | 236 |     dom_bb->dom_frontier->SetBit(succ_bb->id); | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 237 |   } | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 238 | } | 
 | 239 |  | 
 | 240 | /* Worker function to compute the dominance frontier */ | 
| Brian Carlstrom | 2ce745c | 2013-07-17 17:44:30 -0700 | [diff] [blame] | 241 | bool MIRGraph::ComputeDominanceFrontier(BasicBlock* bb) { | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 242 |   /* Calculate DF_local */ | 
| buzbee | 0d82948 | 2013-10-11 15:24:55 -0700 | [diff] [blame] | 243 |   if (bb->taken != NullBasicBlockId) { | 
 | 244 |     CheckForDominanceFrontier(bb, GetBasicBlock(bb->taken)); | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 245 |   } | 
| buzbee | 0d82948 | 2013-10-11 15:24:55 -0700 | [diff] [blame] | 246 |   if (bb->fall_through != NullBasicBlockId) { | 
 | 247 |     CheckForDominanceFrontier(bb, GetBasicBlock(bb->fall_through)); | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 248 |   } | 
| buzbee | 0d82948 | 2013-10-11 15:24:55 -0700 | [diff] [blame] | 249 |   if (bb->successor_block_list_type != kNotUsed) { | 
 | 250 |     GrowableArray<SuccessorBlockInfo*>::Iterator iterator(bb->successor_blocks); | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 251 |       while (true) { | 
| buzbee | 862a760 | 2013-04-05 10:58:54 -0700 | [diff] [blame] | 252 |         SuccessorBlockInfo *successor_block_info = iterator.Next(); | 
| Brian Carlstrom | 0cd7ec2 | 2013-07-17 23:40:20 -0700 | [diff] [blame] | 253 |         if (successor_block_info == NULL) { | 
 | 254 |           break; | 
 | 255 |         } | 
| buzbee | 0d82948 | 2013-10-11 15:24:55 -0700 | [diff] [blame] | 256 |         BasicBlock* succ_bb = GetBasicBlock(successor_block_info->block); | 
| buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 257 |         CheckForDominanceFrontier(bb, succ_bb); | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 258 |       } | 
 | 259 |   } | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 260 |  | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 261 |   /* Calculate DF_up */ | 
| Vladimir Marko | a5b8fde | 2014-05-23 15:16:44 +0100 | [diff] [blame] | 262 |   for (uint32_t dominated_idx : bb->i_dominated->Indexes()) { | 
| Jean Christophe Beyler | 2469e60 | 2014-05-06 20:36:55 -0700 | [diff] [blame] | 263 |     BasicBlock* dominated_bb = GetBasicBlock(dominated_idx); | 
| Vladimir Marko | a5b8fde | 2014-05-23 15:16:44 +0100 | [diff] [blame] | 264 |     for (uint32_t df_up_block_idx : dominated_bb->dom_frontier->Indexes()) { | 
| Jean Christophe Beyler | 2469e60 | 2014-05-06 20:36:55 -0700 | [diff] [blame] | 265 |       BasicBlock* df_up_block = GetBasicBlock(df_up_block_idx); | 
| buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 266 |       CheckForDominanceFrontier(bb, df_up_block); | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 267 |     } | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 268 |   } | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 269 |  | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 270 |   return true; | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 271 | } | 
 | 272 |  | 
 | 273 | /* Worker function for initializing domination-related data structures */ | 
| Brian Carlstrom | 2ce745c | 2013-07-17 17:44:30 -0700 | [diff] [blame] | 274 | void MIRGraph::InitializeDominationInfo(BasicBlock* bb) { | 
| buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 275 |   int num_total_blocks = GetBasicBlockListCount(); | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 276 |  | 
| Brian Carlstrom | df62950 | 2013-07-17 22:39:56 -0700 | [diff] [blame] | 277 |   if (bb->dominators == NULL) { | 
| buzbee | 862a760 | 2013-04-05 10:58:54 -0700 | [diff] [blame] | 278 |     bb->dominators = new (arena_) ArenaBitVector(arena_, num_total_blocks, | 
 | 279 |                                                  false /* expandable */, kBitMapDominators); | 
 | 280 |     bb->i_dominated = new (arena_) ArenaBitVector(arena_, num_total_blocks, | 
 | 281 |                                                   false /* expandable */, kBitMapIDominated); | 
 | 282 |     bb->dom_frontier = new (arena_) ArenaBitVector(arena_, num_total_blocks, | 
 | 283 |                                                    false /* expandable */, kBitMapDomFrontier); | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 284 |   } else { | 
| buzbee | 862a760 | 2013-04-05 10:58:54 -0700 | [diff] [blame] | 285 |     bb->dominators->ClearAllBits(); | 
 | 286 |     bb->i_dominated->ClearAllBits(); | 
 | 287 |     bb->dom_frontier->ClearAllBits(); | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 288 |   } | 
 | 289 |   /* Set all bits in the dominator vector */ | 
| buzbee | 862a760 | 2013-04-05 10:58:54 -0700 | [diff] [blame] | 290 |   bb->dominators->SetInitialBits(num_total_blocks); | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 291 |  | 
| buzbee | 862a760 | 2013-04-05 10:58:54 -0700 | [diff] [blame] | 292 |   return; | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 293 | } | 
 | 294 |  | 
| buzbee | 5b53710 | 2012-01-17 17:33:47 -0800 | [diff] [blame] | 295 | /* | 
| buzbee | fa57c47 | 2012-11-21 12:06:18 -0800 | [diff] [blame] | 296 |  * Walk through the ordered i_dom list until we reach common parent. | 
 | 297 |  * Given the ordering of i_dom_list, this common parent represents the | 
| buzbee | 5b53710 | 2012-01-17 17:33:47 -0800 | [diff] [blame] | 298 |  * last element of the intersection of block1 and block2 dominators. | 
 | 299 |   */ | 
| Brian Carlstrom | 2ce745c | 2013-07-17 17:44:30 -0700 | [diff] [blame] | 300 | int MIRGraph::FindCommonParent(int block1, int block2) { | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 301 |   while (block1 != block2) { | 
 | 302 |     while (block1 < block2) { | 
| buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 303 |       block1 = i_dom_list_[block1]; | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 304 |       DCHECK_NE(block1, NOTVISITED); | 
| buzbee | 5b53710 | 2012-01-17 17:33:47 -0800 | [diff] [blame] | 305 |     } | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 306 |     while (block2 < block1) { | 
| buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 307 |       block2 = i_dom_list_[block2]; | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 308 |       DCHECK_NE(block2, NOTVISITED); | 
 | 309 |     } | 
 | 310 |   } | 
 | 311 |   return block1; | 
| buzbee | 5b53710 | 2012-01-17 17:33:47 -0800 | [diff] [blame] | 312 | } | 
 | 313 |  | 
 | 314 | /* Worker function to compute each block's immediate dominator */ | 
| Brian Carlstrom | 2ce745c | 2013-07-17 17:44:30 -0700 | [diff] [blame] | 315 | bool MIRGraph::ComputeblockIDom(BasicBlock* bb) { | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 316 |   /* Special-case entry block */ | 
| buzbee | 0d82948 | 2013-10-11 15:24:55 -0700 | [diff] [blame] | 317 |   if ((bb->id == NullBasicBlockId) || (bb == GetEntryBlock())) { | 
| buzbee | 5b53710 | 2012-01-17 17:33:47 -0800 | [diff] [blame] | 318 |     return false; | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 319 |   } | 
 | 320 |  | 
 | 321 |   /* Iterate through the predecessors */ | 
| buzbee | 0d82948 | 2013-10-11 15:24:55 -0700 | [diff] [blame] | 322 |   GrowableArray<BasicBlockId>::Iterator iter(bb->predecessors); | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 323 |  | 
 | 324 |   /* Find the first processed predecessor */ | 
| buzbee | 862a760 | 2013-04-05 10:58:54 -0700 | [diff] [blame] | 325 |   int idom = -1; | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 326 |   while (true) { | 
| buzbee | 0d82948 | 2013-10-11 15:24:55 -0700 | [diff] [blame] | 327 |     BasicBlock* pred_bb = GetBasicBlock(iter.Next()); | 
| buzbee | fa57c47 | 2012-11-21 12:06:18 -0800 | [diff] [blame] | 328 |     CHECK(pred_bb != NULL); | 
| buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 329 |     if (i_dom_list_[pred_bb->dfs_id] != NOTVISITED) { | 
| buzbee | fa57c47 | 2012-11-21 12:06:18 -0800 | [diff] [blame] | 330 |       idom = pred_bb->dfs_id; | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 331 |       break; | 
 | 332 |     } | 
 | 333 |   } | 
 | 334 |  | 
 | 335 |   /* Scan the rest of the predecessors */ | 
 | 336 |   while (true) { | 
| buzbee | 0d82948 | 2013-10-11 15:24:55 -0700 | [diff] [blame] | 337 |       BasicBlock* pred_bb = GetBasicBlock(iter.Next()); | 
| Brian Carlstrom | 0cd7ec2 | 2013-07-17 23:40:20 -0700 | [diff] [blame] | 338 |       if (!pred_bb) { | 
 | 339 |         break; | 
 | 340 |       } | 
| buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 341 |       if (i_dom_list_[pred_bb->dfs_id] == NOTVISITED) { | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 342 |         continue; | 
 | 343 |       } else { | 
| buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 344 |         idom = FindCommonParent(pred_bb->dfs_id, idom); | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 345 |       } | 
 | 346 |   } | 
 | 347 |  | 
 | 348 |   DCHECK_NE(idom, NOTVISITED); | 
 | 349 |  | 
 | 350 |   /* Did something change? */ | 
| buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 351 |   if (i_dom_list_[bb->dfs_id] != idom) { | 
 | 352 |     i_dom_list_[bb->dfs_id] = idom; | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 353 |     return true; | 
 | 354 |   } | 
 | 355 |   return false; | 
| buzbee | 5b53710 | 2012-01-17 17:33:47 -0800 | [diff] [blame] | 356 | } | 
 | 357 |  | 
 | 358 | /* Worker function to compute each block's domintors */ | 
| Brian Carlstrom | 2ce745c | 2013-07-17 17:44:30 -0700 | [diff] [blame] | 359 | bool MIRGraph::ComputeBlockDominators(BasicBlock* bb) { | 
| buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 360 |   if (bb == GetEntryBlock()) { | 
| buzbee | 862a760 | 2013-04-05 10:58:54 -0700 | [diff] [blame] | 361 |     bb->dominators->ClearAllBits(); | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 362 |   } else { | 
| buzbee | 0d82948 | 2013-10-11 15:24:55 -0700 | [diff] [blame] | 363 |     bb->dominators->Copy(GetBasicBlock(bb->i_dom)->dominators); | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 364 |   } | 
| buzbee | 862a760 | 2013-04-05 10:58:54 -0700 | [diff] [blame] | 365 |   bb->dominators->SetBit(bb->id); | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 366 |   return false; | 
| buzbee | 5b53710 | 2012-01-17 17:33:47 -0800 | [diff] [blame] | 367 | } | 
 | 368 |  | 
| Brian Carlstrom | 2ce745c | 2013-07-17 17:44:30 -0700 | [diff] [blame] | 369 | bool MIRGraph::SetDominators(BasicBlock* bb) { | 
| buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 370 |   if (bb != GetEntryBlock()) { | 
 | 371 |     int idom_dfs_idx = i_dom_list_[bb->dfs_id]; | 
| buzbee | fa57c47 | 2012-11-21 12:06:18 -0800 | [diff] [blame] | 372 |     DCHECK_NE(idom_dfs_idx, NOTVISITED); | 
| buzbee | 862a760 | 2013-04-05 10:58:54 -0700 | [diff] [blame] | 373 |     int i_dom_idx = dfs_post_order_->Get(idom_dfs_idx); | 
| buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 374 |     BasicBlock* i_dom = GetBasicBlock(i_dom_idx); | 
| buzbee | 0d82948 | 2013-10-11 15:24:55 -0700 | [diff] [blame] | 375 |     bb->i_dom = i_dom->id; | 
| buzbee | fa57c47 | 2012-11-21 12:06:18 -0800 | [diff] [blame] | 376 |     /* Add bb to the i_dominated set of the immediate dominator block */ | 
| buzbee | 862a760 | 2013-04-05 10:58:54 -0700 | [diff] [blame] | 377 |     i_dom->i_dominated->SetBit(bb->id); | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 378 |   } | 
 | 379 |   return false; | 
| buzbee | 5b53710 | 2012-01-17 17:33:47 -0800 | [diff] [blame] | 380 | } | 
 | 381 |  | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 382 | /* Compute dominators, immediate dominator, and dominance fronter */ | 
| Brian Carlstrom | 2ce745c | 2013-07-17 17:44:30 -0700 | [diff] [blame] | 383 | void MIRGraph::ComputeDominators() { | 
| buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 384 |   int num_reachable_blocks = num_reachable_blocks_; | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 385 |  | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 386 |   /* Initialize domination-related data structures */ | 
| buzbee | 56c7178 | 2013-09-05 17:13:19 -0700 | [diff] [blame] | 387 |   PreOrderDfsIterator iter(this); | 
| buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 388 |   for (BasicBlock* bb = iter.Next(); bb != NULL; bb = iter.Next()) { | 
 | 389 |     InitializeDominationInfo(bb); | 
 | 390 |   } | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 391 |  | 
| Jean Christophe Beyler | 4896d7b | 2014-05-01 15:36:22 -0700 | [diff] [blame] | 392 |   /* Initialize & Clear i_dom_list */ | 
 | 393 |   if (max_num_reachable_blocks_ < num_reachable_blocks_) { | 
| Mathieu Chartier | f6c4b3b | 2013-08-24 16:11:37 -0700 | [diff] [blame] | 394 |     i_dom_list_ = static_cast<int*>(arena_->Alloc(sizeof(int) * num_reachable_blocks, | 
| Vladimir Marko | 83cc7ae | 2014-02-12 18:02:05 +0000 | [diff] [blame] | 395 |                                                   kArenaAllocDFInfo)); | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 396 |   } | 
| buzbee | fa57c47 | 2012-11-21 12:06:18 -0800 | [diff] [blame] | 397 |   for (int i = 0; i < num_reachable_blocks; i++) { | 
| buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 398 |     i_dom_list_[i] = NOTVISITED; | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 399 |   } | 
| buzbee | 5b53710 | 2012-01-17 17:33:47 -0800 | [diff] [blame] | 400 |  | 
| buzbee | fa57c47 | 2012-11-21 12:06:18 -0800 | [diff] [blame] | 401 |   /* For post-order, last block is entry block.  Set its i_dom to istelf */ | 
| buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 402 |   DCHECK_EQ(GetEntryBlock()->dfs_id, num_reachable_blocks-1); | 
 | 403 |   i_dom_list_[GetEntryBlock()->dfs_id] = GetEntryBlock()->dfs_id; | 
| buzbee | 5b53710 | 2012-01-17 17:33:47 -0800 | [diff] [blame] | 404 |  | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 405 |   /* Compute the immediate dominators */ | 
| buzbee | 56c7178 | 2013-09-05 17:13:19 -0700 | [diff] [blame] | 406 |   RepeatingReversePostOrderDfsIterator iter2(this); | 
| buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 407 |   bool change = false; | 
 | 408 |   for (BasicBlock* bb = iter2.Next(false); bb != NULL; bb = iter2.Next(change)) { | 
 | 409 |     change = ComputeblockIDom(bb); | 
 | 410 |   } | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 411 |  | 
 | 412 |   /* Set the dominator for the root node */ | 
| buzbee | 862a760 | 2013-04-05 10:58:54 -0700 | [diff] [blame] | 413 |   GetEntryBlock()->dominators->ClearAllBits(); | 
 | 414 |   GetEntryBlock()->dominators->SetBit(GetEntryBlock()->id); | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 415 |  | 
| buzbee | 0d82948 | 2013-10-11 15:24:55 -0700 | [diff] [blame] | 416 |   GetEntryBlock()->i_dom = 0; | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 417 |  | 
| buzbee | 56c7178 | 2013-09-05 17:13:19 -0700 | [diff] [blame] | 418 |   PreOrderDfsIterator iter3(this); | 
| buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 419 |   for (BasicBlock* bb = iter3.Next(); bb != NULL; bb = iter3.Next()) { | 
 | 420 |     SetDominators(bb); | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 421 |   } | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 422 |  | 
| buzbee | 56c7178 | 2013-09-05 17:13:19 -0700 | [diff] [blame] | 423 |   ReversePostOrderDfsIterator iter4(this); | 
| buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 424 |   for (BasicBlock* bb = iter4.Next(); bb != NULL; bb = iter4.Next()) { | 
 | 425 |     ComputeBlockDominators(bb); | 
 | 426 |   } | 
| buzbee | 5b53710 | 2012-01-17 17:33:47 -0800 | [diff] [blame] | 427 |  | 
| buzbee | a5abf70 | 2013-04-12 14:39:29 -0700 | [diff] [blame] | 428 |   // Compute the dominance frontier for each block. | 
| buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 429 |   ComputeDomPostOrderTraversal(GetEntryBlock()); | 
| buzbee | 56c7178 | 2013-09-05 17:13:19 -0700 | [diff] [blame] | 430 |   PostOrderDOMIterator iter5(this); | 
| buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 431 |   for (BasicBlock* bb = iter5.Next(); bb != NULL; bb = iter5.Next()) { | 
 | 432 |     ComputeDominanceFrontier(bb); | 
 | 433 |   } | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 434 | } | 
 | 435 |  | 
 | 436 | /* | 
 | 437 |  * Perform dest U= src1 ^ ~src2 | 
 | 438 |  * This is probably not general enough to be placed in BitVector.[ch]. | 
 | 439 |  */ | 
| buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 440 | void MIRGraph::ComputeSuccLineIn(ArenaBitVector* dest, const ArenaBitVector* src1, | 
| Brian Carlstrom | 2ce745c | 2013-07-17 17:44:30 -0700 | [diff] [blame] | 441 |                                  const ArenaBitVector* src2) { | 
| buzbee | 862a760 | 2013-04-05 10:58:54 -0700 | [diff] [blame] | 442 |   if (dest->GetStorageSize() != src1->GetStorageSize() || | 
 | 443 |       dest->GetStorageSize() != src2->GetStorageSize() || | 
 | 444 |       dest->IsExpandable() != src1->IsExpandable() || | 
 | 445 |       dest->IsExpandable() != src2->IsExpandable()) { | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 446 |     LOG(FATAL) << "Incompatible set properties"; | 
 | 447 |   } | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 448 |  | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 449 |   unsigned int idx; | 
| buzbee | 862a760 | 2013-04-05 10:58:54 -0700 | [diff] [blame] | 450 |   for (idx = 0; idx < dest->GetStorageSize(); idx++) { | 
 | 451 |     dest->GetRawStorage()[idx] |= src1->GetRawStorageWord(idx) & ~(src2->GetRawStorageWord(idx)); | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 452 |   } | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 453 | } | 
 | 454 |  | 
 | 455 | /* | 
 | 456 |  * Iterate through all successor blocks and propagate up the live-in sets. | 
 | 457 |  * The calculated result is used for phi-node pruning - where we only need to | 
 | 458 |  * insert a phi node if the variable is live-in to the block. | 
 | 459 |  */ | 
| Brian Carlstrom | 2ce745c | 2013-07-17 17:44:30 -0700 | [diff] [blame] | 460 | bool MIRGraph::ComputeBlockLiveIns(BasicBlock* bb) { | 
| Razvan A Lupusoru | 8d0d03e | 2014-06-06 17:04:52 -0700 | [diff] [blame^] | 461 |   DCHECK_EQ(temp_bit_vector_size_, cu_->mir_graph.get()->GetNumOfCodeAndTempVRs()); | 
| Vladimir Marko | a5b8fde | 2014-05-23 15:16:44 +0100 | [diff] [blame] | 462 |   ArenaBitVector* temp_dalvik_register_v = temp_bit_vector_; | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 463 |  | 
| Brian Carlstrom | 0cd7ec2 | 2013-07-17 23:40:20 -0700 | [diff] [blame] | 464 |   if (bb->data_flow_info == NULL) { | 
 | 465 |     return false; | 
 | 466 |   } | 
| buzbee | 862a760 | 2013-04-05 10:58:54 -0700 | [diff] [blame] | 467 |   temp_dalvik_register_v->Copy(bb->data_flow_info->live_in_v); | 
| buzbee | 0d82948 | 2013-10-11 15:24:55 -0700 | [diff] [blame] | 468 |   BasicBlock* bb_taken = GetBasicBlock(bb->taken); | 
 | 469 |   BasicBlock* bb_fall_through = GetBasicBlock(bb->fall_through); | 
 | 470 |   if (bb_taken && bb_taken->data_flow_info) | 
 | 471 |     ComputeSuccLineIn(temp_dalvik_register_v, bb_taken->data_flow_info->live_in_v, | 
| buzbee | fa57c47 | 2012-11-21 12:06:18 -0800 | [diff] [blame] | 472 |                       bb->data_flow_info->def_v); | 
| buzbee | 0d82948 | 2013-10-11 15:24:55 -0700 | [diff] [blame] | 473 |   if (bb_fall_through && bb_fall_through->data_flow_info) | 
 | 474 |     ComputeSuccLineIn(temp_dalvik_register_v, bb_fall_through->data_flow_info->live_in_v, | 
| buzbee | fa57c47 | 2012-11-21 12:06:18 -0800 | [diff] [blame] | 475 |                       bb->data_flow_info->def_v); | 
| buzbee | 0d82948 | 2013-10-11 15:24:55 -0700 | [diff] [blame] | 476 |   if (bb->successor_block_list_type != kNotUsed) { | 
 | 477 |     GrowableArray<SuccessorBlockInfo*>::Iterator iterator(bb->successor_blocks); | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 478 |     while (true) { | 
| buzbee | 862a760 | 2013-04-05 10:58:54 -0700 | [diff] [blame] | 479 |       SuccessorBlockInfo *successor_block_info = iterator.Next(); | 
| Brian Carlstrom | 0cd7ec2 | 2013-07-17 23:40:20 -0700 | [diff] [blame] | 480 |       if (successor_block_info == NULL) { | 
 | 481 |         break; | 
 | 482 |       } | 
| buzbee | 0d82948 | 2013-10-11 15:24:55 -0700 | [diff] [blame] | 483 |       BasicBlock* succ_bb = GetBasicBlock(successor_block_info->block); | 
| buzbee | fa57c47 | 2012-11-21 12:06:18 -0800 | [diff] [blame] | 484 |       if (succ_bb->data_flow_info) { | 
| buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 485 |         ComputeSuccLineIn(temp_dalvik_register_v, succ_bb->data_flow_info->live_in_v, | 
| buzbee | fa57c47 | 2012-11-21 12:06:18 -0800 | [diff] [blame] | 486 |                           bb->data_flow_info->def_v); | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 487 |       } | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 488 |     } | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 489 |   } | 
| buzbee | 862a760 | 2013-04-05 10:58:54 -0700 | [diff] [blame] | 490 |   if (!temp_dalvik_register_v->Equal(bb->data_flow_info->live_in_v)) { | 
 | 491 |     bb->data_flow_info->live_in_v->Copy(temp_dalvik_register_v); | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 492 |     return true; | 
 | 493 |   } | 
 | 494 |   return false; | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 495 | } | 
 | 496 |  | 
 | 497 | /* Insert phi nodes to for each variable to the dominance frontiers */ | 
| Brian Carlstrom | 2ce745c | 2013-07-17 17:44:30 -0700 | [diff] [blame] | 498 | void MIRGraph::InsertPhiNodes() { | 
| buzbee | fa57c47 | 2012-11-21 12:06:18 -0800 | [diff] [blame] | 499 |   int dalvik_reg; | 
| Vladimir Marko | a5b8fde | 2014-05-23 15:16:44 +0100 | [diff] [blame] | 500 |   ArenaBitVector* phi_blocks = new (temp_scoped_alloc_.get()) ArenaBitVector( | 
 | 501 |       temp_scoped_alloc_.get(), GetNumBlocks(), false, kBitMapPhi); | 
 | 502 |   ArenaBitVector* input_blocks = new (temp_scoped_alloc_.get()) ArenaBitVector( | 
 | 503 |       temp_scoped_alloc_.get(), GetNumBlocks(), false, kBitMapInputBlocks); | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 504 |  | 
| buzbee | 56c7178 | 2013-09-05 17:13:19 -0700 | [diff] [blame] | 505 |   RepeatingPostOrderDfsIterator iter(this); | 
| buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 506 |   bool change = false; | 
 | 507 |   for (BasicBlock* bb = iter.Next(false); bb != NULL; bb = iter.Next(change)) { | 
 | 508 |     change = ComputeBlockLiveIns(bb); | 
 | 509 |   } | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 510 |  | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 511 |   /* Iterate through each Dalvik register */ | 
| Razvan A Lupusoru | 8d0d03e | 2014-06-06 17:04:52 -0700 | [diff] [blame^] | 512 |   for (dalvik_reg = GetNumOfCodeAndTempVRs() - 1; dalvik_reg >= 0; dalvik_reg--) { | 
| buzbee | 862a760 | 2013-04-05 10:58:54 -0700 | [diff] [blame] | 513 |     input_blocks->Copy(def_block_matrix_[dalvik_reg]); | 
 | 514 |     phi_blocks->ClearAllBits(); | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 515 |     do { | 
| Vladimir Marko | a5b8fde | 2014-05-23 15:16:44 +0100 | [diff] [blame] | 516 |       // TUNING: When we repeat this, we could skip indexes from the previous pass. | 
 | 517 |       for (uint32_t idx : input_blocks->Indexes()) { | 
| Brian Carlstrom | 0cd7ec2 | 2013-07-17 23:40:20 -0700 | [diff] [blame] | 518 |         BasicBlock* def_bb = GetBasicBlock(idx); | 
| Vladimir Marko | a5b8fde | 2014-05-23 15:16:44 +0100 | [diff] [blame] | 519 |         if (def_bb->dom_frontier != nullptr) { | 
 | 520 |           phi_blocks->Union(def_bb->dom_frontier); | 
| Brian Carlstrom | 0cd7ec2 | 2013-07-17 23:40:20 -0700 | [diff] [blame] | 521 |         } | 
 | 522 |       } | 
| Vladimir Marko | a5b8fde | 2014-05-23 15:16:44 +0100 | [diff] [blame] | 523 |     } while (input_blocks->Union(phi_blocks)); | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 524 |  | 
 | 525 |     /* | 
| buzbee | fa57c47 | 2012-11-21 12:06:18 -0800 | [diff] [blame] | 526 |      * Insert a phi node for dalvik_reg in the phi_blocks if the Dalvik | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 527 |      * register is in the live-in set. | 
 | 528 |      */ | 
| Vladimir Marko | a5b8fde | 2014-05-23 15:16:44 +0100 | [diff] [blame] | 529 |     for (uint32_t idx : phi_blocks->Indexes()) { | 
| buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 530 |       BasicBlock* phi_bb = GetBasicBlock(idx); | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 531 |       /* Variable will be clobbered before being used - no need for phi */ | 
| Brian Carlstrom | 0cd7ec2 | 2013-07-17 23:40:20 -0700 | [diff] [blame] | 532 |       if (!phi_bb->data_flow_info->live_in_v->IsBitSet(dalvik_reg)) { | 
 | 533 |         continue; | 
 | 534 |       } | 
| Jean Christophe Beyler | 3aa5773 | 2014-04-17 12:47:24 -0700 | [diff] [blame] | 535 |       MIR *phi = NewMIR(); | 
| buzbee | cbd6d44 | 2012-11-17 14:11:25 -0800 | [diff] [blame] | 536 |       phi->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpPhi); | 
| buzbee | fa57c47 | 2012-11-21 12:06:18 -0800 | [diff] [blame] | 537 |       phi->dalvikInsn.vA = dalvik_reg; | 
 | 538 |       phi->offset = phi_bb->start_offset; | 
| Brian Carlstrom | 7934ac2 | 2013-07-26 10:54:15 -0700 | [diff] [blame] | 539 |       phi->m_unit_index = 0;  // Arbitrarily assign all Phi nodes to outermost method. | 
| Jean Christophe Beyler | cdacac4 | 2014-03-13 14:54:59 -0700 | [diff] [blame] | 540 |       phi_bb->PrependMIR(phi); | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 541 |     } | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 542 |   } | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 543 | } | 
 | 544 |  | 
 | 545 | /* | 
 | 546 |  * Worker function to insert phi-operands with latest SSA names from | 
 | 547 |  * predecessor blocks | 
 | 548 |  */ | 
| Brian Carlstrom | 2ce745c | 2013-07-17 17:44:30 -0700 | [diff] [blame] | 549 | bool MIRGraph::InsertPhiNodeOperands(BasicBlock* bb) { | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 550 |   /* Phi nodes are at the beginning of each block */ | 
| buzbee | 0d82948 | 2013-10-11 15:24:55 -0700 | [diff] [blame] | 551 |   for (MIR* mir = bb->first_mir_insn; mir != NULL; mir = mir->next) { | 
| buzbee | cbd6d44 | 2012-11-17 14:11:25 -0800 | [diff] [blame] | 552 |     if (mir->dalvikInsn.opcode != static_cast<Instruction::Code>(kMirOpPhi)) | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 553 |       return true; | 
| buzbee | fa57c47 | 2012-11-21 12:06:18 -0800 | [diff] [blame] | 554 |     int ssa_reg = mir->ssa_rep->defs[0]; | 
 | 555 |     DCHECK_GE(ssa_reg, 0);   // Shouldn't see compiler temps here | 
| buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 556 |     int v_reg = SRegToVReg(ssa_reg); | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 557 |  | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 558 |     /* Iterate through the predecessors */ | 
| buzbee | 0d82948 | 2013-10-11 15:24:55 -0700 | [diff] [blame] | 559 |     GrowableArray<BasicBlockId>::Iterator iter(bb->predecessors); | 
 | 560 |     size_t num_uses = bb->predecessors->Size(); | 
| Jean Christophe Beyler | 4896d7b | 2014-05-01 15:36:22 -0700 | [diff] [blame] | 561 |     AllocateSSAUseData(mir, num_uses); | 
 | 562 |     int* uses = mir->ssa_rep->uses; | 
| buzbee | 0d82948 | 2013-10-11 15:24:55 -0700 | [diff] [blame] | 563 |     BasicBlockId* incoming = | 
 | 564 |         static_cast<BasicBlockId*>(arena_->Alloc(sizeof(BasicBlockId) * num_uses, | 
| Vladimir Marko | 83cc7ae | 2014-02-12 18:02:05 +0000 | [diff] [blame] | 565 |                                                  kArenaAllocDFInfo)); | 
| buzbee | 0d82948 | 2013-10-11 15:24:55 -0700 | [diff] [blame] | 566 |     mir->meta.phi_incoming = incoming; | 
 | 567 |     int idx = 0; | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 568 |     while (true) { | 
| buzbee | 0d82948 | 2013-10-11 15:24:55 -0700 | [diff] [blame] | 569 |       BasicBlock* pred_bb = GetBasicBlock(iter.Next()); | 
| Brian Carlstrom | 0cd7ec2 | 2013-07-17 23:40:20 -0700 | [diff] [blame] | 570 |       if (!pred_bb) { | 
| Jean Christophe Beyler | 4896d7b | 2014-05-01 15:36:22 -0700 | [diff] [blame] | 571 |        break; | 
| Brian Carlstrom | 0cd7ec2 | 2013-07-17 23:40:20 -0700 | [diff] [blame] | 572 |       } | 
| Jean Christophe Beyler | 4896d7b | 2014-05-01 15:36:22 -0700 | [diff] [blame] | 573 |       int ssa_reg = pred_bb->data_flow_info->vreg_to_ssa_map_exit[v_reg]; | 
| buzbee | 0d82948 | 2013-10-11 15:24:55 -0700 | [diff] [blame] | 574 |       uses[idx] = ssa_reg; | 
 | 575 |       incoming[idx] = pred_bb->id; | 
 | 576 |       idx++; | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 577 |     } | 
 | 578 |   } | 
 | 579 |  | 
 | 580 |   return true; | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 581 | } | 
 | 582 |  | 
| Brian Carlstrom | 2ce745c | 2013-07-17 17:44:30 -0700 | [diff] [blame] | 583 | void MIRGraph::DoDFSPreOrderSSARename(BasicBlock* block) { | 
| Brian Carlstrom | 0cd7ec2 | 2013-07-17 23:40:20 -0700 | [diff] [blame] | 584 |   if (block->visited || block->hidden) { | 
 | 585 |     return; | 
 | 586 |   } | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 587 |   block->visited = true; | 
| buzbee | f0cde54 | 2011-09-13 14:55:02 -0700 | [diff] [blame] | 588 |  | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 589 |   /* Process this block */ | 
| buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 590 |   DoSSAConversion(block); | 
| Razvan A Lupusoru | 8d0d03e | 2014-06-06 17:04:52 -0700 | [diff] [blame^] | 591 |   int map_size = sizeof(int) * GetNumOfCodeAndTempVRs(); | 
| buzbee | f0cde54 | 2011-09-13 14:55:02 -0700 | [diff] [blame] | 592 |  | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 593 |   /* Save SSA map snapshot */ | 
| Vladimir Marko | 5d47447 | 2014-03-21 17:10:58 +0000 | [diff] [blame] | 594 |   ScopedArenaAllocator allocator(&cu_->arena_stack); | 
| buzbee | 862a760 | 2013-04-05 10:58:54 -0700 | [diff] [blame] | 595 |   int* saved_ssa_map = | 
| Vladimir Marko | 5d47447 | 2014-03-21 17:10:58 +0000 | [diff] [blame] | 596 |       static_cast<int*>(allocator.Alloc(map_size, kArenaAllocDalvikToSSAMap)); | 
| buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 597 |   memcpy(saved_ssa_map, vreg_to_ssa_map_, map_size); | 
| buzbee | f0cde54 | 2011-09-13 14:55:02 -0700 | [diff] [blame] | 598 |  | 
| buzbee | 0d82948 | 2013-10-11 15:24:55 -0700 | [diff] [blame] | 599 |   if (block->fall_through != NullBasicBlockId) { | 
 | 600 |     DoDFSPreOrderSSARename(GetBasicBlock(block->fall_through)); | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 601 |     /* Restore SSA map snapshot */ | 
| buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 602 |     memcpy(vreg_to_ssa_map_, saved_ssa_map, map_size); | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 603 |   } | 
| buzbee | 0d82948 | 2013-10-11 15:24:55 -0700 | [diff] [blame] | 604 |   if (block->taken != NullBasicBlockId) { | 
 | 605 |     DoDFSPreOrderSSARename(GetBasicBlock(block->taken)); | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 606 |     /* Restore SSA map snapshot */ | 
| buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 607 |     memcpy(vreg_to_ssa_map_, saved_ssa_map, map_size); | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 608 |   } | 
| buzbee | 0d82948 | 2013-10-11 15:24:55 -0700 | [diff] [blame] | 609 |   if (block->successor_block_list_type != kNotUsed) { | 
 | 610 |     GrowableArray<SuccessorBlockInfo*>::Iterator iterator(block->successor_blocks); | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 611 |     while (true) { | 
| buzbee | 862a760 | 2013-04-05 10:58:54 -0700 | [diff] [blame] | 612 |       SuccessorBlockInfo *successor_block_info = iterator.Next(); | 
| Brian Carlstrom | 0cd7ec2 | 2013-07-17 23:40:20 -0700 | [diff] [blame] | 613 |       if (successor_block_info == NULL) { | 
 | 614 |         break; | 
 | 615 |       } | 
| buzbee | 0d82948 | 2013-10-11 15:24:55 -0700 | [diff] [blame] | 616 |       BasicBlock* succ_bb = GetBasicBlock(successor_block_info->block); | 
| buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 617 |       DoDFSPreOrderSSARename(succ_bb); | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 618 |       /* Restore SSA map snapshot */ | 
| buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 619 |       memcpy(vreg_to_ssa_map_, saved_ssa_map, map_size); | 
| buzbee | f0cde54 | 2011-09-13 14:55:02 -0700 | [diff] [blame] | 620 |     } | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 621 |   } | 
| Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 622 |   return; | 
| buzbee | f0cde54 | 2011-09-13 14:55:02 -0700 | [diff] [blame] | 623 | } | 
 | 624 |  | 
| Elliott Hughes | 11d1b0c | 2012-01-23 16:57:47 -0800 | [diff] [blame] | 625 | }  // namespace art |