static void addCustomGraphFeatures(SelectionDAG *G, GraphWriter<SelectionDAG*> &GW) { GW.emitSimpleNode(0, "plaintext=circle", "GraphRoot"); if (G->getRoot().getNode()) GW.emitEdge(0, -1, G->getRoot().getNode(), G->getRoot().getResNo(), "color=blue,style=dashed"); }
void ScheduleDAGSDNodes::getCustomGraphFeatures(GraphWriter<ScheduleDAG*> &GW) const { if (DAG) { // Draw a special "GraphRoot" node to indicate the root of the graph. GW.emitSimpleNode(0, "plaintext=circle", "GraphRoot"); const SDNode *N = DAG->getRoot().getNode(); if (N && N->getNodeId() != -1) GW.emitEdge(0, -1, &SUnits[N->getNodeId()], -1, "color=blue,style=dashed"); } }
static void addCustomGraphFeatures(SelectionDAG *G, GraphWriter<SelectionDAG*> &GW) { GW.emitSimpleNode(0, "plaintext=circle", "GraphRoot"); if (G->getRoot().Val) GW.emitEdge(0, -1, G->getRoot().Val, -1, ""); }
/// 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"); } } }