10b57cec5SDimitry Andric //===-- ScheduleDAGPrinter.cpp - Implement ScheduleDAG::viewGraph() -------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This implements the ScheduleDAG::viewGraph method.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
140b57cec5SDimitry Andric #include "llvm/CodeGen/ScheduleDAG.h"
150b57cec5SDimitry Andric #include "llvm/Support/GraphWriter.h"
160b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
170b57cec5SDimitry Andric using namespace llvm;
180b57cec5SDimitry Andric
190b57cec5SDimitry Andric namespace llvm {
200b57cec5SDimitry Andric template<>
210b57cec5SDimitry Andric struct DOTGraphTraits<ScheduleDAG*> : public DefaultDOTGraphTraits {
220b57cec5SDimitry Andric
DOTGraphTraitsllvm::DOTGraphTraits230b57cec5SDimitry Andric DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {}
240b57cec5SDimitry Andric
getGraphNamellvm::DOTGraphTraits250b57cec5SDimitry Andric static std::string getGraphName(const ScheduleDAG *G) {
265ffd83dbSDimitry Andric return std::string(G->MF.getName());
270b57cec5SDimitry Andric }
280b57cec5SDimitry Andric
renderGraphFromBottomUpllvm::DOTGraphTraits290b57cec5SDimitry Andric static bool renderGraphFromBottomUp() {
300b57cec5SDimitry Andric return true;
310b57cec5SDimitry Andric }
320b57cec5SDimitry Andric
isNodeHiddenllvm::DOTGraphTraits33*e8d8bef9SDimitry Andric static bool isNodeHidden(const SUnit *Node, const ScheduleDAG *G) {
340b57cec5SDimitry Andric return (Node->NumPreds > 10 || Node->NumSuccs > 10);
350b57cec5SDimitry Andric }
360b57cec5SDimitry Andric
getNodeIdentifierLabelllvm::DOTGraphTraits370b57cec5SDimitry Andric static std::string getNodeIdentifierLabel(const SUnit *Node,
380b57cec5SDimitry Andric const ScheduleDAG *Graph) {
390b57cec5SDimitry Andric std::string R;
400b57cec5SDimitry Andric raw_string_ostream OS(R);
410b57cec5SDimitry Andric OS << static_cast<const void *>(Node);
420b57cec5SDimitry Andric return R;
430b57cec5SDimitry Andric }
440b57cec5SDimitry Andric
450b57cec5SDimitry Andric /// If you want to override the dot attributes printed for a particular
460b57cec5SDimitry Andric /// edge, override this method.
getEdgeAttributesllvm::DOTGraphTraits470b57cec5SDimitry Andric static std::string getEdgeAttributes(const SUnit *Node,
480b57cec5SDimitry Andric SUnitIterator EI,
490b57cec5SDimitry Andric const ScheduleDAG *Graph) {
500b57cec5SDimitry Andric if (EI.isArtificialDep())
510b57cec5SDimitry Andric return "color=cyan,style=dashed";
520b57cec5SDimitry Andric if (EI.isCtrlDep())
530b57cec5SDimitry Andric return "color=blue,style=dashed";
540b57cec5SDimitry Andric return "";
550b57cec5SDimitry Andric }
560b57cec5SDimitry Andric
570b57cec5SDimitry Andric
580b57cec5SDimitry Andric std::string getNodeLabel(const SUnit *SU, const ScheduleDAG *Graph);
getNodeAttributesllvm::DOTGraphTraits590b57cec5SDimitry Andric static std::string getNodeAttributes(const SUnit *N,
600b57cec5SDimitry Andric const ScheduleDAG *Graph) {
610b57cec5SDimitry Andric return "shape=Mrecord";
620b57cec5SDimitry Andric }
630b57cec5SDimitry Andric
addCustomGraphFeaturesllvm::DOTGraphTraits640b57cec5SDimitry Andric static void addCustomGraphFeatures(ScheduleDAG *G,
650b57cec5SDimitry Andric GraphWriter<ScheduleDAG*> &GW) {
660b57cec5SDimitry Andric return G->addCustomGraphFeatures(GW);
670b57cec5SDimitry Andric }
680b57cec5SDimitry Andric };
690b57cec5SDimitry Andric }
700b57cec5SDimitry Andric
getNodeLabel(const SUnit * SU,const ScheduleDAG * G)710b57cec5SDimitry Andric std::string DOTGraphTraits<ScheduleDAG*>::getNodeLabel(const SUnit *SU,
720b57cec5SDimitry Andric const ScheduleDAG *G) {
730b57cec5SDimitry Andric return G->getGraphNodeLabel(SU);
740b57cec5SDimitry Andric }
750b57cec5SDimitry Andric
760b57cec5SDimitry Andric /// viewGraph - Pop up a ghostview window with the reachable parts of the DAG
770b57cec5SDimitry Andric /// rendered using 'dot'.
780b57cec5SDimitry Andric ///
viewGraph(const Twine & Name,const Twine & Title)790b57cec5SDimitry Andric void ScheduleDAG::viewGraph(const Twine &Name, const Twine &Title) {
800b57cec5SDimitry Andric // This code is only for debugging!
810b57cec5SDimitry Andric #ifndef NDEBUG
820b57cec5SDimitry Andric ViewGraph(this, Name, false, Title);
830b57cec5SDimitry Andric #else
840b57cec5SDimitry Andric errs() << "ScheduleDAG::viewGraph is only available in debug builds on "
850b57cec5SDimitry Andric << "systems with Graphviz or gv!\n";
860b57cec5SDimitry Andric #endif // NDEBUG
870b57cec5SDimitry Andric }
880b57cec5SDimitry Andric
890b57cec5SDimitry Andric /// Out-of-line implementation with no arguments is handy for gdb.
viewGraph()900b57cec5SDimitry Andric void ScheduleDAG::viewGraph() {
910b57cec5SDimitry Andric viewGraph(getDAGName(), "Scheduling-Units Graph for " + getDAGName());
920b57cec5SDimitry Andric }
93