[llvm-commits] [poolalloc] r138740 - /poolalloc/trunk/lib/DSA/BottomUpClosure.cpp
John Criswell
criswell at uiuc.edu
Mon Aug 29 10:17:57 PDT 2011
Author: criswell
Date: Mon Aug 29 12:17:56 2011
New Revision: 138740
URL: http://llvm.org/viewvc/llvm-project?rev=138740&view=rev
Log:
Refactored the CloneAuxIntoGlobal() to remove quadratic behavior.
This reduces the time spent on a test case from OpenSSH on Mac OS X from
intolerable time (+1 hour, if I recall correctly) to 7 minutes of analysis time.
Modified:
poolalloc/trunk/lib/DSA/BottomUpClosure.cpp
Modified: poolalloc/trunk/lib/DSA/BottomUpClosure.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/BottomUpClosure.cpp?rev=138740&r1=138739&r2=138740&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/BottomUpClosure.cpp (original)
+++ poolalloc/trunk/lib/DSA/BottomUpClosure.cpp Mon Aug 29 12:17:56 2011
@@ -489,6 +489,11 @@
return MyID; // == Min
}
+ bool compareDSCallSites (const DSCallSite & DS1, const DSCallSite & DS2) {
+ return (DS1.getCallSite().getCalledValue() <
+ DS2.getCallSite().getCalledValue());
+ }
+
//
// Method: CloneAuxIntoGlobal()
//
@@ -500,48 +505,105 @@
// site in its own list of unresolved call sites.
//
void BUDataStructures::CloneAuxIntoGlobal(DSGraph* G) {
+ //
+ // If this DSGraph has no unresolved call sites, do nothing. We do enough
+ // work that wastes time even when the list is empty that this extra check
+ // is probably worth it.
+ //
+ if (G->afc_begin() == G->afc_end())
+ return;
+
DSGraph* GG = G->getGlobalsGraph();
ReachabilityCloner RC(GG, G, 0);
//
- // Scan through all unresolved call sites (call sites for which we do not yet
- // know all of the callees) in the specified graph and see if the globals
- // graph also has an unresolved call site for the same function pointer. If
- // it does, merge them together; otherwise, just bring the unresolved call
- // site into the global graph's set of unresolved call sites.
+ // Sort the lists of DSCallSites by the LLVM value that is used for the
+ // indirect call.
//
+ G->getAuxFunctionCalls().sort (compareDSCallSites);
+ GG->getAuxFunctionCalls().sort (compareDSCallSites);
+
+ //
+ // Determine which called values are both within the local graph DSCallsites
+ // and the global graph DSCallsites. Note that we require that the global
+ // graph have a DSNode for the called value.
+ //
+ std::set<Value *> LocalCallValues;
+ std::set<Value *> GlobalCallValues;
+ std::set<Value *> CommonCallValues;
for (DSGraph::afc_iterator ii = G->afc_begin(), ee = G->afc_end();
ii != ee;
++ii) {
+ Value * V = ii->getCallSite().getCalledValue();
+ if (GG->hasNodeForValue(V)) {
+ LocalCallValues.insert (V);
+ }
+ }
+
+ for (DSGraph::afc_iterator ii = GG->afc_begin();
+ ii != GG->afc_end();
+ ++ii) {
+ Value * V = ii->getCallSite().getCalledValue();
+ GlobalCallValues.insert (V);
+ }
+
+ std::set_intersection (LocalCallValues.begin(), LocalCallValues.end(),
+ GlobalCallValues.begin(), GlobalCallValues.end(),
+ std::inserter (CommonCallValues,
+ CommonCallValues.begin()));
+ LocalCallValues.clear();
+ GlobalCallValues.clear();
+ //
+ // Scan through all the unresolved call sites in the local graph for which
+ // the globals graph also considers the call site unresolved; merge such call
+ // sites together.
+ //
+ DSGraph::afc_iterator ii = G->afc_begin();
+ DSGraph::afc_iterator GGii = GG->afc_begin();
+ for (std::set<Value *>::iterator iv = CommonCallValues.begin();
+ iv != CommonCallValues.end();
+ ++iv) {
//
- // If we can, merge with an existing call site for this instruction.
+ // Move the iterator in the local graph to the appropriate call site.
+ // In the process, if we see a call site that needs to be added to the
+ // globals graph, do that now.
//
- if (GG->hasNodeForValue(ii->getCallSite().getCalledValue())) {
- //
- // Determine whether the globals graph knows about this call site and
- // consider it to be unresolved.
- //
- DSGraph::afc_iterator GGii;
- for(GGii = GG->afc_begin(); GGii != GG->afc_end(); ++GGii)
- if (GGii->getCallSite().getCalledValue() ==
- ii->getCallSite().getCalledValue())
- break;
-
- //
- // If the globals graph knows about the call site, merge it in.
- // Otherwise, just record it as an unresolved call site.
- //
- if (GGii != GG->afc_end())
- RC.cloneCallSite(*ii).mergeWith(*GGii);
- else
- GG->addAuxFunctionCall(RC.cloneCallSite(*ii));
- } else {
+ Value * V = *iv;
+ while (ii->getCallSite().getCalledValue() != V) {
GG->addAuxFunctionCall(RC.cloneCallSite(*ii));
+ ++ii;
}
+
+ //
+ // Move the iterator in the global graph to the appropriate call site.
+ //
+ while (GGii->getCallSite().getCalledValue() != V)
+ ++GGii;
+
+ //
+ // Merge the two call sites together.
+ //
+ RC.cloneCallSite(*ii).mergeWith(*GGii);
+
+ //
+ // Make sure not to repeat any merges.
+ //
+ ++ii;
+ ++GGii;
+ }
+
+ //
+ // We've now merged all DSCallSites that were known both to the local graph
+ // and the globals graph. Now, there are still some local call sites that
+ // need to be *added* to the globals graph. Do that now.
+ //
+ for (; ii != G->afc_end(); ++ii) {
+ GG->addAuxFunctionCall(RC.cloneCallSite(*ii));
}
}
+
//
// Description:
// Inline all graphs in the callgraph and remove callsites that are completely
More information about the llvm-commits
mailing list