+ // Loop over all of the users of the function... looking for callers...
+ //
+ bool isUsedExternally = false;
+ for (Value::use_iterator I = F->use_begin(), E = F->use_end(); I != E; ++I){
+ if (Instruction *Inst = dyn_cast<Instruction>(*I)) {
+ CallSite CS = CallSite::get(Inst);
+ if (isOnlyADirectCall(F, CS))
+ getOrInsertFunction(Inst->getParent()->getParent())
+ ->addCalledFunction(CS, Node);
+ else
+ isUsedExternally = true;
+ } else if (GlobalValue *GV = dyn_cast<GlobalValue>(*I)) {
+ for (Value::use_iterator I = GV->use_begin(), E = GV->use_end();
+ I != E; ++I)
+ if (Instruction *Inst = dyn_cast<Instruction>(*I)) {
+ CallSite CS = CallSite::get(Inst);
+ if (isOnlyADirectCall(F, CS))
+ getOrInsertFunction(Inst->getParent()->getParent())
+ ->addCalledFunction(CS, Node);
+ else
+ isUsedExternally = true;
+ } else {
+ isUsedExternally = true;
+ }
+ } else { // Can't classify the user!
+ isUsedExternally = true;
+ }
+ }
+ if (isUsedExternally)
+ ExternalCallingNode->addCalledFunction(CallSite(), Node);
+
+ // Look for an indirect function call.
+ for (Function::iterator BB = F->begin(), BBE = F->end(); BB != BBE; ++BB)
+ for (BasicBlock::iterator II = BB->begin(), IE = BB->end();
+ II != IE; ++II) {
+ CallSite CS = CallSite::get(II);
+ if (CS.getInstruction() && !CS.getCalledFunction())
+ Node->addCalledFunction(CS, CallsExternalNode);
+ }
+ }
+
+ //
+ // destroy - Release memory for the call graph
+ virtual void destroy() {
+ if (!CallsExternalNode) {
+ delete CallsExternalNode;
+ CallsExternalNode = 0;
+ }
+ }
+};
+
+RegisterAnalysisGroup<CallGraph> X("Call Graph");
+RegisterPass<BasicCallGraph> Y("basiccg", "Basic CallGraph Construction");
+RegisterAnalysisGroup<CallGraph, true> Z(Y);
+
+} //End anonymous namespace
+
+void CallGraph::initialize(Module &M) {
+ destroy();
+ Mod = &M;