[llvm-commits] CVS: poolalloc/lib/PoolAllocate/PoolAllocate.cpp PoolAllocate.h TransformFunctionBody.cpp
Chris Lattner
lattner at cs.uiuc.edu
Tue Dec 14 12:16:34 PST 2004
Changes in directory poolalloc/lib/PoolAllocate:
PoolAllocate.cpp updated: 1.94 -> 1.95
PoolAllocate.h updated: 1.32 -> 1.33
TransformFunctionBody.cpp updated: 1.33 -> 1.34
---
Log message:
Refactor a bunch of code to make it easier to understand. Switch from
std::set<pair<x,y>> to multimap<x,y>.
---
Diffs of the changes: (+164 -158)
Index: poolalloc/lib/PoolAllocate/PoolAllocate.cpp
diff -u poolalloc/lib/PoolAllocate/PoolAllocate.cpp:1.94 poolalloc/lib/PoolAllocate/PoolAllocate.cpp:1.95
--- poolalloc/lib/PoolAllocate/PoolAllocate.cpp:1.94 Mon Nov 15 15:05:09 2004
+++ poolalloc/lib/PoolAllocate/PoolAllocate.cpp Tue Dec 14 14:16:24 2004
@@ -386,8 +386,6 @@
return true;
}
- TargetData &TD = getAnalysis<TargetData>();
-
std::cerr << "Pool allocating " << GlobalHeapNodes.size()
<< " global nodes!\n";
@@ -557,8 +555,8 @@
// Transform the body of the function now... collecting information about uses
// of the pools.
- std::set<std::pair<AllocaInst*, Instruction*> > PoolUses;
- std::set<std::pair<AllocaInst*, CallInst*> > PoolFrees;
+ std::multimap<AllocaInst*, Instruction*> PoolUses;
+ std::multimap<AllocaInst*, CallInst*> PoolFrees;
TransformBody(G, FI, PoolUses, PoolFrees, NewF);
// Create pool construction/destruction code
@@ -582,13 +580,16 @@
}
static void DeleteIfIsPoolFree(Instruction *I, AllocaInst *PD,
- std::set<std::pair<AllocaInst*, CallInst*> > &PoolFrees) {
+ std::multimap<AllocaInst*, CallInst*> &PoolFrees) {
+ std::multimap<AllocaInst*, CallInst*>::iterator PFI, PFE;
if (CallInst *CI = dyn_cast<CallInst>(I))
- if (PoolFrees.count(std::make_pair(PD, CI))) {
- PoolFrees.erase(std::make_pair(PD, CI));
- I->eraseFromParent();
- ++NumPoolFree;
- }
+ for (tie(PFI,PFE) = PoolFrees.equal_range(PD); PFI != PFE; ++PFI)
+ if (PFI->second == I) {
+ PoolFrees.erase(PFI);
+ I->eraseFromParent();
+ ++NumPoolFree;
+ return;
+ }
}
void PoolAllocate::CalculateLivePoolFreeBlocks(std::set<BasicBlock*>&LiveBlocks,
@@ -608,17 +609,57 @@
}
}
-
-/// InitializeAndDestroyPools - This inserts calls to poolinit and pooldestroy
-/// into the function to initialize and destroy the pools in the NodesToPA list.
+/// InitializeAndDestroyPools- This inserts calls to poolinit and pooldestroy
+/// into the function to initialize and destroy one pool.
///
-void PoolAllocate::InitializeAndDestroyPools(Function &F,
- const std::vector<DSNode*> &NodesToPA,
+void PoolAllocate::InitializeAndDestroyPool(Function &F, DSNode *Node,
std::map<DSNode*, Value*> &PoolDescriptors,
- std::set<std::pair<AllocaInst*, Instruction*> > &PoolUses,
- std::set<std::pair<AllocaInst*, CallInst*> > &PoolFrees) {
- TargetData &TD = getAnalysis<TargetData>();
-
+ std::multimap<AllocaInst*, Instruction*> &PoolUses,
+ std::multimap<AllocaInst*, CallInst*> &PoolFrees) {
+ AllocaInst *PD = cast<AllocaInst>(PoolDescriptors[Node]);
+
+ // Convert the PoolUses/PoolFrees sets into something specific to this pool: a
+ // set of which blocks are immediately using the pool.
+ std::set<BasicBlock*> UsingBlocks;
+
+ std::multimap<AllocaInst*, Instruction*>::iterator PUI, PUE;
+ tie(PUI, PUE) = PoolUses.equal_range(PD);
+ for (; PUI != PUE; ++PUI)
+ UsingBlocks.insert(PUI->second->getParent());
+
+ // To calculate all of the basic blocks which require the pool to be
+ // initialized before, do a depth first search on the CFG from the using
+ // blocks.
+ std::set<BasicBlock*> InitializedBefore;
+ std::set<BasicBlock*> DestroyedAfter;
+ for (std::set<BasicBlock*>::iterator I = UsingBlocks.begin(),
+ E = UsingBlocks.end(); I != E; ++I) {
+ for (df_ext_iterator<BasicBlock*, std::set<BasicBlock*> >
+ DI = df_ext_begin(*I, InitializedBefore),
+ DE = df_ext_end(*I, InitializedBefore); DI != DE; ++DI)
+ /* empty */;
+
+ for (idf_ext_iterator<BasicBlock*, std::set<BasicBlock*> >
+ DI = idf_ext_begin(*I, DestroyedAfter),
+ DE = idf_ext_end(*I, DestroyedAfter); DI != DE; ++DI)
+ /* empty */;
+ }
+ // Now that we have created the sets, intersect them.
+ std::set<BasicBlock*> LiveBlocks;
+ std::set_intersection(InitializedBefore.begin(),InitializedBefore.end(),
+ DestroyedAfter.begin(), DestroyedAfter.end(),
+ std::inserter(LiveBlocks, LiveBlocks.end()));
+ InitializedBefore.clear();
+ DestroyedAfter.clear();
+
+ DEBUG(std::cerr << "POOL: " << PD->getName() << " information:\n");
+ DEBUG(std::cerr << " Live in blocks: ");
+ DEBUG(for (std::set<BasicBlock*>::iterator I = LiveBlocks.begin(),
+ E = LiveBlocks.end(); I != E; ++I)
+ std::cerr << (*I)->getName() << " ");
+ DEBUG(std::cerr << "\n");
+
+
std::vector<Instruction*> PoolInitPoints;
std::vector<Instruction*> PoolDestroyPoints;
@@ -635,100 +676,32 @@
if (isa<ReturnInst>(BB->getTerminator()) ||
isa<UnwindInst>(BB->getTerminator()))
PoolDestroyPoints.push_back(BB->getTerminator());
- }
-
- std::set<AllocaInst*> AllocasHandled;
-
- // Insert all of the poolinit/destroy calls into the function.
- for (unsigned i = 0, e = NodesToPA.size(); i != e; ++i) {
- DSNode *Node = NodesToPA[i];
-
- if (isa<GlobalVariable>(PoolDescriptors[Node]) ||
- isa<ConstantPointerNull>(PoolDescriptors[Node]))
- continue;
-
- assert(isa<AllocaInst>(PoolDescriptors[Node]) && "Why pool allocate this?");
- AllocaInst *PD = cast<AllocaInst>(PoolDescriptors[Node]);
-
- std::set<std::pair<AllocaInst*, Instruction*> >::iterator XUI =
- PoolUses.lower_bound(std::make_pair(PD, (Instruction*)0));
- bool HasUse = XUI != PoolUses.end() && XUI->first == PD;
-
- std::set<std::pair<AllocaInst*, CallInst*> >::iterator XUI2 =
- PoolFrees.lower_bound(std::make_pair(PD, (CallInst*)0));
- bool HasFree = XUI2 != PoolFrees.end() && XUI2->first == PD;
-
- // FIXME: Turn this into an assert and fix the problem!!
- //assert(HasUse && "Pool is not used, but is marked heap?!");
- if (!HasUse && !HasFree) continue;
- if (!AllocasHandled.insert(PD).second) continue;
-
- ++NumPools;
- if (!Node->isNodeCompletelyFolded())
- ++NumTSPools;
-
- // Convert the PoolUses/PoolFrees sets into something specific to this
- // pool.
- std::set<BasicBlock*> UsingBlocks;
-
- std::set<std::pair<AllocaInst*, Instruction*> >::iterator PUI =
- PoolUses.lower_bound(std::make_pair(PD, (Instruction*)0));
- if (PUI != PoolUses.end() && PUI->first < PD) ++PUI;
- for (; PUI != PoolUses.end() && PUI->first == PD; ++PUI)
- UsingBlocks.insert(PUI->second->getParent());
-
- // To calculate all of the basic blocks which require the pool to be
- // initialized before, do a depth first search on the CFG from the using
- // blocks.
- std::set<BasicBlock*> InitializedBefore;
- std::set<BasicBlock*> DestroyedAfter;
- for (std::set<BasicBlock*>::iterator I = UsingBlocks.begin(),
- E = UsingBlocks.end(); I != E; ++I) {
- for (df_ext_iterator<BasicBlock*, std::set<BasicBlock*> >
- DI = df_ext_begin(*I, InitializedBefore),
- DE = df_ext_end(*I, InitializedBefore); DI != DE; ++DI)
- /* empty */;
-
- for (idf_ext_iterator<BasicBlock*, std::set<BasicBlock*> >
- DI = idf_ext_begin(*I, DestroyedAfter),
- DE = idf_ext_end(*I, DestroyedAfter); DI != DE; ++DI)
- /* empty */;
- }
- // Now that we have created the sets, intersect them.
- std::set<BasicBlock*> LiveBlocks;
- std::set_intersection(InitializedBefore.begin(),InitializedBefore.end(),
- DestroyedAfter.begin(), DestroyedAfter.end(),
- std::inserter(LiveBlocks, LiveBlocks.end()));
- InitializedBefore.clear();
- DestroyedAfter.clear();
-
- // Keep track of the blocks we have inserted poolinit/destroy in
+ } else {
+ // Keep track of the blocks we have inserted poolinit/destroy into.
std::set<BasicBlock*> PoolInitInsertedBlocks, PoolDestroyInsertedBlocks;
-
- DEBUG(std::cerr << "POOL: " << PD->getName() << " information:\n");
- DEBUG(std::cerr << " Live in blocks: ");
+
for (std::set<BasicBlock*>::iterator I = LiveBlocks.begin(),
E = LiveBlocks.end(); I != E; ++I) {
BasicBlock *BB = *I;
TerminatorInst *Term = BB->getTerminator();
- DEBUG(std::cerr << BB->getName() << " ");
// Check the predecessors of this block. If any preds are not in the
// set, or if there are no preds, insert a pool init.
bool AllIn, NoneIn;
AllOrNoneInSet(pred_begin(BB), pred_end(BB), LiveBlocks, AllIn,
NoneIn);
-
+
if (NoneIn) {
if (!PoolInitInsertedBlocks.count(BB)) {
BasicBlock::iterator It = BB->begin();
+#if 0
// Move through all of the instructions not in the pool
while (!PoolUses.count(std::make_pair(PD, It)))
// Advance past non-users deleting any pool frees that we run
// across.
DeleteIfIsPoolFree(It++, PD, PoolFrees);
- if (!DisableInitDestroyOpt)
- PoolInitPoints.push_back(It);
+#endif
+ PoolInitPoints.push_back(It);
PoolInitInsertedBlocks.insert(BB);
}
} else if (!AllIn) {
@@ -739,10 +712,9 @@
if (SplitCriticalEdge(BB, PI))
// If the critical edge was split, *PI was invalidated
goto TryAgainPred;
-
+
// Insert at the end of the predecessor, before the terminator.
- if (!DisableInitDestroyOpt)
- PoolInitPoints.push_back((*PI)->getTerminator());
+ PoolInitPoints.push_back((*PI)->getTerminator());
PoolInitInsertedBlocks.insert(*PI);
}
}
@@ -751,19 +723,20 @@
// not in the set, insert a destroy in this block.
AllOrNoneInSet(succ_begin(BB), succ_end(BB), LiveBlocks,
AllIn, NoneIn);
-
+
if (NoneIn) {
// Insert before the terminator.
if (!PoolDestroyInsertedBlocks.count(BB)) {
BasicBlock::iterator It = Term;
- // Rewind to the first using insruction
+ // Rewind to the first using instruction.
+#if 0
while (!PoolUses.count(std::make_pair(PD, It)))
DeleteIfIsPoolFree(It--, PD, PoolFrees);
-
+#endif
+
// Insert after the first using instruction
- if (!DisableInitDestroyOpt)
- PoolDestroyPoints.push_back(++It);
+ PoolDestroyPoints.push_back(++It);
PoolDestroyInsertedBlocks.insert(BB);
}
} else if (!AllIn) {
@@ -773,64 +746,92 @@
!PoolDestroyInsertedBlocks.count(*SI)) {
// If this edge is critical, split it.
SplitCriticalEdge(BB, SI);
-
+
// Insert at entry to the successor, but after any PHI nodes.
BasicBlock::iterator It = (*SI)->begin();
while (isa<PHINode>(It)) ++It;
- if (!DisableInitDestroyOpt)
- PoolDestroyPoints.push_back(It);
+ PoolDestroyPoints.push_back(It);
PoolDestroyInsertedBlocks.insert(*SI);
}
}
}
- DEBUG(std::cerr << "\n Init in blocks: ");
+ }
- // Insert the calls to initialize the pool.
- unsigned ElSizeV = Heuristic::getRecommendedSize(Node);
- Value *ElSize = ConstantUInt::get(Type::UIntTy, ElSizeV);
- unsigned AlignV = Heuristic::getRecommendedAlignment(Node);
- Value *Align = ConstantUInt::get(Type::UIntTy, AlignV);
-
- for (unsigned i = 0, e = PoolInitPoints.size(); i != e; ++i) {
- new CallInst(PoolInit, make_vector((Value*)PD, ElSize, Align, 0),
- "", PoolInitPoints[i]);
- DEBUG(std::cerr << PoolInitPoints[i]->getParent()->getName() << " ");
- }
- if (!DisableInitDestroyOpt)
- PoolInitPoints.clear();
+ DEBUG(std::cerr << " Init in blocks: ");
- DEBUG(std::cerr << "\n Destroy in blocks: ");
+ // Insert the calls to initialize the pool.
+ unsigned ElSizeV = Heuristic::getRecommendedSize(Node);
+ Value *ElSize = ConstantUInt::get(Type::UIntTy, ElSizeV);
+ unsigned AlignV = Heuristic::getRecommendedAlignment(Node);
+ Value *Align = ConstantUInt::get(Type::UIntTy, AlignV);
+
+ for (unsigned i = 0, e = PoolInitPoints.size(); i != e; ++i) {
+ new CallInst(PoolInit, make_vector((Value*)PD, ElSize, Align, 0),
+ "", PoolInitPoints[i]);
+ DEBUG(std::cerr << PoolInitPoints[i]->getParent()->getName() << " ");
+ }
+
+ DEBUG(std::cerr << "\n Destroy in blocks: ");
+
+ // Loop over all of the places to insert pooldestroy's...
+ for (unsigned i = 0, e = PoolDestroyPoints.size(); i != e; ++i) {
+ // Insert the pooldestroy call for this pool.
+ new CallInst(PoolDestroy, make_vector((Value*)PD, 0), "",
+ PoolDestroyPoints[i]);
+ DEBUG(std::cerr << PoolDestroyPoints[i]->getParent()->getName()<<" ");
+ }
+ DEBUG(std::cerr << "\n\n");
+
+ // We are allowed to delete any poolfree's which occur between the last
+ // call to poolalloc, and the call to pooldestroy. Figure out which
+ // basic blocks have this property for this pool.
+ std::set<BasicBlock*> PoolFreeLiveBlocks;
+ if (!DisablePoolFreeOpt)
+ CalculateLivePoolFreeBlocks(PoolFreeLiveBlocks, PD);
+ else
+ PoolFreeLiveBlocks = LiveBlocks;
+
+ // Delete any pool frees which are not in live blocks, for correctness.
+ std::multimap<AllocaInst*, CallInst*>::iterator PFI, PFE;
+ for (tie(PFI,PFE) = PoolFrees.equal_range(PD); PFI != PFE; ) {
+ CallInst *PoolFree = (PFI++)->second;
+ if (!LiveBlocks.count(PoolFree->getParent()) ||
+ !PoolFreeLiveBlocks.count(PoolFree->getParent()))
+ DeleteIfIsPoolFree(PoolFree, PD, PoolFrees);
+ }
+}
- // Loop over all of the places to insert pooldestroy's...
- for (unsigned i = 0, e = PoolDestroyPoints.size(); i != e; ++i) {
- // Insert the pooldestroy call for this pool.
- new CallInst(PoolDestroy, make_vector((Value*)PD, 0), "",
- PoolDestroyPoints[i]);
- DEBUG(std::cerr << PoolDestroyPoints[i]->getParent()->getName()<<" ");
- }
- DEBUG(std::cerr << "\n\n");
- // We are allowed to delete any poolfree's which occur between the last
- // call to poolalloc, and the call to pooldestroy. Figure out which
- // basic blocks have this property for this pool.
- std::set<BasicBlock*> PoolFreeLiveBlocks;
- if (!DisablePoolFreeOpt)
- CalculateLivePoolFreeBlocks(PoolFreeLiveBlocks, PD);
- else
- PoolFreeLiveBlocks = LiveBlocks;
+/// InitializeAndDestroyPools - This inserts calls to poolinit and pooldestroy
+/// into the function to initialize and destroy the pools in the NodesToPA list.
+///
+void PoolAllocate::InitializeAndDestroyPools(Function &F,
+ const std::vector<DSNode*> &NodesToPA,
+ std::map<DSNode*, Value*> &PoolDescriptors,
+ std::multimap<AllocaInst*, Instruction*> &PoolUses,
+ std::multimap<AllocaInst*, CallInst*> &PoolFrees) {
+ std::set<AllocaInst*> AllocasHandled;
- if (!DisableInitDestroyOpt)
- PoolDestroyPoints.clear();
+ // Insert all of the poolinit/destroy calls into the function.
+ for (unsigned i = 0, e = NodesToPA.size(); i != e; ++i) {
+ DSNode *Node = NodesToPA[i];
- // Delete any pool frees which are not in live blocks, for correctness.
- std::set<std::pair<AllocaInst*, CallInst*> >::iterator PFI =
- PoolFrees.lower_bound(std::make_pair(PD, (CallInst*)0));
- if (PFI != PoolFrees.end() && PFI->first < PD) ++PFI;
- for (; PFI != PoolFrees.end() && PFI->first == PD; ) {
- CallInst *PoolFree = (PFI++)->second;
- if (!LiveBlocks.count(PoolFree->getParent()) ||
- !PoolFreeLiveBlocks.count(PoolFree->getParent()))
- DeleteIfIsPoolFree(PoolFree, PD, PoolFrees);
- }
+ if (isa<GlobalVariable>(PoolDescriptors[Node]) ||
+ isa<ConstantPointerNull>(PoolDescriptors[Node]))
+ continue;
+
+ assert(isa<AllocaInst>(PoolDescriptors[Node]) && "Why pool allocate this?");
+ AllocaInst *PD = cast<AllocaInst>(PoolDescriptors[Node]);
+
+ // FIXME: Turn this into an assert and fix the problem!!
+ //assert(PoolUses.count(PD) && "Pool is not used, but is marked heap?!");
+ if (!PoolUses.count(PD) && !PoolFrees.count(PD)) continue;
+ if (!AllocasHandled.insert(PD).second) continue;
+
+ ++NumPools;
+ if (!Node->isNodeCompletelyFolded())
+ ++NumTSPools;
+
+ InitializeAndDestroyPool(F, Node, PoolDescriptors, PoolUses, PoolFrees);
}
}
Index: poolalloc/lib/PoolAllocate/PoolAllocate.h
diff -u poolalloc/lib/PoolAllocate/PoolAllocate.h:1.32 poolalloc/lib/PoolAllocate/PoolAllocate.h:1.33
--- poolalloc/lib/PoolAllocate/PoolAllocate.h:1.32 Mon Nov 15 15:05:09 2004
+++ poolalloc/lib/PoolAllocate/PoolAllocate.h Tue Dec 14 14:16:24 2004
@@ -187,8 +187,8 @@
std::map<DSNode*, Value*> &PoolDescriptors);
void TransformBody(DSGraph &g, PA::FuncInfo &fi,
- std::set<std::pair<AllocaInst*, Instruction*> > &poolUses,
- std::set<std::pair<AllocaInst*, CallInst*> > &poolFrees,
+ std::multimap<AllocaInst*, Instruction*> &poolUses,
+ std::multimap<AllocaInst*, CallInst*> &poolFrees,
Function &F);
/// InitializeAndDestroyPools - This inserts calls to poolinit and pooldestroy
@@ -197,8 +197,13 @@
void InitializeAndDestroyPools(Function &F,
const std::vector<DSNode*> &NodesToPA,
std::map<DSNode*, Value*> &PoolDescriptors,
- std::set<std::pair<AllocaInst*, Instruction*> > &PoolUses,
- std::set<std::pair<AllocaInst*, CallInst*> > &PoolFrees);
+ std::multimap<AllocaInst*, Instruction*> &PoolUses,
+ std::multimap<AllocaInst*, CallInst*> &PoolFrees);
+
+ void InitializeAndDestroyPool(Function &F, DSNode *Pool,
+ std::map<DSNode*, Value*> &PoolDescriptors,
+ std::multimap<AllocaInst*, Instruction*> &PoolUses,
+ std::multimap<AllocaInst*, CallInst*> &PoolFrees);
void CalculateLivePoolFreeBlocks(std::set<BasicBlock*> &LiveBlocks,Value *PD);
};
Index: poolalloc/lib/PoolAllocate/TransformFunctionBody.cpp
diff -u poolalloc/lib/PoolAllocate/TransformFunctionBody.cpp:1.33 poolalloc/lib/PoolAllocate/TransformFunctionBody.cpp:1.34
--- poolalloc/lib/PoolAllocate/TransformFunctionBody.cpp:1.33 Mon Nov 15 15:05:09 2004
+++ poolalloc/lib/PoolAllocate/TransformFunctionBody.cpp Tue Dec 14 14:16:24 2004
@@ -40,15 +40,15 @@
// of which blocks require the memory in the pool to not be freed. This
// does not include poolfree's. Note that this is only tracked for pools
// which this is the home of, ie, they are Alloca instructions.
- std::set<std::pair<AllocaInst*, Instruction*> > &PoolUses;
+ std::multimap<AllocaInst*, Instruction*> &PoolUses;
// PoolDestroys - For each pool, keep track of the actual poolfree calls
// inserted into the code. This is seperated out from PoolUses.
- std::set<std::pair<AllocaInst*, CallInst*> > &PoolFrees;
+ std::multimap<AllocaInst*, CallInst*> &PoolFrees;
FuncTransform(PoolAllocate &P, DSGraph &g, FuncInfo &fi,
- std::set<std::pair<AllocaInst*, Instruction*> > &poolUses,
- std::set<std::pair<AllocaInst*, CallInst*> > &poolFrees)
+ std::multimap<AllocaInst*, Instruction*> &poolUses,
+ std::multimap<AllocaInst*, CallInst*> &poolFrees)
: PAInfo(P), G(g), FI(fi),
PoolUses(poolUses), PoolFrees(poolFrees) {
}
@@ -111,8 +111,8 @@
}
void PoolAllocate::TransformBody(DSGraph &g, PA::FuncInfo &fi,
- std::set<std::pair<AllocaInst*,Instruction*> > &poolUses,
- std::set<std::pair<AllocaInst*, CallInst*> > &poolFrees,
+ std::multimap<AllocaInst*,Instruction*> &poolUses,
+ std::multimap<AllocaInst*, CallInst*> &poolFrees,
Function &F) {
FuncTransform(*this, g, fi, poolUses, poolFrees).visit(F);
}
More information about the llvm-commits
mailing list