llvm/lib/Analysis/PostDominators.cpp
Owen Anderson 2ab36d3502 Begin adding static dependence information to passes, which will allow us to
perform initialization without static constructors AND without explicit initialization
by the client.  For the moment, passes are required to initialize both their
(potential) dependencies and any passes they preserve.  I hope to be able to relax
the latter requirement in the future.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@116334 91177308-0d34-0410-b5e6-96231b3b80d8
2010-10-12 19:48:12 +00:00

102 lines
3.3 KiB
C++

//===- PostDominators.cpp - Post-Dominator Calculation --------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the post-dominator construction algorithms.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "postdomtree"
#include "llvm/Analysis/PostDominators.h"
#include "llvm/Instructions.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/Debug.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/SetOperations.h"
#include "llvm/Analysis/DominatorInternals.h"
using namespace llvm;
//===----------------------------------------------------------------------===//
// PostDominatorTree Implementation
//===----------------------------------------------------------------------===//
char PostDominatorTree::ID = 0;
char PostDominanceFrontier::ID = 0;
INITIALIZE_PASS(PostDominatorTree, "postdomtree",
"Post-Dominator Tree Construction", true, true)
bool PostDominatorTree::runOnFunction(Function &F) {
DT->recalculate(F);
return false;
}
PostDominatorTree::~PostDominatorTree() {
delete DT;
}
void PostDominatorTree::print(raw_ostream &OS, const Module *) const {
DT->print(OS);
}
FunctionPass* llvm::createPostDomTree() {
return new PostDominatorTree();
}
//===----------------------------------------------------------------------===//
// PostDominanceFrontier Implementation
//===----------------------------------------------------------------------===//
INITIALIZE_PASS_BEGIN(PostDominanceFrontier, "postdomfrontier",
"Post-Dominance Frontier Construction", true, true)
INITIALIZE_PASS_DEPENDENCY(PostDominatorTree)
INITIALIZE_PASS_END(PostDominanceFrontier, "postdomfrontier",
"Post-Dominance Frontier Construction", true, true)
const DominanceFrontier::DomSetType &
PostDominanceFrontier::calculate(const PostDominatorTree &DT,
const DomTreeNode *Node) {
// Loop over CFG successors to calculate DFlocal[Node]
BasicBlock *BB = Node->getBlock();
DomSetType &S = Frontiers[BB]; // The new set to fill in...
if (getRoots().empty()) return S;
if (BB)
for (pred_iterator SI = pred_begin(BB), SE = pred_end(BB);
SI != SE; ++SI) {
BasicBlock *P = *SI;
// Does Node immediately dominate this predecessor?
DomTreeNode *SINode = DT[P];
if (SINode && SINode->getIDom() != Node)
S.insert(P);
}
// At this point, S is DFlocal. Now we union in DFup's of our children...
// Loop through and visit the nodes that Node immediately dominates (Node's
// children in the IDomTree)
//
for (DomTreeNode::const_iterator
NI = Node->begin(), NE = Node->end(); NI != NE; ++NI) {
DomTreeNode *IDominee = *NI;
const DomSetType &ChildDF = calculate(DT, IDominee);
DomSetType::const_iterator CDFI = ChildDF.begin(), CDFE = ChildDF.end();
for (; CDFI != CDFE; ++CDFI) {
if (!DT.properlyDominates(Node, DT[*CDFI]))
S.insert(*CDFI);
}
}
return S;
}
FunctionPass* llvm::createPostDomFrontier() {
return new PostDominanceFrontier();
}