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"); } }
void ProgramState::exportCurrentGraph(string outputPath) { GraphWriter *graphWriter = new GraphWriter(); if (isWeighted()) { graphWriter->writeWeightedGraph(&(this->weightedGraph), outputPath); } else if (isDigraph()) { graphWriter->writeDirectedGraph(&(this->directedGraph), outputPath); } else { graphWriter->writeGraph(&(this->graph), outputPath); } delete graphWriter; }
// Print the cluster of the subregions. This groups the single basic blocks // and adds a different background color for each group. static void printRegionCluster(const Region &R, GraphWriter<RegionInfo *> &GW, unsigned depth = 0) { raw_ostream &O = GW.getOStream(); O.indent(2 * depth) << "subgraph cluster_" << static_cast<const void*>(&R) << " {\n"; O.indent(2 * (depth + 1)) << "label = \"\";\n"; if (!onlySimpleRegions || R.isSimple()) { O.indent(2 * (depth + 1)) << "style = filled;\n"; O.indent(2 * (depth + 1)) << "color = " << ((R.getDepth() * 2 % 12) + 1) << "\n"; } else { O.indent(2 * (depth + 1)) << "style = solid;\n"; O.indent(2 * (depth + 1)) << "color = " << ((R.getDepth() * 2 % 12) + 2) << "\n"; } for (Region::const_iterator RI = R.begin(), RE = R.end(); RI != RE; ++RI) printRegionCluster(**RI, GW, depth + 1); const RegionInfo &RI = *static_cast<const RegionInfo*>(R.getRegionInfo()); for (auto *BB : R.blocks()) if (RI.getRegionFor(BB) == &R) O.indent(2 * (depth + 1)) << "Node" << static_cast<const void*>(RI.getTopLevelRegion()->getBBNode(BB)) << ";\n"; O.indent(2 * depth) << "}\n"; }
// Print the cluster of the subregions. This groups the single basic blocks // and adds a different background color for each group. static void printRegionCluster(const Region *R, GraphWriter<RegionInfo*> &GW, unsigned depth = 0) { raw_ostream &O = GW.getOStream(); O.indent(2 * depth) << "subgraph cluster_" << static_cast<const void*>(R) << " {\n"; O.indent(2 * (depth + 1)) << "label = \"\";\n"; if (!onlySimpleRegions || R->isSimple()) { O.indent(2 * (depth + 1)) << "style = filled;\n"; O.indent(2 * (depth + 1)) << "color = " << ((R->getDepth() * 2 % 12) + 1) << "\n"; } else { O.indent(2 * (depth + 1)) << "style = solid;\n"; O.indent(2 * (depth + 1)) << "color = " << ((R->getDepth() * 2 % 12) + 2) << "\n"; } for (Region::const_iterator RI = R->begin(), RE = R->end(); RI != RE; ++RI) printRegionCluster(*RI, GW, depth + 1); RegionInfo *RI = R->getRegionInfo(); for (Region::const_block_iterator BI = R->block_begin(), BE = R->block_end(); BI != BE; ++BI) if (RI->getRegionFor(*BI) == R) O.indent(2 * (depth + 1)) << "Node" << static_cast<const void*>(RI->getTopLevelRegion()->getBBNode(*BI)) << ";\n"; O.indent(2 * depth) << "}\n"; }
static void addCustomGraphFeatures(const RegionInfo *G, GraphWriter<RegionInfo *> &GW) { raw_ostream &O = GW.getOStream(); O << "\tcolorscheme = \"paired12\"\n"; printRegionCluster(*G->getTopLevelRegion(), GW, 4); }
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, ""); }
static void addCustomGraphFeatures(const ScopDetection *SD, GraphWriter<ScopDetection *> &GW) { raw_ostream &O = GW.getOStream(); O << "\tcolorscheme = \"paired12\"\n"; printRegionCluster(SD, SD->getRI()->getTopLevelRegion(), O, 4); }
/// 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"); } } }