[llvm-commits] CVS: llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp DataStructure.cpp DataStructureStats.cpp Local.cpp Printer.cpp Steensgaard.cpp TopDownClosure.cpp
Chris Lattner
lattner at cs.uiuc.edu
Wed Feb 5 16:01:01 PST 2003
Changes in directory llvm/lib/Analysis/DataStructure:
BottomUpClosure.cpp updated: 1.51 -> 1.52
DataStructure.cpp updated: 1.86 -> 1.87
DataStructureStats.cpp updated: 1.2 -> 1.3
Local.cpp updated: 1.46 -> 1.47
Printer.cpp updated: 1.46 -> 1.47
Steensgaard.cpp updated: 1.19 -> 1.20
TopDownClosure.cpp updated: 1.35 -> 1.36
---
Log message:
Implement optimization for direct function call case. This dramatically
reduces the number of function nodes created and speeds up analysis by
about 10% overall.
---
Diffs of the changes:
Index: llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp
diff -u llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.51 llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.52
--- llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.51 Mon Feb 3 13:11:38 2003
+++ llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp Wed Feb 5 15:59:56 2003
@@ -22,6 +22,13 @@
using namespace DS;
+static bool isVAHackFn(const Function *F) {
+ return F->getName() == "printf" || F->getName() == "sscanf" ||
+ F->getName() == "fprintf" || F->getName() == "open" ||
+ F->getName() == "sprintf" || F->getName() == "fputs" ||
+ F->getName() == "fscanf";
+}
+
// isCompleteNode - Return true if we know all of the targets of this node, and
// if the call sites are not external.
//
@@ -29,14 +36,9 @@
if (N->NodeType & DSNode::Incomplete) return false;
const std::vector<GlobalValue*> &Callees = N->getGlobals();
for (unsigned i = 0, e = Callees.size(); i != e; ++i)
- if (Callees[i]->isExternal()) {
- GlobalValue &FI = cast<Function>(*Callees[i]);
- if (FI.getName() != "printf" && FI.getName() != "sscanf" &&
- FI.getName() != "fprintf" && FI.getName() != "open" &&
- FI.getName() != "sprintf" && FI.getName() != "fputs" &&
- FI.getName() != "fscanf")
+ if (Callees[i]->isExternal())
+ if (!isVAHackFn(cast<Function>(Callees[i])))
return false; // External function found...
- }
return true; // otherwise ok
}
@@ -48,7 +50,7 @@
CallSiteIterator(std::vector<DSCallSite> &CS) : FCs(&CS) {
CallSite = 0; CallSiteEntry = 0;
- advanceToNextValid();
+ advanceToValidCallee();
}
// End iterator ctor...
@@ -56,18 +58,24 @@
CallSite = FCs->size(); CallSiteEntry = 0;
}
- void advanceToNextValid() {
+ void advanceToValidCallee() {
while (CallSite < FCs->size()) {
- if (DSNode *CalleeNode = (*FCs)[CallSite].getCallee().getNode()) {
+ if ((*FCs)[CallSite].isDirectCall()) {
+ if (CallSiteEntry == 0 && // direct call only has one target...
+ (!(*FCs)[CallSite].getCalleeFunc()->isExternal() ||
+ isVAHackFn((*FCs)[CallSite].getCalleeFunc()))) // If not external
+ return;
+ } else {
+ DSNode *CalleeNode = (*FCs)[CallSite].getCalleeNode();
if (CallSiteEntry || isCompleteNode(CalleeNode)) {
const std::vector<GlobalValue*> &Callees = CalleeNode->getGlobals();
if (CallSiteEntry < Callees.size())
return;
}
- CallSiteEntry = 0;
- ++CallSite;
}
+ CallSiteEntry = 0;
+ ++CallSite;
}
}
public:
@@ -87,14 +95,18 @@
unsigned getCallSiteIdx() const { return CallSite; }
DSCallSite &getCallSite() const { return (*FCs)[CallSite]; }
- Function* operator*() const {
- DSNode *Node = (*FCs)[CallSite].getCallee().getNode();
- return cast<Function>(Node->getGlobals()[CallSiteEntry]);
+ Function *operator*() const {
+ if ((*FCs)[CallSite].isDirectCall()) {
+ return (*FCs)[CallSite].getCalleeFunc();
+ } else {
+ DSNode *Node = (*FCs)[CallSite].getCalleeNode();
+ return cast<Function>(Node->getGlobals()[CallSiteEntry]);
+ }
}
CallSiteIterator& operator++() { // Preincrement
++CallSiteEntry;
- advanceToNextValid();
+ advanceToValidCallee();
return *this;
}
CallSiteIterator operator++(int) { // Postincrement
Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp
diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.86 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.87
--- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.86 Mon Feb 3 18:03:04 2003
+++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Wed Feb 5 15:59:56 2003
@@ -799,7 +799,8 @@
std::sort(Calls.begin(), Calls.end()); // Sort by callee as primary key!
// Scan the call list cleaning it up as necessary...
- DSNode *LastCalleeNode = 0;
+ DSNode *LastCalleeNode = 0;
+ Function *LastCalleeFunc = 0;
unsigned NumDuplicateCalls = 0;
bool LastCalleeContainsExternalFunction = false;
for (unsigned i = 0; i != Calls.size(); ++i) {
@@ -807,8 +808,9 @@
// If the Callee is a useless edge, this must be an unreachable call site,
// eliminate it.
- killIfUselessEdge(CS.getCallee());
- if (CS.getCallee().getNode() == 0) {
+ if (CS.isIndirectCall() && CS.getCalleeNode()->getReferrers().size() == 1 &&
+ CS.getCalleeNode()->NodeType == 0) { // No useful info?
+ std::cerr << "WARNING: Useless call site found??\n";
CS.swap(Calls.back());
Calls.pop_back();
--i;
@@ -826,11 +828,15 @@
// never be resolved. Merge the arguments of the call node because no
// information will be lost.
//
- if (CS.getCallee().getNode() == LastCalleeNode) {
+ if ((CS.isDirectCall() && CS.getCalleeFunc() == LastCalleeFunc) ||
+ (CS.isIndirectCall() && CS.getCalleeNode() == LastCalleeNode)) {
++NumDuplicateCalls;
if (NumDuplicateCalls == 1) {
- LastCalleeContainsExternalFunction =
- nodeContainsExternalFunction(LastCalleeNode);
+ if (LastCalleeNode)
+ LastCalleeContainsExternalFunction =
+ nodeContainsExternalFunction(LastCalleeNode);
+ else
+ LastCalleeContainsExternalFunction = LastCalleeFunc->isExternal();
}
if (LastCalleeContainsExternalFunction ||
@@ -847,7 +853,13 @@
OCS = CS;
}
} else {
- LastCalleeNode = CS.getCallee().getNode();
+ if (CS.isDirectCall()) {
+ LastCalleeFunc = CS.getCalleeFunc();
+ LastCalleeNode = 0;
+ } else {
+ LastCalleeNode = CS.getCalleeNode();
+ LastCalleeFunc = 0;
+ }
NumDuplicateCalls = 0;
}
}
@@ -877,7 +889,7 @@
for (unsigned i = 0; i != Nodes.size(); ++i) {
DSNode *Node = Nodes[i];
if (!(Node->NodeType & ~(DSNode::Composition | DSNode::Array |
- DSNode::DEAD))) {
+ DSNode::DEAD))) {
// This is a useless node if it has no mod/ref info (checked above),
// outgoing edges (which it cannot, as it is not modified in this
// context), and it has no incoming edges. If it is a global node it may
@@ -918,7 +930,7 @@
void DSCallSite::markReachableNodes(hash_set<DSNode*> &Nodes) {
getRetVal().getNode()->markReachableNodes(Nodes);
- getCallee().getNode()->markReachableNodes(Nodes);
+ if (isIndirectCall()) getCalleeNode()->markReachableNodes(Nodes);
for (unsigned i = 0, e = getNumPtrArgs(); i != e; ++i)
getPtrArg(i).getNode()->markReachableNodes(Nodes);
@@ -954,8 +966,10 @@
//
static bool CallSiteUsesAliveArgs(DSCallSite &CS, hash_set<DSNode*> &Alive,
hash_set<DSNode*> &Visited) {
- if (CanReachAliveNodes(CS.getRetVal().getNode(), Alive, Visited) ||
- CanReachAliveNodes(CS.getCallee().getNode(), Alive, Visited))
+ if (CanReachAliveNodes(CS.getRetVal().getNode(), Alive, Visited))
+ return true;
+ if (CS.isIndirectCall() &&
+ CanReachAliveNodes(CS.getCalleeNode(), Alive, Visited))
return true;
for (unsigned i = 0, e = CS.getNumPtrArgs(); i != e; ++i)
if (CanReachAliveNodes(CS.getPtrArg(i).getNode(), Alive, Visited))
Index: llvm/lib/Analysis/DataStructure/DataStructureStats.cpp
diff -u llvm/lib/Analysis/DataStructure/DataStructureStats.cpp:1.2 llvm/lib/Analysis/DataStructure/DataStructureStats.cpp:1.3
--- llvm/lib/Analysis/DataStructure/DataStructureStats.cpp:1.2 Sun Nov 17 16:17:12 2002
+++ llvm/lib/Analysis/DataStructure/DataStructureStats.cpp Wed Feb 5 15:59:56 2003
@@ -48,9 +48,7 @@
}
-void DSGraphStats::countCallees(const Function& F,
- const DSGraph& tdGraph)
-{
+void DSGraphStats::countCallees(const Function& F, const DSGraph& tdGraph) {
unsigned numIndirectCalls = 0, totalNumCallees = 0;
const std::vector<DSCallSite>& callSites = tdGraph.getFunctionCalls();
@@ -58,12 +56,11 @@
if (isIndirectCallee(callSites[i].getCallInst().getCalledValue()))
{ // This is an indirect function call
std::vector<GlobalValue*> Callees =
- callSites[i].getCallee().getNode()->getGlobals();
- if (Callees.size() > 0)
- {
- totalNumCallees += Callees.size();
- ++numIndirectCalls;
- }
+ callSites[i].getCalleeNode()->getGlobals();
+ if (Callees.size() > 0) {
+ totalNumCallees += Callees.size();
+ ++numIndirectCalls;
+ }
#ifndef NDEBUG
else
std::cerr << "WARNING: No callee in Function " << F.getName()
@@ -81,8 +78,7 @@
}
-bool DSGraphStats::runOnFunction(Function& F)
-{
+bool DSGraphStats::runOnFunction(Function& F) {
const DSGraph& tdGraph = getAnalysis<TDDataStructures>().getDSGraph(F);
countCallees(F, tdGraph);
return true;
Index: llvm/lib/Analysis/DataStructure/Local.cpp
diff -u llvm/lib/Analysis/DataStructure/Local.cpp:1.46 llvm/lib/Analysis/DataStructure/Local.cpp:1.47
--- llvm/lib/Analysis/DataStructure/Local.cpp:1.46 Mon Feb 3 18:59:50 2003
+++ llvm/lib/Analysis/DataStructure/Local.cpp Wed Feb 5 15:59:56 2003
@@ -19,6 +19,7 @@
#include "llvm/Target/TargetData.h"
#include "Support/Statistic.h"
#include "Support/Timer.h"
+#include "Support/CommandLine.h"
// FIXME: This should eventually be a FunctionPass that is automatically
// aggregated into a Pass.
@@ -45,6 +46,11 @@
namespace {
+ cl::opt<bool>
+ DisableDirectCallOpt("disable-direct-call-dsopt", cl::Hidden,
+ cl::desc("Disable direct call optimization in "
+ "DSGraph construction"));
+
//===--------------------------------------------------------------------===//
// GraphBuilder Class
//===--------------------------------------------------------------------===//
@@ -375,7 +381,9 @@
if (isPointerType(CI.getType()))
RetVal = getValueDest(CI);
- DSNodeHandle Callee = getValueDest(*CI.getOperand(0));
+ DSNode *Callee = 0;
+ if (DisableDirectCallOpt || !isa<Function>(CI.getOperand(0)))
+ Callee = getValueDest(*CI.getOperand(0)).getNode();
std::vector<DSNodeHandle> Args;
Args.reserve(CI.getNumOperands()-1);
@@ -386,7 +394,11 @@
Args.push_back(getValueDest(*CI.getOperand(i)));
// Add a new function call entry...
- FunctionCalls.push_back(DSCallSite(CI, RetVal, Callee, Args));
+ if (Callee)
+ FunctionCalls.push_back(DSCallSite(CI, RetVal, Callee, Args));
+ else
+ FunctionCalls.push_back(DSCallSite(CI, RetVal,
+ cast<Function>(CI.getOperand(0)), Args));
}
void GraphBuilder::visitFreeInst(FreeInst &FI) {
Index: llvm/lib/Analysis/DataStructure/Printer.cpp
diff -u llvm/lib/Analysis/DataStructure/Printer.cpp:1.46 llvm/lib/Analysis/DataStructure/Printer.cpp:1.47
--- llvm/lib/Analysis/DataStructure/Printer.cpp:1.46 Mon Feb 3 18:03:18 2003
+++ llvm/lib/Analysis/DataStructure/Printer.cpp Wed Feb 5 15:59:56 2003
@@ -123,18 +123,27 @@
: G->getFunctionCalls();
for (unsigned i = 0, e = FCs.size(); i != e; ++i) {
const DSCallSite &Call = FCs[i];
- GW.emitSimpleNode(&Call, "shape=record", "call", Call.getNumPtrArgs()+2);
+ std::vector<std::string> EdgeSourceCaptions(Call.getNumPtrArgs()+2);
+ EdgeSourceCaptions[0] = "r";
+ if (Call.isDirectCall())
+ EdgeSourceCaptions[1] = Call.getCalleeFunc()->getName();
+
+ GW.emitSimpleNode(&Call, "shape=record", "call", Call.getNumPtrArgs()+2,
+ &EdgeSourceCaptions);
if (DSNode *N = Call.getRetVal().getNode()) {
int EdgeDest = Call.getRetVal().getOffset() >> DS::PointerShift;
if (EdgeDest == 0) EdgeDest = -1;
GW.emitEdge(&Call, 0, N, EdgeDest, "color=gray63");
}
- if (DSNode *N = Call.getCallee().getNode()) {
- int EdgeDest = Call.getCallee().getOffset() >> DS::PointerShift;
- if (EdgeDest == 0) EdgeDest = -1;
- GW.emitEdge(&Call, 1, N, EdgeDest, "color=gray63");
+
+ // Print out the callee...
+ if (Call.isIndirectCall()) {
+ DSNode *N = Call.getCalleeNode();
+ assert(N && "Null call site callee node!");
+ GW.emitEdge(&Call, 1, N, -1, "color=gray63");
}
+
for (unsigned j = 0, e = Call.getNumPtrArgs(); j != e; ++j)
if (DSNode *N = Call.getPtrArg(j).getNode()) {
int EdgeDest = Call.getPtrArg(j).getOffset() >> DS::PointerShift;
Index: llvm/lib/Analysis/DataStructure/Steensgaard.cpp
diff -u llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.19 llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.20
--- llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.19 Tue Feb 4 10:33:23 2003
+++ llvm/lib/Analysis/DataStructure/Steensgaard.cpp Wed Feb 5 15:59:56 2003
@@ -163,8 +163,12 @@
DSCallSite &CurCall = Calls[i];
// Loop over the called functions, eliminating as many as possible...
- std::vector<GlobalValue*> CallTargets =
- CurCall.getCallee().getNode()->getGlobals();
+ std::vector<GlobalValue*> CallTargets;
+ if (CurCall.isDirectCall())
+ CallTargets.push_back(CurCall.getCalleeFunc());
+ else
+ CallTargets = CurCall.getCalleeNode()->getGlobals();
+
for (unsigned c = 0; c != CallTargets.size(); ) {
// If we can eliminate this function call, do so!
bool Eliminated = false;
Index: llvm/lib/Analysis/DataStructure/TopDownClosure.cpp
diff -u llvm/lib/Analysis/DataStructure/TopDownClosure.cpp:1.35 llvm/lib/Analysis/DataStructure/TopDownClosure.cpp:1.36
--- llvm/lib/Analysis/DataStructure/TopDownClosure.cpp:1.35 Mon Feb 3 18:59:32 2003
+++ llvm/lib/Analysis/DataStructure/TopDownClosure.cpp Wed Feb 5 15:59:56 2003
@@ -116,17 +116,22 @@
std::multimap<Function*, const DSCallSite*> CalleeSites;
for (unsigned i = 0, e = CallSites.size(); i != e; ++i) {
const DSCallSite &CS = CallSites[i];
- const std::vector<GlobalValue*> Callees =
- CS.getCallee().getNode()->getGlobals();
+ if (CS.isDirectCall()) {
+ if (!CS.getCalleeFunc()->isExternal()) // If it's not external
+ CalleeSites.insert(std::make_pair(CS.getCalleeFunc(), &CS)); // Keep it
+ } else {
+ const std::vector<GlobalValue*> &Callees =
+ CS.getCalleeNode()->getGlobals();
- // Loop over all of the functions that this call may invoke...
- for (unsigned c = 0, e = Callees.size(); c != e; ++c)
- if (Function *F = dyn_cast<Function>(Callees[c])) // If this is a fn...
- if (!F->isExternal()) // If it's not external
- CalleeSites.insert(std::make_pair(F, &CS)); // Keep track of it!
+ // Loop over all of the functions that this call may invoke...
+ for (unsigned c = 0, e = Callees.size(); c != e; ++c)
+ if (Function *F = dyn_cast<Function>(Callees[c])) // If this is a fn...
+ if (!F->isExternal()) // If it's not extern
+ CalleeSites.insert(std::make_pair(F, &CS)); // Keep track of it!
+ }
}
- // Now that we have information about all of the callees, propogate the
+ // Now that we have information about all of the callees, propagate the
// current graph into the callees.
//
DEBUG(std::cerr << " [TD] Inlining '" << F.getName() << "' into "
More information about the llvm-commits
mailing list