forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			111 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			111 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			C++
		
	
	
	
//===- IteratedDominanceFrontier.cpp - Compute IDF ------------------------===//
 | 
						|
//
 | 
						|
//                     The LLVM Compiler Infrastructure
 | 
						|
//
 | 
						|
// This file is distributed under the University of Illinois Open Source
 | 
						|
// License. See LICENSE.TXT for details.
 | 
						|
//
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
//
 | 
						|
// 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);
 | 
						|
 | 
						|
        // Quickly skip all CFG edges that are also dominator tree edges instead
 | 
						|
        // of catching them below.
 | 
						|
        if (SuccNode->getIDom() == Node)
 | 
						|
          return;
 | 
						|
 | 
						|
        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>;
 | 
						|
}
 |