#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/SetOperations.h"
#include <algorithm>
+#include <iostream>
using namespace llvm;
//===----------------------------------------------------------------------===//
//
//===----------------------------------------------------------------------===//
-static RegisterAnalysis<ImmediateDominators>
+static RegisterPass<ImmediateDominators>
C("idom", "Immediate Dominators Construction", true);
unsigned ImmediateDominators::DFSPass(BasicBlock *V, InfoRec &VInfo,
return false;
}
+/// dominates - Return true if A dominates B.
+///
+bool ImmediateDominatorsBase::dominates(BasicBlock *A, BasicBlock *B) const {
+ assert(A && B && "Null pointers?");
+
+ // Walk up the dominator tree from B to determine if A dom B.
+ while (A != B && B)
+ B = get(B);
+ return A == B;
+}
+
void ImmediateDominatorsBase::print(std::ostream &o, const Module* ) const {
Function *F = getRoots()[0]->getParent();
for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
// DominatorSet Implementation
//===----------------------------------------------------------------------===//
-static RegisterAnalysis<DominatorSet>
+static RegisterPass<DominatorSet>
B("domset", "Dominator Set Construction", true);
// dominates - Return true if A dominates B. This performs the special checks
BasicBlock::iterator I = BBA->begin();
for (; &*I != A && &*I != B; ++I) /*empty*/;
- // A dominates B if it is found first in the basic block...
- return &*I == A;
+ if(!IsPostDominators) {
+ // A dominates B if it is found first in the basic block.
+ return &*I == A;
+ } else {
+ // A post-dominates B if B is found first in the basic block.
+ return &*I == B;
+ }
}
return false;
}
-void DominatorSet::stub() {}
-
namespace llvm {
static std::ostream &operator<<(std::ostream &o,
const std::set<BasicBlock*> &BBs) {
// DominatorTree Implementation
//===----------------------------------------------------------------------===//
-static RegisterAnalysis<DominatorTree>
+static RegisterPass<DominatorTree>
E("domtree", "Dominator Tree Construction", true);
// DominatorTreeBase::reset - Free all of the tree node memory.
// DominanceFrontier Implementation
//===----------------------------------------------------------------------===//
-static RegisterAnalysis<DominanceFrontier>
+static RegisterPass<DominanceFrontier>
G("domfrontier", "Dominance Frontier Construction", true);
const DominanceFrontier::DomSetType &
DomSetType::const_iterator CDFI = ChildDF.begin(), CDFE = ChildDF.end();
for (; CDFI != CDFE; ++CDFI) {
- if (!Node->dominates(DT[*CDFI]))
+ if (!Node->properlyDominates(DT[*CDFI]))
S.insert(*CDFI);
}
}
}
}
+//===----------------------------------------------------------------------===//
+// ETOccurrence Implementation
+//===----------------------------------------------------------------------===//
+
+void ETOccurrence::Splay() {
+ ETOccurrence *father;
+ ETOccurrence *grandfather;
+ int occdepth;
+ int fatherdepth;
+
+ while (Parent) {
+ occdepth = Depth;
+
+ father = Parent;
+ fatherdepth = Parent->Depth;
+ grandfather = father->Parent;
+
+ // If we have no grandparent, a single zig or zag will do.
+ if (!grandfather) {
+ setDepthAdd(fatherdepth);
+ MinOccurrence = father->MinOccurrence;
+ Min = father->Min;
+
+ // See what we have to rotate
+ if (father->Left == this) {
+ // Zig
+ father->setLeft(Right);
+ setRight(father);
+ if (father->Left)
+ father->Left->setDepthAdd(occdepth);
+ } else {
+ // Zag
+ father->setRight(Left);
+ setLeft(father);
+ if (father->Right)
+ father->Right->setDepthAdd(occdepth);
+ }
+ father->setDepth(-occdepth);
+ Parent = NULL;
+
+ father->recomputeMin();
+ return;
+ }
+
+ // If we have a grandfather, we need to do some
+ // combination of zig and zag.
+ int grandfatherdepth = grandfather->Depth;
+
+ setDepthAdd(fatherdepth + grandfatherdepth);
+ MinOccurrence = grandfather->MinOccurrence;
+ Min = grandfather->Min;
+
+ ETOccurrence *greatgrandfather = grandfather->Parent;
+
+ if (grandfather->Left == father) {
+ if (father->Left == this) {
+ // Zig zig
+ grandfather->setLeft(father->Right);
+ father->setLeft(Right);
+ setRight(father);
+ father->setRight(grandfather);
+
+ father->setDepth(-occdepth);
+
+ if (father->Left)
+ father->Left->setDepthAdd(occdepth);
+
+ grandfather->setDepth(-fatherdepth);
+ if (grandfather->Left)
+ grandfather->Left->setDepthAdd(fatherdepth);
+ } else {
+ // Zag zig
+ grandfather->setLeft(Right);
+ father->setRight(Left);
+ setLeft(father);
+ setRight(grandfather);
+
+ father->setDepth(-occdepth);
+ if (father->Right)
+ father->Right->setDepthAdd(occdepth);
+ grandfather->setDepth(-occdepth - fatherdepth);
+ if (grandfather->Left)
+ grandfather->Left->setDepthAdd(occdepth + fatherdepth);
+ }
+ } else {
+ if (father->Left == this) {
+ // Zig zag
+ grandfather->setRight(Left);
+ father->setLeft(Right);
+ setLeft(grandfather);
+ setRight(father);
+
+ father->setDepth(-occdepth);
+ if (father->Left)
+ father->Left->setDepthAdd(occdepth);
+ grandfather->setDepth(-occdepth - fatherdepth);
+ if (grandfather->Right)
+ grandfather->Right->setDepthAdd(occdepth + fatherdepth);
+ } else { // Zag Zag
+ grandfather->setRight(father->Left);
+ father->setRight(Left);
+ setLeft(father);
+ father->setLeft(grandfather);
+
+ father->setDepth(-occdepth);
+ if (father->Right)
+ father->Right->setDepthAdd(occdepth);
+ grandfather->setDepth(-fatherdepth);
+ if (grandfather->Right)
+ grandfather->Right->setDepthAdd(fatherdepth);
+ }
+ }
+
+ // Might need one more rotate depending on greatgrandfather.
+ setParent(greatgrandfather);
+ if (greatgrandfather) {
+ if (greatgrandfather->Left == grandfather)
+ greatgrandfather->Left = this;
+ else
+ greatgrandfather->Right = this;
+
+ }
+ grandfather->recomputeMin();
+ father->recomputeMin();
+ }
+}
+
+//===----------------------------------------------------------------------===//
+// ETNode implementation
+//===----------------------------------------------------------------------===//
+
+void ETNode::Split() {
+ ETOccurrence *right, *left;
+ ETOccurrence *rightmost = RightmostOcc;
+ ETOccurrence *parent;
+
+ // Update the occurrence tree first.
+ RightmostOcc->Splay();
+
+ // Find the leftmost occurrence in the rightmost subtree, then splay
+ // around it.
+ for (right = rightmost->Right; right->Left; right = right->Left);
+
+ right->Splay();
+
+ // Start splitting
+ right->Left->Parent = NULL;
+ parent = ParentOcc;
+ parent->Splay();
+ ParentOcc = NULL;
+
+ left = parent->Left;
+ parent->Right->Parent = NULL;
+
+ right->setLeft(left);
+
+ right->recomputeMin();
+
+ rightmost->Splay();
+ rightmost->Depth = 0;
+ rightmost->Min = 0;
+
+ delete parent;
+
+ // Now update *our* tree
+
+ if (Father->Son == this)
+ Father->Son = Right;
+
+ if (Father->Son == this)
+ Father->Son = NULL;
+ else {
+ Left->Right = Right;
+ Right->Left = Left;
+ }
+ Left = Right = NULL;
+ Father = NULL;
+}
+
+void ETNode::setFather(ETNode *NewFather) {
+ ETOccurrence *rightmost;
+ ETOccurrence *leftpart;
+ ETOccurrence *NewFatherOcc;
+ ETOccurrence *temp;
+
+ // First update the path in the splay tree
+ NewFatherOcc = new ETOccurrence(NewFather);
+
+ rightmost = NewFather->RightmostOcc;
+ rightmost->Splay();
+
+ leftpart = rightmost->Left;
+
+ temp = RightmostOcc;
+ temp->Splay();
+
+ NewFatherOcc->setLeft(leftpart);
+ NewFatherOcc->setRight(temp);
+
+ temp->Depth++;
+ temp->Min++;
+ NewFatherOcc->recomputeMin();
+
+ rightmost->setLeft(NewFatherOcc);
+
+ if (NewFatherOcc->Min + rightmost->Depth < rightmost->Min) {
+ rightmost->Min = NewFatherOcc->Min + rightmost->Depth;
+ rightmost->MinOccurrence = NewFatherOcc->MinOccurrence;
+ }
+
+ delete ParentOcc;
+ ParentOcc = NewFatherOcc;
+
+ // Update *our* tree
+ ETNode *left;
+ ETNode *right;
+
+ Father = NewFather;
+ right = Father->Son;
+
+ if (right)
+ left = right->Left;
+ else
+ left = right = this;
+
+ left->Right = this;
+ right->Left = this;
+ Left = left;
+ Right = right;
+
+ Father->Son = this;
+}
+
+bool ETNode::Below(ETNode *other) {
+ ETOccurrence *up = other->RightmostOcc;
+ ETOccurrence *down = RightmostOcc;
+
+ if (this == other)
+ return true;
+
+ up->Splay();
+
+ ETOccurrence *left, *right;
+ left = up->Left;
+ right = up->Right;
+
+ if (!left)
+ return false;
+
+ left->Parent = NULL;
+
+ if (right)
+ right->Parent = NULL;
+
+ down->Splay();
+
+ if (left == down || left->Parent != NULL) {
+ if (right)
+ right->Parent = up;
+ up->setLeft(down);
+ } else {
+ left->Parent = up;
+
+ // If the two occurrences are in different trees, put things
+ // back the way they were.
+ if (right && right->Parent != NULL)
+ up->setRight(down);
+ else
+ up->setRight(right);
+ return false;
+ }
+
+ if (down->Depth <= 0)
+ return false;
+
+ return !down->Right || down->Right->Min + down->Depth >= 0;
+}
+
+ETNode *ETNode::NCA(ETNode *other) {
+ ETOccurrence *occ1 = RightmostOcc;
+ ETOccurrence *occ2 = other->RightmostOcc;
+
+ ETOccurrence *left, *right, *ret;
+ ETOccurrence *occmin;
+ int mindepth;
+
+ if (this == other)
+ return this;
+
+ occ1->Splay();
+ left = occ1->Left;
+ right = occ1->Right;
+
+ if (left)
+ left->Parent = NULL;
+
+ if (right)
+ right->Parent = NULL;
+ occ2->Splay();
+
+ if (left == occ2 || (left && left->Parent != NULL)) {
+ ret = occ2->Right;
+
+ occ1->setLeft(occ2);
+ if (right)
+ right->Parent = occ1;
+ } else {
+ ret = occ2->Left;
+
+ occ1->setRight(occ2);
+ if (left)
+ left->Parent = occ1;
+ }
+
+ if (occ2->Depth > 0) {
+ occmin = occ1;
+ mindepth = occ1->Depth;
+ } else {
+ occmin = occ2;
+ mindepth = occ2->Depth + occ1->Depth;
+ }
+
+ if (ret && ret->Min + occ1->Depth + occ2->Depth < mindepth)
+ return ret->MinOccurrence->OccFor;
+ else
+ return occmin->OccFor;
+}
+
+void ETNode::assignDFSNumber(int num) {
+ std::vector<ETNode *> workStack;
+ std::set<ETNode *> visitedNodes;
+
+ workStack.push_back(this);
+ visitedNodes.insert(this);
+ this->DFSNumIn = num++;
+
+ while (!workStack.empty()) {
+ ETNode *Node = workStack.back();
+
+ // If this is leaf node then set DFSNumOut and pop the stack
+ if (!Node->Son) {
+ Node->DFSNumOut = num++;
+ workStack.pop_back();
+ continue;
+ }
+
+ ETNode *son = Node->Son;
+
+ // Visit Node->Son first
+ if (visitedNodes.count(son) == 0) {
+ son->DFSNumIn = num++;
+ workStack.push_back(son);
+ visitedNodes.insert(son);
+ continue;
+ }
+
+ bool visitChild = false;
+ // Visit remaining children
+ for (ETNode *s = son->Right; s != son && !visitChild; s = s->Right) {
+ if (visitedNodes.count(s) == 0) {
+ visitChild = true;
+ s->DFSNumIn = num++;
+ workStack.push_back(s);
+ visitedNodes.insert(s);
+ }
+ }
+
+ if (!visitChild) {
+ // If we reach here means all children are visited
+ Node->DFSNumOut = num++;
+ workStack.pop_back();
+ }
+ }
+}
+
+//===----------------------------------------------------------------------===//
+// ETForest implementation
+//===----------------------------------------------------------------------===//
+
+static RegisterPass<ETForest>
+D("etforest", "ET Forest Construction", true);
+
+void ETForestBase::reset() {
+ for (ETMapType::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I)
+ delete I->second;
+ Nodes.clear();
+}
+
+void ETForestBase::updateDFSNumbers()
+{
+ int dfsnum = 0;
+ // Iterate over all nodes in depth first order.
+ for (unsigned i = 0, e = Roots.size(); i != e; ++i)
+ for (df_iterator<BasicBlock*> I = df_begin(Roots[i]),
+ E = df_end(Roots[i]); I != E; ++I) {
+ BasicBlock *BB = *I;
+ if (!getNode(BB)->hasFather())
+ getNode(BB)->assignDFSNumber(dfsnum);
+ }
+ SlowQueries = 0;
+ DFSInfoValid = true;
+}
+
+ETNode *ETForest::getNodeForBlock(BasicBlock *BB) {
+ ETNode *&BBNode = Nodes[BB];
+ if (BBNode) return BBNode;
+
+ // Haven't calculated this node yet? Get or calculate the node for the
+ // immediate dominator.
+ BasicBlock *IDom = getAnalysis<ImmediateDominators>()[BB];
+
+ // If we are unreachable, we may not have an immediate dominator.
+ if (!IDom)
+ return BBNode = new ETNode(BB);
+ else {
+ ETNode *IDomNode = getNodeForBlock(IDom);
+
+ // Add a new tree node for this BasicBlock, and link it as a child of
+ // IDomNode
+ BBNode = new ETNode(BB);
+ BBNode->setFather(IDomNode);
+ return BBNode;
+ }
+}
+
+void ETForest::calculate(const ImmediateDominators &ID) {
+ assert(Roots.size() == 1 && "ETForest should have 1 root block!");
+ BasicBlock *Root = Roots[0];
+ Nodes[Root] = new ETNode(Root); // Add a node for the root
+
+ Function *F = Root->getParent();
+ // Loop over all of the reachable blocks in the function...
+ for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I)
+ if (BasicBlock *ImmDom = ID.get(I)) { // Reachable block.
+ ETNode *&BBNode = Nodes[I];
+ if (!BBNode) { // Haven't calculated this node yet?
+ // Get or calculate the node for the immediate dominator
+ ETNode *IDomNode = getNodeForBlock(ImmDom);
+
+ // Add a new ETNode for this BasicBlock, and set it's parent
+ // to it's immediate dominator.
+ BBNode = new ETNode(I);
+ BBNode->setFather(IDomNode);
+ }
+ }
+
+ // Make sure we've got nodes around for every block
+ for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
+ ETNode *&BBNode = Nodes[I];
+ if (!BBNode)
+ BBNode = new ETNode(I);
+ }
+
+ updateDFSNumbers ();
+}
+
+//===----------------------------------------------------------------------===//
+// ETForestBase Implementation
+//===----------------------------------------------------------------------===//
+
+void ETForestBase::addNewBlock(BasicBlock *BB, BasicBlock *IDom) {
+ ETNode *&BBNode = Nodes[BB];
+ assert(!BBNode && "BasicBlock already in ET-Forest");
+
+ BBNode = new ETNode(BB);
+ BBNode->setFather(getNode(IDom));
+ DFSInfoValid = false;
+}
+
+void ETForestBase::setImmediateDominator(BasicBlock *BB, BasicBlock *newIDom) {
+ assert(getNode(BB) && "BasicBlock not in ET-Forest");
+ assert(getNode(newIDom) && "IDom not in ET-Forest");
+
+ ETNode *Node = getNode(BB);
+ if (Node->hasFather()) {
+ if (Node->getFather()->getData<BasicBlock>() == newIDom)
+ return;
+ Node->Split();
+ }
+ Node->setFather(getNode(newIDom));
+ DFSInfoValid= false;
+}
+
+void ETForestBase::print(std::ostream &o, const Module *) const {
+ o << "=============================--------------------------------\n";
+ o << "ET Forest:\n";
+ o << "DFS Info ";
+ if (DFSInfoValid)
+ o << "is";
+ else
+ o << "is not";
+ o << " up to date\n";
+
+ Function *F = getRoots()[0]->getParent();
+ for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
+ o << " DFS Numbers For Basic Block:";
+ WriteAsOperand(o, I, false);
+ o << " are:";
+ if (ETNode *EN = getNode(I)) {
+ o << "In: " << EN->getDFSNumIn();
+ o << " Out: " << EN->getDFSNumOut() << "\n";
+ } else {
+ o << "No associated ETNode";
+ }
+ o << "\n";
+ }
+ o << "\n";
+}
+
+DEFINING_FILE_FOR(DominatorSet)