blob: 307bb29db15b84ca32ecdccdc9f42134b8f09d07 [file] [log] [blame]
Daniel Berlin2372a192015-04-21 19:13:02 +00001//===- IteratedDominanceFrontier.cpp - Compute IDF ------------------------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Daniel Berlin2372a192015-04-21 19:13:02 +00006//
7//===----------------------------------------------------------------------===//
8//
George Burgess IV825a8682016-07-21 20:52:35 +00009// Compute iterated dominance frontiers using a linear time algorithm.
Daniel Berlin2372a192015-04-21 19:13:02 +000010//
11//===----------------------------------------------------------------------===//
12
13#include "llvm/Analysis/IteratedDominanceFrontier.h"
14#include "llvm/IR/CFG.h"
15#include "llvm/IR/Dominators.h"
16#include <queue>
17
Daniel Berlin77fa84e2016-04-19 06:13:28 +000018namespace llvm {
Alina Sbirlea0dfe8302018-08-17 17:39:15 +000019
Jakub Kuderskib292c222017-07-14 18:26:09 +000020template <class NodeTy, bool IsPostDom>
21void IDFCalculator<NodeTy, IsPostDom>::calculate(
Daniel Berlin77fa84e2016-04-19 06:13:28 +000022 SmallVectorImpl<BasicBlock *> &PHIBlocks) {
Daniel Berlin2372a192015-04-21 19:13:02 +000023 // Use a priority queue keyed on dominator tree level so that inserted nodes
Michael Zolotukhin046da972018-05-12 01:44:32 +000024 // are handled from the bottom of the dominator tree upwards. We also augment
25 // the level with a DFS number to ensure that the blocks are ordered in a
26 // deterministic way.
27 typedef std::pair<DomTreeNode *, std::pair<unsigned, unsigned>>
28 DomTreeNodePair;
Daniel Berlin2372a192015-04-21 19:13:02 +000029 typedef std::priority_queue<DomTreeNodePair, SmallVector<DomTreeNodePair, 32>,
30 less_second> IDFPriorityQueue;
31 IDFPriorityQueue PQ;
32
Michael Zolotukhin046da972018-05-12 01:44:32 +000033 DT.updateDFSNumbers();
34
Daniel Berlin2372a192015-04-21 19:13:02 +000035 for (BasicBlock *BB : *DefBlocks) {
36 if (DomTreeNode *Node = DT.getNode(BB))
Michael Zolotukhin046da972018-05-12 01:44:32 +000037 PQ.push({Node, std::make_pair(Node->getLevel(), Node->getDFSNumIn())});
Daniel Berlin2372a192015-04-21 19:13:02 +000038 }
39
40 SmallVector<DomTreeNode *, 32> Worklist;
41 SmallPtrSet<DomTreeNode *, 32> VisitedPQ;
42 SmallPtrSet<DomTreeNode *, 32> VisitedWorklist;
43
44 while (!PQ.empty()) {
45 DomTreeNodePair RootPair = PQ.top();
46 PQ.pop();
47 DomTreeNode *Root = RootPair.first;
Michael Zolotukhin046da972018-05-12 01:44:32 +000048 unsigned RootLevel = RootPair.second.first;
Daniel Berlin2372a192015-04-21 19:13:02 +000049
50 // Walk all dominator tree children of Root, inspecting their CFG edges with
51 // targets elsewhere on the dominator tree. Only targets whose level is at
52 // most Root's level are added to the iterated dominance frontier of the
53 // definition set.
54
55 Worklist.clear();
56 Worklist.push_back(Root);
57 VisitedWorklist.insert(Root);
58
59 while (!Worklist.empty()) {
60 DomTreeNode *Node = Worklist.pop_back_val();
61 BasicBlock *BB = Node->getBlock();
Daniel Berlin77fa84e2016-04-19 06:13:28 +000062 // Succ is the successor in the direction we are calculating IDF, so it is
63 // successor for IDF, and predecessor for Reverse IDF.
Alina Sbirlea0dfe8302018-08-17 17:39:15 +000064 auto DoWork = [&](BasicBlock *Succ) {
Daniel Berlin2372a192015-04-21 19:13:02 +000065 DomTreeNode *SuccNode = DT.getNode(Succ);
66
67 // Quickly skip all CFG edges that are also dominator tree edges instead
68 // of catching them below.
69 if (SuccNode->getIDom() == Node)
Alina Sbirlea0dfe8302018-08-17 17:39:15 +000070 return;
Daniel Berlin2372a192015-04-21 19:13:02 +000071
Jakub Kuderski604a22b2017-07-01 00:23:01 +000072 const unsigned SuccLevel = SuccNode->getLevel();
Daniel Berlin2372a192015-04-21 19:13:02 +000073 if (SuccLevel > RootLevel)
Alina Sbirlea0dfe8302018-08-17 17:39:15 +000074 return;
Daniel Berlin2372a192015-04-21 19:13:02 +000075
76 if (!VisitedPQ.insert(SuccNode).second)
Alina Sbirlea0dfe8302018-08-17 17:39:15 +000077 return;
Daniel Berlin2372a192015-04-21 19:13:02 +000078
79 BasicBlock *SuccBB = SuccNode->getBlock();
80 if (useLiveIn && !LiveInBlocks->count(SuccBB))
Alina Sbirlea0dfe8302018-08-17 17:39:15 +000081 return;
Daniel Berlin2372a192015-04-21 19:13:02 +000082
83 PHIBlocks.emplace_back(SuccBB);
84 if (!DefBlocks->count(SuccBB))
Michael Zolotukhin046da972018-05-12 01:44:32 +000085 PQ.push(std::make_pair(
86 SuccNode, std::make_pair(SuccLevel, SuccNode->getDFSNumIn())));
Alina Sbirlea0dfe8302018-08-17 17:39:15 +000087 };
88
89 if (GD) {
90 for (auto Pair : children<
91 std::pair<const GraphDiff<BasicBlock *, IsPostDom> *, NodeTy>>(
92 {GD, BB}))
93 DoWork(Pair.second);
94 } else {
95 for (auto *Succ : children<NodeTy>(BB))
96 DoWork(Succ);
Daniel Berlin2372a192015-04-21 19:13:02 +000097 }
98
99 for (auto DomChild : *Node) {
100 if (VisitedWorklist.insert(DomChild).second)
101 Worklist.push_back(DomChild);
102 }
103 }
104 }
105}
Daniel Berlin77fa84e2016-04-19 06:13:28 +0000106
Jakub Kuderskib292c222017-07-14 18:26:09 +0000107template class IDFCalculator<BasicBlock *, false>;
108template class IDFCalculator<Inverse<BasicBlock *>, true>;
Daniel Berlin77fa84e2016-04-19 06:13:28 +0000109}