X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FSelectionDAG%2FSelectionDAGPrinter.cpp;h=76eb9453561e95242562a68c271eb1bf433a1c96;hb=29d8f0cae425f1bba583565227eaebf58f26ce73;hp=8e3247fb673e2c89a66c0ae4837ab2a11960a63e;hpb=aed48bfee87046f40330fc35d17265dd3aaf5dd5;p=oota-llvm.git diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp index 8e3247fb673..76eb9453561 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp @@ -11,27 +11,33 @@ // //===----------------------------------------------------------------------===// +#include "ScheduleDAGSDNodes.h" #include "llvm/Constants.h" #include "llvm/Function.h" #include "llvm/Assembly/Writer.h" #include "llvm/CodeGen/SelectionDAG.h" -#include "llvm/CodeGen/ScheduleDAG.h" #include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/PseudoSourceValue.h" +#include "llvm/Analysis/DebugInfo.h" #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/Support/Debug.h" #include "llvm/Support/GraphWriter.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Config/config.h" -#include using namespace llvm; namespace llvm { template<> struct DOTGraphTraits : public DefaultDOTGraphTraits { + + explicit DOTGraphTraits(bool isSimple=false) : + DefaultDOTGraphTraits(isSimple) {} + static bool hasEdgeDestLabels() { return true; } @@ -41,12 +47,17 @@ namespace llvm { } static std::string getEdgeDestLabel(const void *Node, unsigned i) { - return ((const SDNode *) Node)->getValueType(i).getMVTString(); + return ((const SDNode *) Node)->getValueType(i).getEVTString(); + } + + template + static std::string getEdgeSourceLabel(const void *Node, EdgeIter I) { + return itostr(I - SDNodeIterator::begin((SDNode *) Node)); } /// edgeTargetsEdgeSource - This method returns true if this outgoing edge - /// should actually target another edge source, not a node. If this method is - /// implemented, getEdgeTarget should be implemented. + /// should actually target another edge source, not a node. If this method + /// is implemented, getEdgeTarget should be implemented. template static bool edgeTargetsEdgeSource(const void *Node, EdgeIter I) { return true; @@ -70,28 +81,36 @@ namespace llvm { static bool renderGraphFromBottomUp() { return true; } - + static bool hasNodeAddressLabel(const SDNode *Node, const SelectionDAG *Graph) { return true; } - + /// If you want to override the dot attributes printed for a particular /// edge, override this method. template static std::string getEdgeAttributes(const void *Node, EdgeIter EI) { SDValue Op = EI.getNode()->getOperand(EI.getOperand()); - MVT VT = Op.getValueType(); - if (VT == MVT::Flag) + EVT VT = Op.getValueType(); + if (VT == MVT::Glue) return "color=red,style=bold"; else if (VT == MVT::Other) return "color=blue,style=dashed"; return ""; } - - static std::string getNodeLabel(const SDNode *Node, - const SelectionDAG *Graph); + + static std::string getSimpleNodeLabel(const SDNode *Node, + const SelectionDAG *G) { + std::string Result = Node->getOperationName(G); + { + raw_string_ostream OS(Result); + Node->print_details(OS, G); + } + return Result; + } + std::string getNodeLabel(const SDNode *Node, const SelectionDAG *Graph); static std::string getNodeAttributes(const SDNode *N, const SelectionDAG *Graph) { #ifndef NDEBUG @@ -118,136 +137,7 @@ namespace llvm { std::string DOTGraphTraits::getNodeLabel(const SDNode *Node, const SelectionDAG *G) { - std::string Op = Node->getOperationName(G); - - if (const ConstantSDNode *CSDN = dyn_cast(Node)) { - Op += ": " + utostr(CSDN->getZExtValue()); - } else if (const ConstantFPSDNode *CSDN = dyn_cast(Node)) { - Op += ": " + ftostr(CSDN->getValueAPF()); - } else if (const GlobalAddressSDNode *GADN = - dyn_cast(Node)) { - int offset = GADN->getOffset(); - Op += ": " + GADN->getGlobal()->getName(); - if (offset > 0) - Op += "+" + itostr(offset); - else - Op += itostr(offset); - } else if (const FrameIndexSDNode *FIDN = dyn_cast(Node)) { - Op += " " + itostr(FIDN->getIndex()); - } else if (const JumpTableSDNode *JTDN = dyn_cast(Node)) { - Op += " " + itostr(JTDN->getIndex()); - } else if (const ConstantPoolSDNode *CP = dyn_cast(Node)){ - if (CP->isMachineConstantPoolEntry()) { - Op += '<'; - { - raw_string_ostream OSS(Op); - OSS << *CP->getMachineCPVal(); - } - Op += '>'; - } else { - if (ConstantFP *CFP = dyn_cast(CP->getConstVal())) - Op += "<" + ftostr(CFP->getValueAPF()) + ">"; - else if (ConstantInt *CI = dyn_cast(CP->getConstVal())) - Op += "<" + utostr(CI->getZExtValue()) + ">"; - else { - Op += '<'; - { - raw_string_ostream OSS(Op); - WriteAsOperand(OSS, CP->getConstVal(), false); - } - Op += '>'; - } - } - Op += " A=" + itostr(1 << CP->getAlignment()); - } else if (const BasicBlockSDNode *BBDN = dyn_cast(Node)) { - Op = "BB: "; - const Value *LBB = (const Value*)BBDN->getBasicBlock()->getBasicBlock(); - if (LBB) - Op += LBB->getName(); - //Op += " " + (const void*)BBDN->getBasicBlock(); - } else if (const RegisterSDNode *R = dyn_cast(Node)) { - if (G && R->getReg() != 0 && - TargetRegisterInfo::isPhysicalRegister(R->getReg())) { - Op = Op + " " + - G->getTarget().getRegisterInfo()->getName(R->getReg()); - } else { - Op += " #" + utostr(R->getReg()); - } - } else if (const DbgStopPointSDNode *D = dyn_cast(Node)) { - Op += ": " + D->getCompileUnit()->getFileName(); - Op += ":" + utostr(D->getLine()); - if (D->getColumn() != 0) - Op += ":" + utostr(D->getColumn()); - } else if (const LabelSDNode *L = dyn_cast(Node)) { - Op += ": LabelID=" + utostr(L->getLabelID()); - } else if (const CallSDNode *C = dyn_cast(Node)) { - Op += ": CallingConv=" + utostr(C->getCallingConv()); - if (C->isVarArg()) - Op += ", isVarArg"; - if (C->isTailCall()) - Op += ", isTailCall"; - } else if (const SymbolSDNode *S = dyn_cast(Node)) { - Op += "'" + std::string(S->getSymbol()) + "'"; - } else if (const SrcValueSDNode *M = dyn_cast(Node)) { - if (M->getValue()) - Op += "<" + M->getValue()->getName() + ">"; - else - Op += ""; - } else if (const MemOperandSDNode *M = dyn_cast(Node)) { - const Value *V = M->MO.getValue(); - Op += '<'; - if (!V) { - Op += "(unknown)"; - } else if (isa(V)) { - // PseudoSourceValues don't have names, so use their print method. - { - raw_string_ostream OSS(Op); - OSS << *M->MO.getValue(); - } - } else { - Op += V->getName(); - } - Op += '+' + itostr(M->MO.getOffset()) + '>'; - } else if (const ARG_FLAGSSDNode *N = dyn_cast(Node)) { - Op = Op + " AF=" + N->getArgFlags().getArgFlagsString(); - } else if (const VTSDNode *N = dyn_cast(Node)) { - Op = Op + " VT=" + N->getVT().getMVTString(); - } else if (const LoadSDNode *LD = dyn_cast(Node)) { - bool doExt = true; - switch (LD->getExtensionType()) { - default: doExt = false; break; - case ISD::EXTLOAD: - Op = Op + "getMemoryVT().getMVTString() + ">"; - if (LD->isVolatile()) - Op += ""; - Op += LD->getIndexedModeName(LD->getAddressingMode()); - if (LD->getAlignment() > 1) - Op += " A=" + utostr(LD->getAlignment()); - } else if (const StoreSDNode *ST = dyn_cast(Node)) { - if (ST->isTruncatingStore()) - Op += "getMemoryVT().getMVTString() + ">"; - if (ST->isVolatile()) - Op += ""; - Op += ST->getIndexedModeName(ST->getAddressingMode()); - if (ST->getAlignment() > 1) - Op += " A=" + utostr(ST->getAlignment()); - } - -#if 0 - Op += " Id=" + itostr(Node->getNodeId()); -#endif - - return Op; + return DOTGraphTraits::getSimpleNodeLabel(Node, G); } @@ -257,11 +147,11 @@ std::string DOTGraphTraits::getNodeLabel(const SDNode *Node, void SelectionDAG::viewGraph(const std::string &Title) { // This code is only for debugging! #ifndef NDEBUG - ViewGraph(this, "dag." + getMachineFunction().getFunction()->getName(), - Title); + ViewGraph(this, "dag." + getMachineFunction().getFunction()->getNameStr(), + false, Title); #else - cerr << "SelectionDAG::viewGraph is only available in debug builds on " - << "systems with Graphviz or gv!\n"; + errs() << "SelectionDAG::viewGraph is only available in debug builds on " + << "systems with Graphviz or gv!\n"; #endif // NDEBUG } @@ -277,8 +167,8 @@ void SelectionDAG::clearGraphAttrs() { #ifndef NDEBUG NodeGraphAttrs.clear(); #else - cerr << "SelectionDAG::clearGraphAttrs is only available in debug builds" - << " on systems with Graphviz or gv!\n"; + errs() << "SelectionDAG::clearGraphAttrs is only available in debug builds" + << " on systems with Graphviz or gv!\n"; #endif } @@ -289,8 +179,8 @@ void SelectionDAG::setGraphAttrs(const SDNode *N, const char *Attrs) { #ifndef NDEBUG NodeGraphAttrs[N] = Attrs; #else - cerr << "SelectionDAG::setGraphAttrs is only available in debug builds" - << " on systems with Graphviz or gv!\n"; + errs() << "SelectionDAG::setGraphAttrs is only available in debug builds" + << " on systems with Graphviz or gv!\n"; #endif } @@ -301,15 +191,15 @@ const std::string SelectionDAG::getGraphAttrs(const SDNode *N) const { #ifndef NDEBUG std::map::const_iterator I = NodeGraphAttrs.find(N); - + if (I != NodeGraphAttrs.end()) return I->second; else return ""; #else - cerr << "SelectionDAG::getGraphAttrs is only available in debug builds" - << " on systems with Graphviz or gv!\n"; - return std::string(""); + errs() << "SelectionDAG::getGraphAttrs is only available in debug builds" + << " on systems with Graphviz or gv!\n"; + return std::string(); #endif } @@ -319,86 +209,93 @@ void SelectionDAG::setGraphColor(const SDNode *N, const char *Color) { #ifndef NDEBUG NodeGraphAttrs[N] = std::string("color=") + Color; #else - cerr << "SelectionDAG::setGraphColor is only available in debug builds" - << " on systems with Graphviz or gv!\n"; + errs() << "SelectionDAG::setGraphColor is only available in debug builds" + << " on systems with Graphviz or gv!\n"; #endif } -namespace llvm { - template<> - struct DOTGraphTraits : public DefaultDOTGraphTraits { - static std::string getGraphName(const ScheduleDAG *G) { - return DOTGraphTraits::getGraphName(&G->DAG); - } - - static bool renderGraphFromBottomUp() { - return true; - } - - static bool hasNodeAddressLabel(const SUnit *Node, - const ScheduleDAG *Graph) { - return true; - } - - /// If you want to override the dot attributes printed for a particular - /// edge, override this method. - template - static std::string getEdgeAttributes(const void *Node, EdgeIter EI) { - if (EI.isSpecialDep()) - return "color=cyan,style=dashed"; - if (EI.isCtrlDep()) - return "color=blue,style=dashed"; - return ""; - } - +/// setSubgraphColorHelper - Implement setSubgraphColor. Return +/// whether we truncated the search. +/// +bool SelectionDAG::setSubgraphColorHelper(SDNode *N, const char *Color, DenseSet &visited, + int level, bool &printed) { + bool hit_limit = false; - static std::string getNodeLabel(const SUnit *Node, - const ScheduleDAG *Graph); - static std::string getNodeAttributes(const SUnit *N, - const ScheduleDAG *Graph) { - return "shape=Mrecord"; +#ifndef NDEBUG + if (level >= 20) { + if (!printed) { + printed = true; + DEBUG(dbgs() << "setSubgraphColor hit max level\n"); } + return true; + } - static void addCustomGraphFeatures(ScheduleDAG *G, - GraphWriter &GW) { - GW.emitSimpleNode(0, "plaintext=circle", "GraphRoot"); - const SDNode *N = G->DAG.getRoot().getNode(); - if (N && N->getNodeId() != -1) - GW.emitEdge(0, -1, &G->SUnits[N->getNodeId()], -1, - "color=blue,style=dashed"); + unsigned oldSize = visited.size(); + visited.insert(N); + if (visited.size() != oldSize) { + setGraphColor(N, Color); + for(SDNodeIterator i = SDNodeIterator::begin(N), iend = SDNodeIterator::end(N); + i != iend; + ++i) { + hit_limit = setSubgraphColorHelper(*i, Color, visited, level+1, printed) || hit_limit; } - }; + } +#else + errs() << "SelectionDAG::setSubgraphColor is only available in debug builds" + << " on systems with Graphviz or gv!\n"; +#endif + return hit_limit; } -std::string DOTGraphTraits::getNodeLabel(const SUnit *SU, - const ScheduleDAG *G) { - std::string Op; - - for (unsigned i = 0; i < SU->FlaggedNodes.size(); ++i) { - Op += DOTGraphTraits::getNodeLabel(SU->FlaggedNodes[i], - &G->DAG) + "\n"; +/// setSubgraphColor - Convenience for setting subgraph color attribute. +/// +void SelectionDAG::setSubgraphColor(SDNode *N, const char *Color) { +#ifndef NDEBUG + DenseSet visited; + bool printed = false; + if (setSubgraphColorHelper(N, Color, visited, 0, printed)) { + // Visually mark that we hit the limit + if (strcmp(Color, "red") == 0) { + setSubgraphColorHelper(N, "blue", visited, 0, printed); + } else if (strcmp(Color, "yellow") == 0) { + setSubgraphColorHelper(N, "green", visited, 0, printed); + } } - if (SU->Node) - Op += DOTGraphTraits::getNodeLabel(SU->Node, &G->DAG); - else - Op += ""; - - return Op; +#else + errs() << "SelectionDAG::setSubgraphColor is only available in debug builds" + << " on systems with Graphviz or gv!\n"; +#endif } +std::string ScheduleDAGSDNodes::getGraphNodeLabel(const SUnit *SU) const { + std::string s; + raw_string_ostream O(s); + O << "SU(" << SU->NodeNum << "): "; + if (SU->getNode()) { + SmallVector GluedNodes; + for (SDNode *N = SU->getNode(); N; N = N->getGluedNode()) + GluedNodes.push_back(N); + while (!GluedNodes.empty()) { + O << DOTGraphTraits + ::getSimpleNodeLabel(GluedNodes.back(), DAG); + GluedNodes.pop_back(); + if (!GluedNodes.empty()) + O << "\n "; + } + } else { + O << "CROSS RC COPY"; + } + return O.str(); +} -/// viewGraph - Pop up a ghostview window with the reachable parts of the DAG -/// rendered using 'dot'. -/// -void ScheduleDAG::viewGraph() { -// This code is only for debugging! -#ifndef NDEBUG - ViewGraph(this, "dag." + MF->getFunction()->getName(), - "Scheduling-Units Graph for " + MF->getFunction()->getName() + ':' + - BB->getBasicBlock()->getName()); -#else - cerr << "ScheduleDAG::viewGraph is only available in debug builds on " - << "systems with Graphviz or gv!\n"; -#endif // NDEBUG +void ScheduleDAGSDNodes::getCustomGraphFeatures(GraphWriter &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"); + } }