//===- llvm/Analysis/DominanceFrontier.h - Dominator Frontiers --*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the DominanceFrontier class, which calculate and holds the
// dominance frontier for a function.
//
// This should be considered deprecated, don't add any more uses of this data
// structure.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_ANALYSIS_DOMINANCEFRONTIER_H
#define LLVM_ANALYSIS_DOMINANCEFRONTIER_H

#include "llvm/Analysis/Dominators.h"
#include <map>
#include <set>

namespace llvm {
  
//===----------------------------------------------------------------------===//
/// DominanceFrontierBase - Common base class for computing forward and inverse
/// dominance frontiers for a function.
///
class DominanceFrontierBase : public FunctionPass {
public:
  typedef std::set<BasicBlock*>             DomSetType;    // Dom set for a bb
  typedef std::map<BasicBlock*, DomSetType> DomSetMapType; // Dom set map
protected:
  DomSetMapType Frontiers;
  std::vector<BasicBlock*> Roots;
  const bool IsPostDominators;

public:
  DominanceFrontierBase(char &ID, bool isPostDom)
    : FunctionPass(ID), IsPostDominators(isPostDom) {}

  /// getRoots - Return the root blocks of the current CFG.  This may include
  /// multiple blocks if we are computing post dominators.  For forward
  /// dominators, this will always be a single block (the entry node).
  ///
  inline const std::vector<BasicBlock*> &getRoots() const { return Roots; }

  /// isPostDominator - Returns true if analysis based of postdoms
  ///
  bool isPostDominator() const { return IsPostDominators; }

  virtual void releaseMemory() { Frontiers.clear(); }

  // Accessor interface:
  typedef DomSetMapType::iterator iterator;
  typedef DomSetMapType::const_iterator const_iterator;
  iterator       begin()       { return Frontiers.begin(); }
  const_iterator begin() const { return Frontiers.begin(); }
  iterator       end()         { return Frontiers.end(); }
  const_iterator end()   const { return Frontiers.end(); }
  iterator       find(BasicBlock *B)       { return Frontiers.find(B); }
  const_iterator find(BasicBlock *B) const { return Frontiers.find(B); }

  iterator addBasicBlock(BasicBlock *BB, const DomSetType &frontier) {
    assert(find(BB) == end() && "Block already in DominanceFrontier!");
    return Frontiers.insert(std::make_pair(BB, frontier)).first;
  }

  /// removeBlock - Remove basic block BB's frontier.
  void removeBlock(BasicBlock *BB) {
    assert(find(BB) != end() && "Block is not in DominanceFrontier!");
    for (iterator I = begin(), E = end(); I != E; ++I)
      I->second.erase(BB);
    Frontiers.erase(BB);
  }

  void addToFrontier(iterator I, BasicBlock *Node) {
    assert(I != end() && "BB is not in DominanceFrontier!");
    I->second.insert(Node);
  }

  void removeFromFrontier(iterator I, BasicBlock *Node) {
    assert(I != end() && "BB is not in DominanceFrontier!");
    assert(I->second.count(Node) && "Node is not in DominanceFrontier of BB");
    I->second.erase(Node);
  }

  /// compareDomSet - Return false if two domsets match. Otherwise
  /// return true;
  bool compareDomSet(DomSetType &DS1, const DomSetType &DS2) const {
    std::set<BasicBlock *> tmpSet;
    for (DomSetType::const_iterator I = DS2.begin(),
           E = DS2.end(); I != E; ++I)
      tmpSet.insert(*I);

    for (DomSetType::const_iterator I = DS1.begin(),
           E = DS1.end(); I != E; ) {
      BasicBlock *Node = *I++;

      if (tmpSet.erase(Node) == 0)
        // Node is in DS1 but not in DS2.
        return true;
    }

    if (!tmpSet.empty())
      // There are nodes that are in DS2 but not in DS1.
      return true;

    // DS1 and DS2 matches.
    return false;
  }

  /// compare - Return true if the other dominance frontier base matches
  /// this dominance frontier base. Otherwise return false.
  bool compare(DominanceFrontierBase &Other) const {
    DomSetMapType tmpFrontiers;
    for (DomSetMapType::const_iterator I = Other.begin(),
           E = Other.end(); I != E; ++I)
      tmpFrontiers.insert(std::make_pair(I->first, I->second));

    for (DomSetMapType::iterator I = tmpFrontiers.begin(),
           E = tmpFrontiers.end(); I != E; ) {
      BasicBlock *Node = I->first;
      const_iterator DFI = find(Node);
      if (DFI == end())
        return true;

      if (compareDomSet(I->second, DFI->second))
        return true;

      ++I;
      tmpFrontiers.erase(Node);
    }

    if (!tmpFrontiers.empty())
      return true;

    return false;
  }

  /// print - Convert to human readable form
  ///
  virtual void print(raw_ostream &OS, const Module* = 0) const;

  /// dump - Dump the dominance frontier to dbgs().
  void dump() const;
};


//===-------------------------------------
/// DominanceFrontier Class - Concrete subclass of DominanceFrontierBase that is
/// used to compute a forward dominator frontiers.
///
class DominanceFrontier : public DominanceFrontierBase {
public:
  static char ID; // Pass ID, replacement for typeid
  DominanceFrontier() :
    DominanceFrontierBase(ID, false) {
      initializeDominanceFrontierPass(*PassRegistry::getPassRegistry());
    }

  BasicBlock *getRoot() const {
    assert(Roots.size() == 1 && "Should always have entry node!");
    return Roots[0];
  }

  virtual bool runOnFunction(Function &) {
    Frontiers.clear();
    DominatorTree &DT = getAnalysis<DominatorTree>();
    Roots = DT.getRoots();
    assert(Roots.size() == 1 && "Only one entry block for forward domfronts!");
    calculate(DT, DT[Roots[0]]);
    return false;
  }

  virtual void getAnalysisUsage(AnalysisUsage &AU) const {
    AU.setPreservesAll();
    AU.addRequired<DominatorTree>();
  }

  const DomSetType &calculate(const DominatorTree &DT,
                              const DomTreeNode *Node);
};

} // End llvm namespace

#endif
