#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/CFGDiff.h"
#include "llvm/IR/Dominators.h"
namespace llvm {
template <class NodeTy, bool IsPostDom>
class IDFCalculator {
public:
- IDFCalculator(DominatorTreeBase<BasicBlock, IsPostDom> &DT)
- : DT(DT), useLiveIn(false) {}
+ IDFCalculator(DominatorTreeBase<BasicBlock, IsPostDom> &DT)
+ : DT(DT), GD(nullptr), useLiveIn(false) {}
- /// Give the IDF calculator the set of blocks in which the value is
- /// defined. This is equivalent to the set of starting blocks it should be
- /// calculating the IDF for (though later gets pruned based on liveness).
- ///
- /// Note: This set *must* live for the entire lifetime of the IDF calculator.
- void setDefiningBlocks(const SmallPtrSetImpl<BasicBlock *> &Blocks) {
- DefBlocks = &Blocks;
- }
+ IDFCalculator(DominatorTreeBase<BasicBlock, IsPostDom> &DT,
+ GraphDiff<BasicBlock *, IsPostDom> *GD)
+ : DT(DT), GD(GD), useLiveIn(false) {}
+
+ /// Give the IDF calculator the set of blocks in which the value is
+ /// defined. This is equivalent to the set of starting blocks it should be
+ /// calculating the IDF for (though later gets pruned based on liveness).
+ ///
+ /// Note: This set *must* live for the entire lifetime of the IDF calculator.
+ void setDefiningBlocks(const SmallPtrSetImpl<BasicBlock *> &Blocks) {
+ DefBlocks = &Blocks;
+ }
/// Give the IDF calculator the set of blocks in which the value is
/// live on entry to the block. This is used to prune the IDF calculation to
private:
DominatorTreeBase<BasicBlock, IsPostDom> &DT;
+ GraphDiff<BasicBlock *, IsPostDom> *GD;
bool useLiveIn;
const SmallPtrSetImpl<BasicBlock *> *LiveInBlocks;
const SmallPtrSetImpl<BasicBlock *> *DefBlocks;
#include <queue>
namespace llvm {
+
template <class NodeTy, bool IsPostDom>
void IDFCalculator<NodeTy, IsPostDom>::calculate(
SmallVectorImpl<BasicBlock *> &PHIBlocks) {
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.
- for (auto *Succ : children<NodeTy>(BB)) {
+ auto DoWork = [&](BasicBlock *Succ) {
DomTreeNode *SuccNode = DT.getNode(Succ);
// Quickly skip all CFG edges that are also dominator tree edges instead
// of catching them below.
if (SuccNode->getIDom() == Node)
- continue;
+ return;
const unsigned SuccLevel = SuccNode->getLevel();
if (SuccLevel > RootLevel)
- continue;
+ return;
if (!VisitedPQ.insert(SuccNode).second)
- continue;
+ return;
BasicBlock *SuccBB = SuccNode->getBlock();
if (useLiveIn && !LiveInBlocks->count(SuccBB))
- continue;
+ 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) {