// print_llvm - Print the specified LLVM chunk like an operand, called by // print-tree.c for tree dumps. // void print_llvm(FILE *file, void *LLVM) { oFILEstream FS(file); FS << "LLVM: "; WriteAsOperand(FS, (Value*)LLVM, true, TheModule); }
/// addCustomGraphFeatures - Use this graph writing hook to emit call nodes /// and the return node. /// static void addCustomGraphFeatures(const DSGraph *G, GraphWriter<const DSGraph*> &GW) { const Module *CurMod = 0; if (G->retnodes_begin() != G->retnodes_end()) CurMod = G->retnodes_begin()->first->getParent(); else { // If there is a global in the graph, we can use it to find the module. const DSScalarMap &SM = G->getScalarMap(); if (SM.global_begin() != SM.global_end()) CurMod = (*SM.global_begin())->getParent(); } if (!LimitPrint) { // Add scalar nodes to the graph... const DSGraph::ScalarMapTy &VM = G->getScalarMap(); for (DSGraph::ScalarMapTy::const_iterator I = VM.begin(); I != VM.end(); ++I) if (!isa<GlobalValue>(I->first)) { std::string OS_str; llvm::raw_string_ostream OS(OS_str); WriteAsOperand(OS, I->first, false, CurMod); GW.emitSimpleNode(I->first, "", OS.str()); // Add edge from return node to real destination DSNode *DestNode = I->second.getNode(); int EdgeDest = I->second.getOffset(); if (EdgeDest == 0) EdgeDest = -1; GW.emitEdge(I->first, -1, DestNode, EdgeDest, "arrowtail=tee,color=gray63"); } } // Output the returned value pointer... for (DSGraph::retnodes_iterator I = G->retnodes_begin(), E = G->retnodes_end(); I != E; ++I) if (I->second.getNode()) { std::string Label; if (G->getReturnNodes().size() == 1) Label = "returning"; else Label = I->first->getName().str() + " ret node"; // Output the return node... GW.emitSimpleNode(const_cast<Function*>(I->first), "plaintext=circle", Label); // Add edge from return node to real destination DSNode *RetNode = I->second.getNode(); int RetEdgeDest = I->second.getOffset(); if (RetEdgeDest == 0) RetEdgeDest = -1; GW.emitEdge(const_cast<Function*>(I->first), -1, RetNode, RetEdgeDest, "arrowtail=tee,color=gray63"); } // Output all of the call nodes... const DSGraph::FunctionListTy &FCs = G->shouldUseAuxCalls() ? G->getAuxFunctionCalls() : G->getFunctionCalls(); for (DSGraph::FunctionListTy::const_iterator I = FCs.begin(), E = FCs.end(); I != E; ++I) { const DSCallSite &Call = *I; std::vector<std::string> EdgeSourceCaptions(Call.getNumPtrArgs()+2); EdgeSourceCaptions[0] = "r"; if (Call.isDirectCall()) EdgeSourceCaptions[1] = Call.getCalleeFunc()->getName(); else EdgeSourceCaptions[1] = "f"; GW.emitSimpleNode(&Call, "shape=record", "call", Call.getNumPtrArgs()+2, &EdgeSourceCaptions); if (DSNode *N = Call.getRetVal().getNode()) { int EdgeDest = Call.getRetVal().getOffset(); if (EdgeDest == 0) EdgeDest = -1; GW.emitEdge(&Call, 0, N, EdgeDest, "color=gray63,tailclip=false"); } // FIXME: visualize the VANode? // 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,tailclip=false"); } for (unsigned j = 0, e = Call.getNumPtrArgs(); j != e; ++j) if (DSNode *N = Call.getPtrArg(j).getNode()) { int EdgeDest = Call.getPtrArg(j).getOffset(); if (EdgeDest == 0) EdgeDest = -1; GW.emitEdge(&Call, j+2, N, EdgeDest, "color=gray63,tailclip=false"); } } }