return I;
}
+ /// hasEdgeDestLabels - If this function returns true, the graph is able
+ /// to provide labels for edge destinations.
+ static bool hasEdgeDestLabels() {
+ return false;
+ }
+
+ /// numEdgeDestLabels - If hasEdgeDestLabels, this function returns the
+ /// number of incoming edge labels the given node has.
+ static unsigned numEdgeDestLabels(const void *Node) {
+ return 0;
+ }
+
+ /// getEdgeDestLabel - If hasEdgeDestLabels, this function returns the
+ /// incoming edge label with the given index in the given node.
+ static std::string getEdgeDestLabel(const void *Node, unsigned i) {
+ return "";
+ }
+
/// addCustomGraphFeatures - If a graph is made up of more than just
/// straight-forward nodes and edges, this is the place to put all of the
/// custom stuff necessary. The GraphWriter object, instantiated with your
for (unsigned i = 0; EI != EE && i != 64; ++EI, ++i) {
if (i) O << "|";
- O << "<g" << i << ">" << DOTTraits::getEdgeSourceLabel(Node, EI);
+ O << "<s" << i << ">" << DOTTraits::getEdgeSourceLabel(Node, EI);
}
if (EI != EE)
- O << "|<g64>truncated...";
+ O << "|<s64>truncated...";
O << "}";
if (DOTTraits::renderGraphFromBottomUp()) O << "|";
}
O << "|" << (void*)Node;
}
+ if (DOTTraits::hasEdgeDestLabels()) {
+ O << "|{";
+
+ unsigned i = 0, e = DOTTraits::numEdgeDestLabels(Node);
+ for (; i != e && i != 64; ++i) {
+ if (i) O << "|";
+ O << "<d" << i << ">" << DOTTraits::getEdgeDestLabel(Node, i);
+ }
+
+ if (i != e)
+ O << "|<d64>truncated...";
+ O << "}";
+ }
+
O << "}\"];\n"; // Finish printing the "node" line
// Output all of the edges now
O << "\tNode" << SrcNodeID;
if (SrcNodePort >= 0)
- O << ":g" << SrcNodePort;
+ O << ":s" << SrcNodePort;
O << " -> Node" << reinterpret_cast<const void*>(DestNodeID);
if (DestNodePort >= 0)
- O << ":g" << DestNodePort;
+ O << ":d" << DestNodePort;
if (!Attrs.empty())
O << "[" << Attrs << "]";
namespace llvm {
template<>
struct DOTGraphTraits<SelectionDAG*> : public DefaultDOTGraphTraits {
+ static bool hasEdgeDestLabels() {
+ return true;
+ }
+
+ static unsigned numEdgeDestLabels(const void *Node) {
+ return ((const SDNode *) Node)->getNumValues();
+ }
+
+ static std::string getEdgeDestLabel(const void *Node, unsigned i) {
+ return ((const SDNode *) Node)->getValueType(i).getMVTString();
+ }
+
+ /// 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.
+ template<typename EdgeIter>
+ static bool edgeTargetsEdgeSource(const void *Node, EdgeIter I) {
+ return true;
+ }
+
+ /// getEdgeTarget - If edgeTargetsEdgeSource returns true, this method is
+ /// called to determine which outgoing edge of Node is the target of this
+ /// edge.
+ template<typename EdgeIter>
+ static EdgeIter getEdgeTarget(const void *Node, EdgeIter I) {
+ SDNode *TargetNode = *I;
+ SDNodeIterator NI = SDNodeIterator::begin(TargetNode);
+ std::advance(NI, I.getNode()->getOperand(I.getOperand()).ResNo);
+ return NI;
+ }
+
static std::string getGraphName(const SelectionDAG *G) {
return G->getMachineFunction().getFunction()->getName();
}
const SelectionDAG *G) {
std::string Op = Node->getOperationName(G);
- for (unsigned i = 0, e = Node->getNumValues(); i != e; ++i)
- if (Node->getValueType(i) == MVT::Other)
- Op += ":ch";
- else
- Op = Op + ":" + Node->getValueType(i).getMVTString();
-
if (const ConstantSDNode *CSDN = dyn_cast<ConstantSDNode>(Node)) {
Op += ": " + utostr(CSDN->getValue());
} else if (const ConstantFPSDNode *CSDN = dyn_cast<ConstantFPSDNode>(Node)) {