2002-01-30 23:27:55 +00:00
//===- llvm/Analysis/Dominators.h - Dominator Info Calculation ---*- C++ -*--=//
2001-07-02 05:45:17 +00:00
//
// This file defines the following classes:
2002-04-27 06:56:12 +00:00
// 1. DominatorSet: Calculates the [reverse] dominator set for a function
2001-07-03 05:35:23 +00:00
// 2. ImmediateDominators: Calculates and holds a mapping between BasicBlocks
// and their immediate dominator.
// 3. DominatorTree: Represent the ImmediateDominator as an explicit tree
// structure.
// 4. DominanceFrontier: Calculate and hold the dominance frontier for a
2002-04-27 06:56:12 +00:00
// function.
2001-07-03 05:35:23 +00:00
//
// These data structures are listed in increasing order of complexity. It
// takes longer to calculate the dominator frontier, for example, than the
// ImmediateDominator mapping.
2001-07-02 05:45:17 +00:00
//
//===----------------------------------------------------------------------===//
2002-08-21 23:43:50 +00:00
# ifndef LLVM_ANALYSIS_DOMINATORS_H
# define LLVM_ANALYSIS_DOMINATORS_H
2001-07-02 05:45:17 +00:00
2002-01-30 23:27:55 +00:00
# include "llvm/Pass.h"
2001-07-02 05:45:17 +00:00
# include <set>
2002-05-13 22:03:16 +00:00
class Instruction ;
2001-07-02 05:45:17 +00:00
2002-10-17 01:36:08 +00:00
template < typename GraphType > struct GraphTraits ;
2001-07-06 16:57:21 +00:00
//===----------------------------------------------------------------------===//
//
// DominatorBase - Base class that other, more interesting dominator analyses
// inherit from.
//
2002-04-27 06:56:12 +00:00
class DominatorBase : public FunctionPass {
2001-07-06 16:57:21 +00:00
protected :
2002-01-30 23:27:55 +00:00
BasicBlock * Root ;
const bool IsPostDominators ;
inline DominatorBase ( bool isPostDom ) : Root ( 0 ) , IsPostDominators ( isPostDom ) { }
2001-07-06 16:57:21 +00:00
public :
2002-04-28 00:15:57 +00:00
inline BasicBlock * getRoot ( ) const { return Root ; }
2002-01-30 23:27:55 +00:00
// Returns true if analysis based of postdoms
bool isPostDominator ( ) const { return IsPostDominators ; }
2001-07-06 16:57:21 +00:00
} ;
2001-07-02 05:45:17 +00:00
//===----------------------------------------------------------------------===//
//
2002-04-28 00:15:57 +00:00
// DominatorSet - Maintain a set<BasicBlock*> for every basic block in a
2002-04-27 06:56:12 +00:00
// function, that represents the blocks that dominate the block.
2001-07-02 05:45:17 +00:00
//
2002-07-26 18:40:06 +00:00
class DominatorSetBase : public DominatorBase {
2001-07-02 05:45:17 +00:00
public :
2002-04-28 00:15:57 +00:00
typedef std : : set < BasicBlock * > DomSetType ; // Dom set for a bb
2002-01-20 22:54:45 +00:00
// Map of dom sets
2002-04-28 00:15:57 +00:00
typedef std : : map < BasicBlock * , DomSetType > DomSetMapType ;
2002-07-26 18:40:06 +00:00
protected :
2001-07-02 05:45:17 +00:00
DomSetMapType Doms ;
public :
2002-07-26 18:40:06 +00:00
DominatorSetBase ( bool isPostDom ) : DominatorBase ( isPostDom ) { }
2002-01-30 23:27:55 +00:00
2002-07-26 18:40:06 +00:00
virtual void releaseMemory ( ) { Doms . clear ( ) ; }
2001-07-02 05:45:17 +00:00
// Accessor interface:
typedef DomSetMapType : : const_iterator const_iterator ;
2002-01-30 23:27:55 +00:00
typedef DomSetMapType : : iterator iterator ;
2001-07-02 05:45:17 +00:00
inline const_iterator begin ( ) const { return Doms . begin ( ) ; }
2002-01-30 23:27:55 +00:00
inline iterator begin ( ) { return Doms . begin ( ) ; }
2001-07-02 05:45:17 +00:00
inline const_iterator end ( ) const { return Doms . end ( ) ; }
2002-01-30 23:27:55 +00:00
inline iterator end ( ) { return Doms . end ( ) ; }
2002-04-28 00:15:57 +00:00
inline const_iterator find ( BasicBlock * B ) const { return Doms . find ( B ) ; }
inline iterator find ( BasicBlock * B ) { return Doms . find ( B ) ; }
2001-07-02 05:45:17 +00:00
2002-09-06 02:16:27 +00:00
/// getDominators - Return the set of basic blocks that dominate the specified
/// block.
///
2002-04-28 00:15:57 +00:00
inline const DomSetType & getDominators ( BasicBlock * BB ) const {
2001-07-02 05:45:17 +00:00
const_iterator I = find ( BB ) ;
2002-04-27 06:56:12 +00:00
assert ( I ! = end ( ) & & " BB not in function! " ) ;
2001-07-02 05:45:17 +00:00
return I - > second ;
}
2002-09-06 02:16:27 +00:00
/// dominates - Return true if A dominates B.
///
2002-04-28 00:15:57 +00:00
inline bool dominates ( BasicBlock * A , BasicBlock * B ) const {
2001-07-02 05:45:17 +00:00
return getDominators ( B ) . count ( A ) ! = 0 ;
}
2002-01-30 23:27:55 +00:00
2002-09-06 02:16:27 +00:00
/// properlyDominates - Return true if A dominates B and A != B.
///
bool properlyDominates ( BasicBlock * A , BasicBlock * B ) const {
return dominates ( A , B ) & & A ! = B ;
}
/// print - Convert to human readable form
2002-07-27 01:12:15 +00:00
virtual void print ( std : : ostream & OS ) const ;
2002-09-06 02:16:27 +00:00
/// dominates - Return true if A dominates B. This performs the special
/// checks neccesary if A and B are in the same basic block.
///
2002-05-13 22:03:16 +00:00
bool dominates ( Instruction * A , Instruction * B ) const ;
2002-09-06 02:16:27 +00:00
//===--------------------------------------------------------------------===//
// API to update (Post)DominatorSet information based on modifications to
// the CFG...
/// addBasicBlock - Call to update the dominator set with information about a
/// new block that was inserted into the function.
void addBasicBlock ( BasicBlock * BB , const DomSetType & Dominators ) {
assert ( find ( BB ) = = end ( ) & & " Block already in DominatorSet! " ) ;
Doms . insert ( std : : make_pair ( BB , Dominators ) ) ;
}
2002-09-26 05:42:47 +00:00
// addDominator - If a new block is inserted into the CFG, then method may be
// called to notify the blocks it dominates that it is in their set.
//
void addDominator ( BasicBlock * BB , BasicBlock * NewDominator ) {
iterator I = find ( BB ) ;
assert ( I ! = end ( ) & & " BB is not in DominatorSet! " ) ;
I - > second . insert ( NewDominator ) ;
}
2002-07-26 18:40:06 +00:00
} ;
2002-05-13 22:03:16 +00:00
2002-07-26 18:40:06 +00:00
//===-------------------------------------
// DominatorSet Class - Concrete subclass of DominatorSetBase that is used to
// compute a normal dominator set.
//
struct DominatorSet : public DominatorSetBase {
2002-07-26 19:19:31 +00:00
DominatorSet ( ) : DominatorSetBase ( false ) { }
2002-07-26 18:40:06 +00:00
virtual bool runOnFunction ( Function & F ) ;
2002-10-08 19:12:08 +00:00
/// recalculate - This method may be called by external passes that modify the
/// CFG and then need dominator information recalculated. This method is
/// obviously really slow, so it should be avoided if at all possible.
void recalculate ( ) ;
2002-07-26 18:40:06 +00:00
// getAnalysisUsage - This simply provides a dominator set
virtual void getAnalysisUsage ( AnalysisUsage & AU ) const {
AU . setPreservesAll ( ) ;
}
2002-08-22 20:39:27 +00:00
private :
void calculateDominatorsFromBlock ( BasicBlock * BB ) ;
2002-07-26 18:40:06 +00:00
} ;
2001-07-02 05:45:17 +00:00
//===----------------------------------------------------------------------===//
//
// ImmediateDominators - Calculate the immediate dominator for each node in a
2002-04-27 06:56:12 +00:00
// function.
2001-07-02 05:45:17 +00:00
//
2002-07-26 18:40:06 +00:00
class ImmediateDominatorsBase : public DominatorBase {
protected :
2002-04-28 00:15:57 +00:00
std : : map < BasicBlock * , BasicBlock * > IDoms ;
2002-07-26 18:40:06 +00:00
void calcIDoms ( const DominatorSetBase & DS ) ;
2001-07-02 05:45:17 +00:00
public :
2002-07-26 18:40:06 +00:00
ImmediateDominatorsBase ( bool isPostDom ) : DominatorBase ( isPostDom ) { }
2001-07-02 05:45:17 +00:00
2002-07-26 18:40:06 +00:00
virtual void releaseMemory ( ) { IDoms . clear ( ) ; }
2001-07-02 05:45:17 +00:00
// Accessor interface:
2002-04-28 00:15:57 +00:00
typedef std : : map < BasicBlock * , BasicBlock * > IDomMapType ;
2001-07-02 05:45:17 +00:00
typedef IDomMapType : : const_iterator const_iterator ;
inline const_iterator begin ( ) const { return IDoms . begin ( ) ; }
inline const_iterator end ( ) const { return IDoms . end ( ) ; }
2002-04-28 00:15:57 +00:00
inline const_iterator find ( BasicBlock * B ) const { return IDoms . find ( B ) ; }
2001-07-02 05:45:17 +00:00
// operator[] - Return the idom for the specified basic block. The start
// node returns null, because it does not have an immediate dominator.
//
2002-04-28 00:15:57 +00:00
inline BasicBlock * operator [ ] ( BasicBlock * BB ) const {
2002-09-06 02:16:27 +00:00
return get ( BB ) ;
}
// get() - Synonym for operator[].
inline BasicBlock * get ( BasicBlock * BB ) const {
2002-04-28 00:15:57 +00:00
std : : map < BasicBlock * , BasicBlock * > : : const_iterator I = IDoms . find ( BB ) ;
2001-07-02 05:45:17 +00:00
return I ! = IDoms . end ( ) ? I - > second : 0 ;
}
2002-07-27 01:12:15 +00:00
2002-09-06 02:16:27 +00:00
//===--------------------------------------------------------------------===//
// API to update Immediate(Post)Dominators information based on modifications
// to the CFG...
/// addNewBlock - Add a new block to the CFG, with the specified immediate
/// dominator.
///
void addNewBlock ( BasicBlock * BB , BasicBlock * IDom ) {
assert ( get ( BB ) = = 0 & & " BasicBlock already in idom info! " ) ;
IDoms [ BB ] = IDom ;
}
2002-09-26 16:14:37 +00:00
/// setImmediateDominator - Update the immediate dominator information to
/// change the current immediate dominator for the specified block to another
/// block. This method requires that BB already have an IDom, otherwise just
/// use addNewBlock.
void setImmediateDominator ( BasicBlock * BB , BasicBlock * NewIDom ) {
assert ( IDoms . find ( BB ) ! = IDoms . end ( ) & & " BB doesn't have idom yet! " ) ;
IDoms [ BB ] = NewIDom ;
}
2002-09-06 02:16:27 +00:00
2002-07-27 01:12:15 +00:00
// print - Convert to human readable form
virtual void print ( std : : ostream & OS ) const ;
2002-07-26 18:40:06 +00:00
} ;
//===-------------------------------------
// ImmediateDominators Class - Concrete subclass of ImmediateDominatorsBase that
// is used to compute a normal immediate dominator set.
//
struct ImmediateDominators : public ImmediateDominatorsBase {
2002-07-26 19:19:31 +00:00
ImmediateDominators ( ) : ImmediateDominatorsBase ( false ) { }
2002-07-26 18:40:06 +00:00
virtual bool runOnFunction ( Function & F ) {
IDoms . clear ( ) ; // Reset from the last time we were run...
DominatorSet & DS = getAnalysis < DominatorSet > ( ) ;
Root = DS . getRoot ( ) ;
calcIDoms ( DS ) ;
return false ;
}
2002-01-30 23:27:55 +00:00
2002-04-27 06:56:12 +00:00
virtual void getAnalysisUsage ( AnalysisUsage & AU ) const {
AU . setPreservesAll ( ) ;
2002-08-08 19:01:30 +00:00
AU . addRequired < DominatorSet > ( ) ;
2002-01-30 23:27:55 +00:00
}
2001-07-02 05:45:17 +00:00
} ;
//===----------------------------------------------------------------------===//
//
2002-04-27 06:56:12 +00:00
// DominatorTree - Calculate the immediate dominator tree for a function.
2001-07-02 05:45:17 +00:00
//
2002-07-26 18:40:06 +00:00
class DominatorTreeBase : public DominatorBase {
protected :
2001-10-13 06:25:03 +00:00
class Node2 ;
public :
typedef Node2 Node ;
2002-07-26 18:40:06 +00:00
protected :
2002-04-28 00:15:57 +00:00
std : : map < BasicBlock * , Node * > Nodes ;
2002-01-30 23:27:55 +00:00
void reset ( ) ;
2002-04-28 00:15:57 +00:00
typedef std : : map < BasicBlock * , Node * > NodeMapType ;
2001-07-02 05:45:17 +00:00
public :
2002-09-26 16:14:37 +00:00
class Node2 {
2001-07-02 05:45:17 +00:00
friend class DominatorTree ;
2002-07-26 18:40:06 +00:00
friend class PostDominatorTree ;
2002-09-06 02:16:27 +00:00
friend class DominatorTreeBase ;
2002-04-28 00:15:57 +00:00
BasicBlock * TheNode ;
Node2 * IDom ;
2002-09-26 16:14:37 +00:00
std : : vector < Node * > Children ;
2001-07-02 05:45:17 +00:00
public :
2002-09-26 16:14:37 +00:00
typedef std : : vector < Node * > : : iterator iterator ;
typedef std : : vector < Node * > : : const_iterator const_iterator ;
iterator begin ( ) { return Children . begin ( ) ; }
iterator end ( ) { return Children . end ( ) ; }
const_iterator begin ( ) const { return Children . begin ( ) ; }
const_iterator end ( ) const { return Children . end ( ) ; }
2002-04-28 00:15:57 +00:00
inline BasicBlock * getNode ( ) const { return TheNode ; }
2001-10-13 06:25:03 +00:00
inline Node2 * getIDom ( ) const { return IDom ; }
2002-09-26 16:14:37 +00:00
inline const std : : vector < Node * > & getChildren ( ) const { return Children ; }
2001-07-02 05:45:17 +00:00
// dominates - Returns true iff this dominates N. Note that this is not a
// constant time operation!
2001-10-13 06:25:03 +00:00
inline bool dominates ( const Node2 * N ) const {
const Node2 * IDom ;
2001-07-02 05:45:17 +00:00
while ( ( IDom = N - > getIDom ( ) ) ! = 0 & & IDom ! = this )
N = IDom ; // Walk up the tree
return IDom ! = 0 ;
}
private :
2002-04-28 00:15:57 +00:00
inline Node2 ( BasicBlock * node , Node * iDom )
2001-07-02 05:45:17 +00:00
: TheNode ( node ) , IDom ( iDom ) { }
2002-09-26 16:14:37 +00:00
inline Node2 * addChild ( Node * C ) { Children . push_back ( C ) ; return C ; }
void setIDom ( Node2 * NewIDom ) ;
2001-07-02 05:45:17 +00:00
} ;
public :
2002-07-26 18:40:06 +00:00
DominatorTreeBase ( bool isPostDom ) : DominatorBase ( isPostDom ) { }
~ DominatorTreeBase ( ) { reset ( ) ; }
virtual void releaseMemory ( ) { reset ( ) ; }
2002-09-06 02:16:27 +00:00
/// getNode - return the (Post)DominatorTree node for the specified basic
/// block. This is the same as using operator[] on this class.
///
inline Node * getNode ( BasicBlock * BB ) const {
2002-07-26 18:40:06 +00:00
NodeMapType : : const_iterator i = Nodes . find ( BB ) ;
return ( i ! = Nodes . end ( ) ) ? i - > second : 0 ;
}
2002-07-27 01:12:15 +00:00
2002-09-06 02:16:27 +00:00
inline Node * operator [ ] ( BasicBlock * BB ) const {
return getNode ( BB ) ;
}
2002-09-26 16:14:37 +00:00
//===--------------------------------------------------------------------===// // API to update (Post)DominatorTree information based on modifications to
2002-09-06 02:16:27 +00:00
// the CFG...
/// createNewNode - Add a new node to the dominator tree information. This
/// creates a new node as a child of IDomNode, linking it into the children
/// list of the immediate dominator.
///
Node * createNewNode ( BasicBlock * BB , Node * IDomNode ) {
assert ( getNode ( BB ) = = 0 & & " Block already in dominator tree! " ) ;
2002-09-29 21:37:08 +00:00
assert ( IDomNode & & " Not immediate dominator specified for block! " ) ;
return Nodes [ BB ] = IDomNode - > addChild ( new Node ( BB , IDomNode ) ) ;
2002-09-06 02:16:27 +00:00
}
2002-09-26 16:14:37 +00:00
/// changeImmediateDominator - This method is used to update the dominator
/// tree information when a node's immediate dominator changes.
///
void changeImmediateDominator ( Node * Node , Node * NewIDom ) {
assert ( Node & & NewIDom & & " Cannot change null node pointers! " ) ;
Node - > setIDom ( NewIDom ) ;
}
2002-09-06 02:16:27 +00:00
/// print - Convert to human readable form
2002-07-27 01:12:15 +00:00
virtual void print ( std : : ostream & OS ) const ;
2002-07-26 18:40:06 +00:00
} ;
//===-------------------------------------
// DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to
// compute a normal dominator tree.
//
struct DominatorTree : public DominatorTreeBase {
2002-07-26 19:19:31 +00:00
DominatorTree ( ) : DominatorTreeBase ( false ) { }
2002-01-30 23:27:55 +00:00
2002-06-25 16:13:24 +00:00
virtual bool runOnFunction ( Function & F ) {
2002-07-26 18:40:06 +00:00
reset ( ) ; // Reset from the last time we were run...
DominatorSet & DS = getAnalysis < DominatorSet > ( ) ;
Root = DS . getRoot ( ) ;
calculate ( DS ) ;
2002-01-30 23:27:55 +00:00
return false ;
}
2001-07-02 05:45:17 +00:00
2002-07-26 18:40:06 +00:00
virtual void getAnalysisUsage ( AnalysisUsage & AU ) const {
AU . setPreservesAll ( ) ;
2002-08-08 19:01:30 +00:00
AU . addRequired < DominatorSet > ( ) ;
2002-07-26 18:40:06 +00:00
}
private :
void calculate ( const DominatorSet & DS ) ;
} ;
2002-10-16 23:26:00 +00:00
//===-------------------------------------
// DominatorTree GraphTraits specialization so the DominatorTree can be
// iterable by generic graph iterators.
template < > struct GraphTraits < DominatorTree * > {
typedef DominatorTree : : Node NodeType ;
typedef NodeType : : iterator ChildIteratorType ;
static NodeType * getEntryNode ( DominatorTree * DT ) {
return DT - > getNode ( DT - > getRoot ( ) ) ;
}
static inline ChildIteratorType child_begin ( NodeType * N ) {
return N - > begin ( ) ;
}
static inline ChildIteratorType child_end ( NodeType * N ) {
return N - > end ( ) ;
}
} ;
2002-07-26 18:40:06 +00:00
2001-07-02 05:45:17 +00:00
//===----------------------------------------------------------------------===//
//
2002-04-27 06:56:12 +00:00
// DominanceFrontier - Calculate the dominance frontiers for a function.
2001-07-02 05:45:17 +00:00
//
2002-07-26 18:40:06 +00:00
class DominanceFrontierBase : public DominatorBase {
2001-10-13 06:25:03 +00:00
public :
2002-04-28 00:15:57 +00:00
typedef std : : set < BasicBlock * > DomSetType ; // Dom set for a bb
typedef std : : map < BasicBlock * , DomSetType > DomSetMapType ; // Dom set map
2002-07-26 18:40:06 +00:00
protected :
2001-07-02 05:45:17 +00:00
DomSetMapType Frontiers ;
public :
2002-07-26 18:40:06 +00:00
DominanceFrontierBase ( bool isPostDom ) : DominatorBase ( isPostDom ) { }
virtual void releaseMemory ( ) { Frontiers . clear ( ) ; }
// Accessor interface:
typedef DomSetMapType : : const_iterator const_iterator ;
2002-10-31 02:39:48 +00:00
const_iterator begin ( ) const { return Frontiers . begin ( ) ; }
const_iterator end ( ) const { return Frontiers . end ( ) ; }
const_iterator find ( BasicBlock * B ) const { return Frontiers . find ( B ) ; }
void addBasicBlock ( BasicBlock * BB , const DomSetType & frontier ) {
assert ( find ( BB ) = = end ( ) & & " Block already in DominanceFrontier! " ) ;
Frontiers . insert ( std : : make_pair ( BB , frontier ) ) ;
}
void addToFrontier ( BasicBlock * BB , BasicBlock * Node ) {
DomSetMapType : : iterator I = Frontiers . find ( BB ) ;
assert ( I ! = end ( ) & & " BB is not in DominanceFrontier! " ) ;
I - > second . insert ( Node ) ;
}
void removeFromFrontier ( BasicBlock * BB , BasicBlock * Node ) {
DomSetMapType : : iterator I = Frontiers . find ( BB ) ;
assert ( I ! = end ( ) & & " BB is not in DominanceFrontier! " ) ;
assert ( I - > second . count ( Node ) & & " Node is not in DominanceFrontier of BB " ) ;
I - > second . erase ( Node ) ;
}
2002-07-27 01:12:15 +00:00
// print - Convert to human readable form
virtual void print ( std : : ostream & OS ) const ;
2002-07-26 18:40:06 +00:00
} ;
2002-01-30 23:27:55 +00:00
2002-07-26 18:40:06 +00:00
//===-------------------------------------
// DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to
// compute a normal dominator tree.
//
struct DominanceFrontier : public DominanceFrontierBase {
2002-07-26 19:19:31 +00:00
DominanceFrontier ( ) : DominanceFrontierBase ( false ) { }
2002-01-30 23:27:55 +00:00
2002-06-25 16:13:24 +00:00
virtual bool runOnFunction ( Function & ) {
2002-01-30 23:27:55 +00:00
Frontiers . clear ( ) ;
2002-07-26 18:40:06 +00:00
DominatorTree & DT = getAnalysis < DominatorTree > ( ) ;
Root = DT . getRoot ( ) ;
calculate ( DT , DT [ Root ] ) ;
2002-01-30 23:27:55 +00:00
return false ;
2001-07-02 05:45:17 +00:00
}
2002-07-26 18:40:06 +00:00
virtual void getAnalysisUsage ( AnalysisUsage & AU ) const {
AU . setPreservesAll ( ) ;
2002-08-08 19:01:30 +00:00
AU . addRequired < DominatorTree > ( ) ;
2002-07-26 18:40:06 +00:00
}
private :
const DomSetType & calculate ( const DominatorTree & DT ,
const DominatorTree : : Node * Node ) ;
} ;
2001-07-02 05:45:17 +00:00
# endif