| 277 | } |
| 278 | |
| 279 | void DominatorTree::GetDominatorEdges( |
| 280 | const Function* f, const BasicBlock* placeholder_start_node, |
| 281 | std::vector<std::pair<BasicBlock*, BasicBlock*>>* edges) { |
| 282 | // Each time the depth first traversal calls the postorder callback |
| 283 | // std::function we push that node into the postorder vector to create our |
| 284 | // postorder list. |
| 285 | std::vector<const BasicBlock*> postorder; |
| 286 | auto postorder_function = [&](const BasicBlock* b) { |
| 287 | postorder.push_back(b); |
| 288 | }; |
| 289 | |
| 290 | // CFA::CalculateDominators requires std::vector<BasicBlock*> |
| 291 | // BB are derived from F, so we need to const cast it at some point |
| 292 | // no modification is made on F. |
| 293 | BasicBlockSuccessorHelper<BasicBlock> helper{ |
| 294 | *const_cast<Function*>(f), placeholder_start_node, postdominator_}; |
| 295 | |
| 296 | // The successor function tells DepthFirstTraversal how to move to successive |
| 297 | // nodes by providing an interface to get a list of successor nodes from any |
| 298 | // given node. |
| 299 | auto successor_functor = helper.GetSuccessorFunctor(); |
| 300 | |
| 301 | // The predecessor functor does the same as the successor functor |
| 302 | // but for all nodes preceding a given node. |
| 303 | auto predecessor_functor = helper.GetPredFunctor(); |
| 304 | |
| 305 | // If we're building a post dominator tree we traverse the tree in reverse |
| 306 | // using the predecessor function in place of the successor function and vice |
| 307 | // versa. |
| 308 | DepthFirstSearchPostOrder(placeholder_start_node, successor_functor, |
| 309 | postorder_function); |
| 310 | *edges = CFA<BasicBlock>::CalculateDominators(postorder, predecessor_functor); |
| 311 | } |
| 312 | |
| 313 | void DominatorTree::InitializeTree(const CFG& cfg, const Function* f) { |
| 314 | ClearTree(); |
nothing calls this directly
no test coverage detected