[llvm-commits] [poolalloc] r114617 - in /poolalloc/trunk: include/dsa/DSGraph.h lib/DSA/DSGraph.cpp
Will Dietz
wdietz2 at illinois.edu
Wed Sep 22 18:35:29 PDT 2010
Author: wdietz2
Date: Wed Sep 22 20:35:29 2010
New Revision: 114617
URL: http://llvm.org/viewvc/llvm-project?rev=114617&view=rev
Log:
Better handling of incompleteness due to potential influence of external code.
Fixes extern.ll, extern2.ll, and extern3.ll (PR8206).
Modified:
poolalloc/trunk/include/dsa/DSGraph.h
poolalloc/trunk/lib/DSA/DSGraph.cpp
Modified: poolalloc/trunk/include/dsa/DSGraph.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DSGraph.h?rev=114617&r1=114616&r2=114617&view=diff
==============================================================================
--- poolalloc/trunk/include/dsa/DSGraph.h (original)
+++ poolalloc/trunk/include/dsa/DSGraph.h Wed Sep 22 20:35:29 2010
@@ -499,6 +499,12 @@
};
void markIncompleteNodes(unsigned Flags);
+ // markExternalNodes - Traverse the graph, identifying nodes that may be
+ // exposed to external code. The sources of this happening are:
+ // --Arguments and return values for external functions
+ // --Arguments and return values for externally visible functions
+ void markExternalNodes(void);
+
// removeDeadNodes - Use a reachability analysis to eliminate subgraphs that
// are unreachable. This often occurs because the data structure doesn't
// "escape" into it's caller, and thus should be eliminated from the caller's
Modified: poolalloc/trunk/lib/DSA/DSGraph.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/DSGraph.cpp?rev=114617&r1=114616&r2=114617&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/DSGraph.cpp (original)
+++ poolalloc/trunk/lib/DSA/DSGraph.cpp Wed Sep 22 20:35:29 2010
@@ -648,15 +648,17 @@
E = AuxFunctionCalls.end(); I != E; ++I)
markIncomplete(*I);
-#if 0
// Mark stuff passed into external functions as being incomplete.
// External functions may not appear in Aux during td, so process
// them specially
+#if 0
for (std::list<DSCallSite>::iterator I = FunctionCalls.begin(),
E = FunctionCalls.end(); I != E; ++I)
if(I->isDirectCall() && I->getCalleeFunc()->isDeclaration())
markIncomplete(*I);
#endif
+ // Handle all sources of external
+ markExternalNodes();
// Mark all global nodes as incomplete.
for (DSScalarMap::global_iterator I = ScalarMap.global_begin(),
@@ -675,6 +677,85 @@
}
}
+static void markExternalNode(DSNode *N) {
+ // FIXME: For now, we say that external is the same as incomplete as little to nothing
+ // checks or uses the External flag, and if we're to do the External flag it's as part of something
+ // else and needs more thought. For now we simply are ensuring things that should be incomplete due to
+ // external influence are, in fact, marked incomplete.
+ markIncompleteNode(N);
+}
+
+static void markExternal(DSCallSite &Call) {
+ markExternalNode(Call.getRetVal().getNode());
+
+ markExternalNode(Call.getVAVal().getNode());
+
+ // All objects pointed to by function arguments are incomplete!
+ for (unsigned i = 0, e = Call.getNumPtrArgs(); i != e; ++i)
+ markExternalNode(Call.getPtrArg(i).getNode());
+}
+
+// markExternalNodes - Traverse the graph, identifying nodes that may be
+// exposed to external code. The sources of this happening are:
+// --Arguments and return values for external functions
+// --Arguments and return values for externally visible functions
+//
+// FIXME: Unlike 'Incomplete' flag, the 'External' flag is never reset
+// and if done right should propagate throughout the various passes.
+// That is to say we can probably get away by not re-marking everything,
+// but instead placing just the right flag updates in just the right places.
+// However this is simpler and more likely to be correct--that kind of
+// optimization can wait until everything works correctly.
+void DSGraph::markExternalNodes() {
+ // Process all CallSites that call functions influenced by external code
+ for (std::list<DSCallSite>::iterator I = FunctionCalls.begin(),
+ E = FunctionCalls.end(); I != E; ++I) {
+ bool shouldBeMarkedExternal = false;
+
+ // Figure out what this callsite calls...
+ std::vector<const Function *> Functions;
+ if (I->isDirectCall())
+ Functions.push_back(I->getCalleeFunc());
+ else
+ I->getCalleeNode()->addFullFunctionList(Functions);
+
+ // ...And examine each callee:
+ for (std::vector<const Function *>::iterator II = Functions.begin(),
+ EE = Functions.end();
+ (II != EE) && !shouldBeMarkedExternal; ++II) {
+
+ // Calls to external functions should be marked external
+ shouldBeMarkedExternal |= (*II)->isDeclaration();
+ // Calls to code that is externally visible should be marked
+ // external. This might be overkill due to unification and the
+ // various passes propagating this information,
+ // but for now we /ensure/ the flags are set correctly.
+ shouldBeMarkedExternal |= !(*II)->hasInternalLinkage();
+ }
+
+ if (shouldBeMarkedExternal) {
+ markExternal(*I);
+ }
+ }
+
+ // Additionally, look at each *function* that is external-related
+ // and set the External flag for its arguments and return value.
+ for (ReturnNodesTy::iterator FI = ReturnNodes.begin(), E =ReturnNodes.end();
+ FI != E; ++FI) {
+ const Function &F = *FI->first;
+ // If this function is potentially influenced by external code...
+ if (!F.hasInternalLinkage() || F.isDeclaration()) {
+ // Mark its arguments, return value (and vanode) as external.
+ for (Function::const_arg_iterator I = F.arg_begin(), E = F.arg_end();
+ I != E; ++I)
+ if (isa<PointerType>(I->getType()))
+ markExternalNode(getNodeForValue(I).getNode());
+ markExternalNode(FI->second.getNode());
+ markExternalNode(getVANodeFor(F).getNode());
+ }
+ }
+}
+
static inline void killIfUselessEdge(DSNodeHandle &Edge) {
if (DSNode * N = Edge.getNode()) // Is there an edge?
if (N->getNumReferrers() == 1) // Does it point to a lonely node?
More information about the llvm-commits
mailing list