-// instance of the promoter -- to keep all the local function data.
-// gets re-created for each function processed
-class PromoteInstance {
-protected:
- vector<AllocaInst*> Allocas; // the alloca instruction..
- map<Instruction*, unsigned> AllocaLookup; // reverse mapping of above
-
- vector<vector<BasicBlock*> > WriteSets; // index corresponds to Allocas
- vector<vector<BasicBlock*> > PhiNodes; // index corresponds to Allocas
- vector<vector<Value*> > CurrentValue; // the current value stack
-
- //list of instructions to remove at end of pass :)
- vector<Instruction *> KillList;
-
- set<BasicBlock*> visited; // the basic blocks we've already visited
- map<BasicBlock*, vector<PHINode*> > NewPhiNodes; // the phinodes we're adding
-
- void traverse(BasicBlock *f, BasicBlock * predecessor);
- bool PromoteFunction(Function *F, DominanceFrontier &DF);
- bool QueuePhiNode(BasicBlock *bb, unsigned alloca_index);
- void findSafeAllocas(Function *M);
- bool didchange;
-public:
- // I do this so that I can force the deconstruction of the local variables
- PromoteInstance(Function *F, DominanceFrontier &DF) {
- didchange = PromoteFunction(F, DF);
- }
- //This returns whether the pass changes anything
- operator bool () { return didchange; }
-};
+ public:
+ // runOnFunction - To run this pass, first we calculate the alloca
+ // instructions that are safe for promotion, then we promote each one.
+ //
+ virtual bool runOnFunction(Function *F);
+
+ // getAnalysisUsage - We need dominance frontiers
+ //
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired(DominanceFrontier::ID);
+ }
+
+ private:
+ void Traverse(BasicBlock *BB, BasicBlock *Pred, vector<Value*> &IncVals,
+ set<BasicBlock*> &Visited);
+ bool QueuePhiNode(BasicBlock *BB, unsigned AllocaIdx);
+ void FindSafeAllocas(Function *F);
+ };