1c3e0fb406fb6fe83566dc6d8b05362e0a2c1e191Eli Friedman//===- SparsePropagation.h - Sparse Conditional Property Propagation ------===//
2e06a75f4c8ea30b6a99d5aa1dce5feda64da09c6Daniel Dunbar//
393ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin//                     The LLVM Compiler Infrastructure
4e06a75f4c8ea30b6a99d5aa1dce5feda64da09c6Daniel Dunbar//
5c36541e7bfa69cc63e2668a986bc99117559c545Mike Stump// This file is distributed under the University of Illinois Open Source
6e06a75f4c8ea30b6a99d5aa1dce5feda64da09c6Daniel Dunbar// License. See LICENSE.TXT for details.
7e06a75f4c8ea30b6a99d5aa1dce5feda64da09c6Daniel Dunbar//
893ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin//===----------------------------------------------------------------------===//
9e06a75f4c8ea30b6a99d5aa1dce5feda64da09c6Daniel Dunbar//
10c36541e7bfa69cc63e2668a986bc99117559c545Mike Stump// This file implements an abstract sparse conditional propagation algorithm,
11e06a75f4c8ea30b6a99d5aa1dce5feda64da09c6Daniel Dunbar// modeled after SCCP, but with a customizable lattice function.
12e06a75f4c8ea30b6a99d5aa1dce5feda64da09c6Daniel Dunbar//
1393ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin//===----------------------------------------------------------------------===//
14e06a75f4c8ea30b6a99d5aa1dce5feda64da09c6Daniel Dunbar
15c36541e7bfa69cc63e2668a986bc99117559c545Mike Stump#ifndef LLVM_ANALYSIS_SPARSEPROPAGATION_H
16e06a75f4c8ea30b6a99d5aa1dce5feda64da09c6Daniel Dunbar#define LLVM_ANALYSIS_SPARSEPROPAGATION_H
17e06a75f4c8ea30b6a99d5aa1dce5feda64da09c6Daniel Dunbar
1893ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin#include "llvm/ADT/DenseMap.h"
19e06a75f4c8ea30b6a99d5aa1dce5feda64da09c6Daniel Dunbar#include "llvm/ADT/SmallPtrSet.h"
20c36541e7bfa69cc63e2668a986bc99117559c545Mike Stump#include <set>
21e06a75f4c8ea30b6a99d5aa1dce5feda64da09c6Daniel Dunbar#include <vector>
22e06a75f4c8ea30b6a99d5aa1dce5feda64da09c6Daniel Dunbar
2393ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Linnamespace llvm {
24e06a75f4c8ea30b6a99d5aa1dce5feda64da09c6Daniel Dunbar  class Value;
25c36541e7bfa69cc63e2668a986bc99117559c545Mike Stump  class Constant;
26e06a75f4c8ea30b6a99d5aa1dce5feda64da09c6Daniel Dunbar  class Argument;
27e06a75f4c8ea30b6a99d5aa1dce5feda64da09c6Daniel Dunbar  class Instruction;
2893ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin  class PHINode;
29e06a75f4c8ea30b6a99d5aa1dce5feda64da09c6Daniel Dunbar  class TerminatorInst;
30c36541e7bfa69cc63e2668a986bc99117559c545Mike Stump  class BasicBlock;
31e06a75f4c8ea30b6a99d5aa1dce5feda64da09c6Daniel Dunbar  class Function;
32e06a75f4c8ea30b6a99d5aa1dce5feda64da09c6Daniel Dunbar  class SparseSolver;
3393ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin  class raw_ostream;
34c36541e7bfa69cc63e2668a986bc99117559c545Mike Stump
35e06a75f4c8ea30b6a99d5aa1dce5feda64da09c6Daniel Dunbar  template<typename T> class SmallVectorImpl;
3693ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin
37d0ef54cb306ef3090ffd551733c491e1cae2a28dDaniel Dunbar/// AbstractLatticeFunction - This class is implemented by the dataflow instance
38d0ef54cb306ef3090ffd551733c491e1cae2a28dDaniel Dunbar/// to specify what the lattice values are and how they handle merges etc.
39e06a75f4c8ea30b6a99d5aa1dce5feda64da09c6Daniel Dunbar/// This gives the client the power to compute lattice values from instructions,
4093ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin/// constants, etc.  The requirement is that lattice values must all fit into
4193ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin/// a void*.  If a void* is not sufficient, the implementation should use this
42e06a75f4c8ea30b6a99d5aa1dce5feda64da09c6Daniel Dunbar/// pointer to be a pointer into a uniquing set or something.
43e06a75f4c8ea30b6a99d5aa1dce5feda64da09c6Daniel Dunbar///
44e06a75f4c8ea30b6a99d5aa1dce5feda64da09c6Daniel Dunbarclass AbstractLatticeFunction {
45e06a75f4c8ea30b6a99d5aa1dce5feda64da09c6Daniel Dunbarpublic:
46c36541e7bfa69cc63e2668a986bc99117559c545Mike Stump  typedef void *LatticeVal;
47c36541e7bfa69cc63e2668a986bc99117559c545Mike Stumpprivate:
48e06a75f4c8ea30b6a99d5aa1dce5feda64da09c6Daniel Dunbar  LatticeVal UndefVal, OverdefinedVal, UntrackedVal;
49e06a75f4c8ea30b6a99d5aa1dce5feda64da09c6Daniel Dunbarpublic:
50e06a75f4c8ea30b6a99d5aa1dce5feda64da09c6Daniel Dunbar  AbstractLatticeFunction(LatticeVal undefVal, LatticeVal overdefinedVal,
5193ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin                          LatticeVal untrackedVal) {
52cf6bde343ff5653744ca782e04d5a9c54b260042Daniel Dunbar    UndefVal = undefVal;
53eedd292ea0cf2216ff16d3490147323489102e3aDaniel Dunbar    OverdefinedVal = overdefinedVal;
54eedd292ea0cf2216ff16d3490147323489102e3aDaniel Dunbar    UntrackedVal = untrackedVal;
5593ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin  }
56e06a75f4c8ea30b6a99d5aa1dce5feda64da09c6Daniel Dunbar  virtual ~AbstractLatticeFunction();
57e06a75f4c8ea30b6a99d5aa1dce5feda64da09c6Daniel Dunbar
58e06a75f4c8ea30b6a99d5aa1dce5feda64da09c6Daniel Dunbar  LatticeVal getUndefVal()       const { return UndefVal; }
59e06a75f4c8ea30b6a99d5aa1dce5feda64da09c6Daniel Dunbar  LatticeVal getOverdefinedVal() const { return OverdefinedVal; }
60c36541e7bfa69cc63e2668a986bc99117559c545Mike Stump  LatticeVal getUntrackedVal()   const { return UntrackedVal; }
61c36541e7bfa69cc63e2668a986bc99117559c545Mike Stump
62e06a75f4c8ea30b6a99d5aa1dce5feda64da09c6Daniel Dunbar  /// IsUntrackedValue - If the specified Value is something that is obviously
63dfc6b80ee13a9102cd67e0b2398fa999eebcbf8eDaniel Dunbar  /// uninteresting to the analysis (and would always return UntrackedVal),
645bde6f41506535ddaf6e9ff60bd1488db8ded952Daniel Dunbar  /// this function can return true to avoid pointless work.
65d0ef54cb306ef3090ffd551733c491e1cae2a28dDaniel Dunbar  virtual bool IsUntrackedValue(Value *V) {
665bde6f41506535ddaf6e9ff60bd1488db8ded952Daniel Dunbar    return false;
675bde6f41506535ddaf6e9ff60bd1488db8ded952Daniel Dunbar  }
685bde6f41506535ddaf6e9ff60bd1488db8ded952Daniel Dunbar
69c36541e7bfa69cc63e2668a986bc99117559c545Mike Stump  /// ComputeConstant - Given a constant value, compute and return a lattice
705bde6f41506535ddaf6e9ff60bd1488db8ded952Daniel Dunbar  /// value corresponding to the specified constant.
71dfc6b80ee13a9102cd67e0b2398fa999eebcbf8eDaniel Dunbar  virtual LatticeVal ComputeConstant(Constant *C) {
72360431660b2245a109f5c6870729126dbcdea254Daniel Dunbar    return getOverdefinedVal(); // always safe
73d0ef54cb306ef3090ffd551733c491e1cae2a28dDaniel Dunbar  }
745e31474b9c8348e8d0404264ae6a8775e34df6acBill Wendling
75d0ef54cb306ef3090ffd551733c491e1cae2a28dDaniel Dunbar  /// IsSpecialCasedPHI - Given a PHI node, determine whether this PHI node is
76d0ef54cb306ef3090ffd551733c491e1cae2a28dDaniel Dunbar  /// one that the we want to handle through ComputeInstructionState.
77d0ef54cb306ef3090ffd551733c491e1cae2a28dDaniel Dunbar  virtual bool IsSpecialCasedPHI(PHINode *PN) {
78d0ef54cb306ef3090ffd551733c491e1cae2a28dDaniel Dunbar    return false;
79360431660b2245a109f5c6870729126dbcdea254Daniel Dunbar  }
80c36541e7bfa69cc63e2668a986bc99117559c545Mike Stump
81360431660b2245a109f5c6870729126dbcdea254Daniel Dunbar  /// GetConstant - If the specified lattice value is representable as an LLVM
82c36541e7bfa69cc63e2668a986bc99117559c545Mike Stump  /// constant value, return it.  Otherwise return null.  The returned value
83360431660b2245a109f5c6870729126dbcdea254Daniel Dunbar  /// must be in the same LLVM type as Val.
84c36541e7bfa69cc63e2668a986bc99117559c545Mike Stump  virtual Constant *GetConstant(LatticeVal LV, Value *Val, SparseSolver &SS) {
85360431660b2245a109f5c6870729126dbcdea254Daniel Dunbar    return nullptr;
86c36541e7bfa69cc63e2668a986bc99117559c545Mike Stump  }
87dfc6b80ee13a9102cd67e0b2398fa999eebcbf8eDaniel Dunbar
88c36541e7bfa69cc63e2668a986bc99117559c545Mike Stump  /// ComputeArgument - Given a formal argument value, compute and return a
89dfc6b80ee13a9102cd67e0b2398fa999eebcbf8eDaniel Dunbar  /// lattice value corresponding to the specified argument.
90c36541e7bfa69cc63e2668a986bc99117559c545Mike Stump  virtual LatticeVal ComputeArgument(Argument *I) {
91dfc6b80ee13a9102cd67e0b2398fa999eebcbf8eDaniel Dunbar    return getOverdefinedVal(); // always safe
92dfc6b80ee13a9102cd67e0b2398fa999eebcbf8eDaniel Dunbar  }
93dfc6b80ee13a9102cd67e0b2398fa999eebcbf8eDaniel Dunbar
94dfc6b80ee13a9102cd67e0b2398fa999eebcbf8eDaniel Dunbar  /// MergeValues - Compute and return the merge of the two specified lattice
95d0ef54cb306ef3090ffd551733c491e1cae2a28dDaniel Dunbar  /// values.  Merging should only move one direction down the lattice to
965e31474b9c8348e8d0404264ae6a8775e34df6acBill Wendling  /// guarantee convergence (toward overdefined).
975e31474b9c8348e8d0404264ae6a8775e34df6acBill Wendling  virtual LatticeVal MergeValues(LatticeVal X, LatticeVal Y) {
985e31474b9c8348e8d0404264ae6a8775e34df6acBill Wendling    return getOverdefinedVal(); // always safe, never useful.
995e31474b9c8348e8d0404264ae6a8775e34df6acBill Wendling  }
1005e31474b9c8348e8d0404264ae6a8775e34df6acBill Wendling
101c36541e7bfa69cc63e2668a986bc99117559c545Mike Stump  /// ComputeInstructionState - Given an instruction and a vector of its operand
102c36541e7bfa69cc63e2668a986bc99117559c545Mike Stump  /// values, compute the result value of the instruction.
103c36541e7bfa69cc63e2668a986bc99117559c545Mike Stump  virtual LatticeVal ComputeInstructionState(Instruction &I, SparseSolver &SS) {
104c36541e7bfa69cc63e2668a986bc99117559c545Mike Stump    return getOverdefinedVal(); // always safe, never useful.
105c36541e7bfa69cc63e2668a986bc99117559c545Mike Stump  }
106c36541e7bfa69cc63e2668a986bc99117559c545Mike Stump
107dfc6b80ee13a9102cd67e0b2398fa999eebcbf8eDaniel Dunbar  /// PrintValue - Render the specified lattice value to the specified stream.
108dfc6b80ee13a9102cd67e0b2398fa999eebcbf8eDaniel Dunbar  virtual void PrintValue(LatticeVal V, raw_ostream &OS);
109dfc6b80ee13a9102cd67e0b2398fa999eebcbf8eDaniel Dunbar};
110d0ef54cb306ef3090ffd551733c491e1cae2a28dDaniel Dunbar
111d0ef54cb306ef3090ffd551733c491e1cae2a28dDaniel Dunbar
112d0ef54cb306ef3090ffd551733c491e1cae2a28dDaniel Dunbar/// SparseSolver - This class is a general purpose solver for Sparse Conditional
113c36541e7bfa69cc63e2668a986bc99117559c545Mike Stump/// Propagation with a programmable lattice function.
114c36541e7bfa69cc63e2668a986bc99117559c545Mike Stump///
115c36541e7bfa69cc63e2668a986bc99117559c545Mike Stumpclass SparseSolver {
1165bde6f41506535ddaf6e9ff60bd1488db8ded952Daniel Dunbar  typedef AbstractLatticeFunction::LatticeVal LatticeVal;
117cf6bde343ff5653744ca782e04d5a9c54b260042Daniel Dunbar
118d0ef54cb306ef3090ffd551733c491e1cae2a28dDaniel Dunbar  /// LatticeFunc - This is the object that knows the lattice and how to do
1195e31474b9c8348e8d0404264ae6a8775e34df6acBill Wendling  /// compute transfer functions.
120c36541e7bfa69cc63e2668a986bc99117559c545Mike Stump  AbstractLatticeFunction *LatticeFunc;
121c36541e7bfa69cc63e2668a986bc99117559c545Mike Stump
122cf6bde343ff5653744ca782e04d5a9c54b260042Daniel Dunbar  DenseMap<Value*, LatticeVal> ValueState;  // The state each value is in.
1235e31474b9c8348e8d0404264ae6a8775e34df6acBill Wendling  SmallPtrSet<BasicBlock*, 16> BBExecutable;   // The bbs that are executable.
124c36541e7bfa69cc63e2668a986bc99117559c545Mike Stump
125f7fff322debe0b7256fe4dbc1103a3c2b43c379aDaniel Dunbar  std::vector<Instruction*> InstWorkList;   // Worklist of insts to process.
12693ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin
127c36541e7bfa69cc63e2668a986bc99117559c545Mike Stump  std::vector<BasicBlock*> BBWorkList;  // The BasicBlock work list
1288e03444e924665d4d90f5cfc0624c815256e0309Daniel Dunbar
12993ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin  /// KnownFeasibleEdges - Entries in this set are edges which have already had
130c36541e7bfa69cc63e2668a986bc99117559c545Mike Stump  /// PHI nodes retriggered.
131eedd292ea0cf2216ff16d3490147323489102e3aDaniel Dunbar  typedef std::pair<BasicBlock*,BasicBlock*> Edge;
13293ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin  std::set<Edge> KnownFeasibleEdges;
133c36541e7bfa69cc63e2668a986bc99117559c545Mike Stump
134fcab2ca966d5176839f8698535e0d807bd968629Daniel Dunbar  SparseSolver(const SparseSolver&) LLVM_DELETED_FUNCTION;
13593ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin  void operator=(const SparseSolver&) LLVM_DELETED_FUNCTION;
136c36541e7bfa69cc63e2668a986bc99117559c545Mike Stumppublic:
1372e0011650fe149bf55916c6f25558bf9bfebf537Daniel Dunbar  explicit SparseSolver(AbstractLatticeFunction *Lattice)
13893ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    : LatticeFunc(Lattice) {}
139c36541e7bfa69cc63e2668a986bc99117559c545Mike Stump  ~SparseSolver() {
1402e0011650fe149bf55916c6f25558bf9bfebf537Daniel Dunbar    delete LatticeFunc;
14193ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin  }
142c36541e7bfa69cc63e2668a986bc99117559c545Mike Stump
143573b907e8ba3b74fc69cddaf63496c7bb5994196Daniel Dunbar  /// Solve - Solve for constants and executable blocks.
14493ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin  ///
145c36541e7bfa69cc63e2668a986bc99117559c545Mike Stump  void Solve(Function &F);
146573b907e8ba3b74fc69cddaf63496c7bb5994196Daniel Dunbar
14793ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin  void Print(Function &F, raw_ostream &OS) const;
148c36541e7bfa69cc63e2668a986bc99117559c545Mike Stump
149cc401dc651a91f53f9f9a39956732be8f537e7faDaniel Dunbar  /// getLatticeState - Return the LatticeVal object that corresponds to the
15093ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin  /// value.  If an value is not in the map, it is returned as untracked,
151c36541e7bfa69cc63e2668a986bc99117559c545Mike Stump  /// unlike the getOrInitValueState method.
152cc401dc651a91f53f9f9a39956732be8f537e7faDaniel Dunbar  LatticeVal getLatticeState(Value *V) const {
15393ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin    DenseMap<Value*, LatticeVal>::const_iterator I = ValueState.find(V);
154c36541e7bfa69cc63e2668a986bc99117559c545Mike Stump    return I != ValueState.end() ? I->second : LatticeFunc->getUntrackedVal();
155836a0641ba4109b2c1254eec247ba4d2731bc2b7Daniel Dunbar  }
15693ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin
157a1e6de9171d10c3a3dde7fc2e8cf72cc98bf6362Eli Friedman  /// getOrInitValueState - Return the LatticeVal object that corresponds to the
158a1e6de9171d10c3a3dde7fc2e8cf72cc98bf6362Eli Friedman  /// value, initializing the value's state if it hasn't been entered into the
159a1e6de9171d10c3a3dde7fc2e8cf72cc98bf6362Eli Friedman  /// map yet.   This function is necessary because not all values should start
160a1e6de9171d10c3a3dde7fc2e8cf72cc98bf6362Eli Friedman  /// out in the underdefined state... Arguments should be overdefined, and
16155e59e139d9ebcaae16d710472e28edbcafac98aDaniel Dunbar  /// constants should be marked as constants.
16293ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin  ///
16355e59e139d9ebcaae16d710472e28edbcafac98aDaniel Dunbar  LatticeVal getOrInitValueState(Value *V);
16455e59e139d9ebcaae16d710472e28edbcafac98aDaniel Dunbar
16555e59e139d9ebcaae16d710472e28edbcafac98aDaniel Dunbar  /// isEdgeFeasible - Return true if the control flow edge from the 'From'
16693ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin  /// basic block to the 'To' basic block is currently feasible.  If
16755e59e139d9ebcaae16d710472e28edbcafac98aDaniel Dunbar  /// AggressiveUndef is true, then this treats values with unknown lattice
16855e59e139d9ebcaae16d710472e28edbcafac98aDaniel Dunbar  /// values as undefined.  This is generally only useful when solving the
16955e59e139d9ebcaae16d710472e28edbcafac98aDaniel Dunbar  /// lattice, not when querying it.
17093ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin  bool isEdgeFeasible(BasicBlock *From, BasicBlock *To,
17155e59e139d9ebcaae16d710472e28edbcafac98aDaniel Dunbar                      bool AggressiveUndef = false);
17255e59e139d9ebcaae16d710472e28edbcafac98aDaniel Dunbar
17393ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin  /// isBlockExecutable - Return true if there are any known feasible
17455e59e139d9ebcaae16d710472e28edbcafac98aDaniel Dunbar  /// edges into the basic block.  This is generally only useful when
17555e59e139d9ebcaae16d710472e28edbcafac98aDaniel Dunbar  /// querying the lattice.
17693ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin  bool isBlockExecutable(BasicBlock *BB) const {
17755e59e139d9ebcaae16d710472e28edbcafac98aDaniel Dunbar    return BBExecutable.count(BB);
17855e59e139d9ebcaae16d710472e28edbcafac98aDaniel Dunbar  }
17993ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin
18055e59e139d9ebcaae16d710472e28edbcafac98aDaniel Dunbarprivate:
18155e59e139d9ebcaae16d710472e28edbcafac98aDaniel Dunbar  /// UpdateState - When the state for some instruction is potentially updated,
18293ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin  /// this function notices and adds I to the worklist if needed.
18355e59e139d9ebcaae16d710472e28edbcafac98aDaniel Dunbar  void UpdateState(Instruction &Inst, LatticeVal V);
18455e59e139d9ebcaae16d710472e28edbcafac98aDaniel Dunbar
18593ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin  /// MarkBlockExecutable - This method can be used by clients to mark all of
18655e59e139d9ebcaae16d710472e28edbcafac98aDaniel Dunbar  /// the blocks that are known to be intrinsically live in the processed unit.
18755e59e139d9ebcaae16d710472e28edbcafac98aDaniel Dunbar  void MarkBlockExecutable(BasicBlock *BB);
18893ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin
18955e59e139d9ebcaae16d710472e28edbcafac98aDaniel Dunbar  /// markEdgeExecutable - Mark a basic block as executable, adding it to the BB
19055e59e139d9ebcaae16d710472e28edbcafac98aDaniel Dunbar  /// work list if it is not already executable.
19155e59e139d9ebcaae16d710472e28edbcafac98aDaniel Dunbar  void markEdgeExecutable(BasicBlock *Source, BasicBlock *Dest);
19293ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin
19355e59e139d9ebcaae16d710472e28edbcafac98aDaniel Dunbar  /// getFeasibleSuccessors - Return a vector of booleans to indicate which
19455e59e139d9ebcaae16d710472e28edbcafac98aDaniel Dunbar  /// successors are reachable from a given terminator instruction.
19555e59e139d9ebcaae16d710472e28edbcafac98aDaniel Dunbar  void getFeasibleSuccessors(TerminatorInst &TI, SmallVectorImpl<bool> &Succs,
19693ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin                             bool AggressiveUndef);
19755e59e139d9ebcaae16d710472e28edbcafac98aDaniel Dunbar
19855e59e139d9ebcaae16d710472e28edbcafac98aDaniel Dunbar  void visitInst(Instruction &I);
19955e59e139d9ebcaae16d710472e28edbcafac98aDaniel Dunbar  void visitPHINode(PHINode &I);
20093ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin  void visitTerminatorInst(TerminatorInst &TI);
20155e59e139d9ebcaae16d710472e28edbcafac98aDaniel Dunbar
20255e59e139d9ebcaae16d710472e28edbcafac98aDaniel Dunbar};
20355e59e139d9ebcaae16d710472e28edbcafac98aDaniel Dunbar
20493ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin} // end namespace llvm
20546c54fb8ec45765a475b7b709b9aee7f94c490c2Daniel Dunbar
20646c54fb8ec45765a475b7b709b9aee7f94c490c2Daniel Dunbar#endif // LLVM_ANALYSIS_SPARSEPROPAGATION_H
20746c54fb8ec45765a475b7b709b9aee7f94c490c2Daniel Dunbar