Changes in directory llvm/lib/Analysis/DataStructure:
CallTargets.cpp added (r1.1)
---
Log message:
move calltarget to dsa
---
Diffs of the changes: (+125 -0)
CallTargets.cpp | 125
1 files changed, 125 insertions(+)
Index: llvm/lib/Analysis/DataStructure/CallTargets.cpp
diff -c /dev/null llvm/lib/Analysis/DataStructure/CallTargets.cpp:1.1
*** /dev/null Mon May 29 18:39:58 2006
--- llvm/lib/Analysis/DataStructure/CallTargets.cpp Mon May 29 18:39:48 2006
***
*** 0
--- 1,125
+ //=- lib/Analysis/IPA/CallTargets.cpp - Resolve Call Targets --*- C++
-*-=//
+ //
+ // The LLVM Compiler Infrastructure
+ //
+ // This file was developed by the LLVM research group and is distributed under
+ // the University of Illinois Open Source License. See LICENSE.TXT for
details.
+ //
+
//===--===//
+ //
+ // This pass uses DSA to map targets of all calls, and reports on if it
+ // thinks it knows all targets of a given call.
+ //
+ // Loop over all callsites, and lookup the DSNode for that site. Pull the
+ // Functions from the node as callees.
+ // This is essentially a utility pass to simplify later passes that only
depend
+ // on call sites and callees to operate (such as a devirtualizer).
+ //
+
//===--===//
+
+ #include llvm/Module.h
+ #include llvm/Instructions.h
+ #include llvm/Analysis/DataStructure/DataStructure.h
+ #include llvm/Analysis/DataStructure/DSGraph.h
+ #include llvm/Analysis/CallTargets.h
+ #include llvm/ADT/Statistic.h
+ #include iostream
+ #include llvm/Constants.h
+
+ using namespace llvm;
+
+ namespace {
+ Statistic DirCall(calltarget, Number of direct calls);
+ Statistic IndCall(calltarget, Number of indirect calls);
+ Statistic CompleteInd(calltarget, Number of complete indirect calls);
+ Statistic CompleteEmpty(calltarget, Number of complete empty calls);
+
+ RegisterAnalysisCallTargetFinder X(calltarget, Find Call Targets (uses
DSA));
+ }
+
+ void CallTargetFinder::findIndTargets(Module M)
+ {
+ TDDataStructures* T = getAnalysisTDDataStructures();
+ for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
+ if (!I-isExternal())
+ for (Function::iterator F = I-begin(), FE = I-end(); F != FE; ++F)
+ for (BasicBlock::iterator B = F-begin(), BE = F-end(); B != BE; ++B)
+ if (isaCallInst(B) || isaInvokeInst(B)) {
+ CallSite cs = CallSite::get(B);
+ AllSites.push_back(cs);
+ if (!cs.getCalledFunction()) {
+ IndCall++;
+ DSNode* N = T-getDSGraph(*cs.getCaller())
+ .getNodeForValue(cs.getCalledValue()).getNode();
+ N-addFullFunctionList(IndMap[cs]);
+ if (N-isComplete() IndMap[cs].size()) {
+ CompleteSites.insert(cs);
+ ++CompleteInd;
+ }
+ if (N-isComplete() !IndMap[cs].size()) {
+ ++CompleteEmpty;
+ std::cerr Call site empty: '
cs.getInstruction()-getName()
+' In '
cs.getInstruction()-getParent()-getParent()-getName()
+'\n;
+ }
+ } else {
+ ++DirCall;
+ IndMap[cs].push_back(cs.getCalledFunction());
+ CompleteSites.insert(cs);
+ }
+ }
+ }
+
+ void CallTargetFinder::print(std::ostream O, const Module *M) const
+ {
+ return;
+ O [* = incomplete] CS: func list\n;
+ for (std::mapCallSite, std::vectorFunction* ::const_iterator ii =
IndMap.begin(),
+ ee = IndMap.end(); ii != ee; ++ii) {
+ if (!ii-first.getCalledFunction()) { //only print indirect
+ if (!isComplete(ii-first)) {
+ O * ;
+ CallSite cs = ii-first;
+ cs.getInstruction()-dump();
+ O cs.getInstruction()-getParent()-getParent()-getName()
+cs.getInstruction()-getName() ;
+ }
+ O ii-first.getInstruction() :;
+ for (std::vectorFunction*::const_iterator i = ii-second.begin(),
+ e = ii-second.end(); i != e; ++i) {
+ O (*i)-getName();
+ }
+ O \n;
+ }
+ }
+ }
+
+ bool CallTargetFinder::runOnModule(Module M) {
+ findIndTargets(M);
+ return false;
+ }
+
+ void CallTargetFinder::getAnalysisUsage(AnalysisUsage AU) const {
+ AU.setPreservesAll();
+ AU.addRequiredTDDataStructures();
+ }
+
+ std::vectorFunction*::iterator CallTargetFinder::begin(CallSite cs) {
+ return IndMap[cs].begin();
+ }
+
+ std::vectorFunction*::iterator CallTargetFinder::end(CallSite cs) {
+ return IndMap[cs].end();
+ }
+
+ bool CallTargetFinder::isComplete(CallSite cs) const {
+ return CompleteSites.find(cs) != CompleteSites.end();
+ }
+
+ std::listCallSite::iterator