forked from OSchip/llvm-project
105 lines
3.5 KiB
C++
105 lines
3.5 KiB
C++
//===- IteratedDominanceFrontier.cpp - Compute IDF ------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Compute iterated dominance frontiers using a linear time algorithm.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/Analysis/IteratedDominanceFrontier.h"
|
|
#include "llvm/IR/CFG.h"
|
|
#include "llvm/IR/Dominators.h"
|
|
#include <queue>
|
|
|
|
namespace llvm {
|
|
|
|
template <class NodeTy, bool IsPostDom>
|
|
void IDFCalculator<NodeTy, IsPostDom>::calculate(
|
|
SmallVectorImpl<BasicBlock *> &PHIBlocks) {
|
|
// Use a priority queue keyed on dominator tree level so that inserted nodes
|
|
// are handled from the bottom of the dominator tree upwards. We also augment
|
|
// the level with a DFS number to ensure that the blocks are ordered in a
|
|
// deterministic way.
|
|
typedef std::pair<DomTreeNode *, std::pair<unsigned, unsigned>>
|
|
DomTreeNodePair;
|
|
typedef std::priority_queue<DomTreeNodePair, SmallVector<DomTreeNodePair, 32>,
|
|
less_second> IDFPriorityQueue;
|
|
IDFPriorityQueue PQ;
|
|
|
|
DT.updateDFSNumbers();
|
|
|
|
for (BasicBlock *BB : *DefBlocks) {
|
|
if (DomTreeNode *Node = DT.getNode(BB))
|
|
PQ.push({Node, std::make_pair(Node->getLevel(), Node->getDFSNumIn())});
|
|
}
|
|
|
|
SmallVector<DomTreeNode *, 32> Worklist;
|
|
SmallPtrSet<DomTreeNode *, 32> VisitedPQ;
|
|
SmallPtrSet<DomTreeNode *, 32> VisitedWorklist;
|
|
|
|
while (!PQ.empty()) {
|
|
DomTreeNodePair RootPair = PQ.top();
|
|
PQ.pop();
|
|
DomTreeNode *Root = RootPair.first;
|
|
unsigned RootLevel = RootPair.second.first;
|
|
|
|
// Walk all dominator tree children of Root, inspecting their CFG edges with
|
|
// targets elsewhere on the dominator tree. Only targets whose level is at
|
|
// most Root's level are added to the iterated dominance frontier of the
|
|
// definition set.
|
|
|
|
Worklist.clear();
|
|
Worklist.push_back(Root);
|
|
VisitedWorklist.insert(Root);
|
|
|
|
while (!Worklist.empty()) {
|
|
DomTreeNode *Node = Worklist.pop_back_val();
|
|
BasicBlock *BB = Node->getBlock();
|
|
// Succ is the successor in the direction we are calculating IDF, so it is
|
|
// successor for IDF, and predecessor for Reverse IDF.
|
|
auto DoWork = [&](BasicBlock *Succ) {
|
|
DomTreeNode *SuccNode = DT.getNode(Succ);
|
|
|
|
const unsigned SuccLevel = SuccNode->getLevel();
|
|
if (SuccLevel > RootLevel)
|
|
return;
|
|
|
|
if (!VisitedPQ.insert(SuccNode).second)
|
|
return;
|
|
|
|
BasicBlock *SuccBB = SuccNode->getBlock();
|
|
if (useLiveIn && !LiveInBlocks->count(SuccBB))
|
|
return;
|
|
|
|
PHIBlocks.emplace_back(SuccBB);
|
|
if (!DefBlocks->count(SuccBB))
|
|
PQ.push(std::make_pair(
|
|
SuccNode, std::make_pair(SuccLevel, SuccNode->getDFSNumIn())));
|
|
};
|
|
|
|
if (GD) {
|
|
for (auto Pair : children<
|
|
std::pair<const GraphDiff<BasicBlock *, IsPostDom> *, NodeTy>>(
|
|
{GD, BB}))
|
|
DoWork(Pair.second);
|
|
} else {
|
|
for (auto *Succ : children<NodeTy>(BB))
|
|
DoWork(Succ);
|
|
}
|
|
|
|
for (auto DomChild : *Node) {
|
|
if (VisitedWorklist.insert(DomChild).second)
|
|
Worklist.push_back(DomChild);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
template class IDFCalculator<BasicBlock *, false>;
|
|
template class IDFCalculator<Inverse<BasicBlock *>, true>;
|
|
}
|