/compiler/utils/GraphPpr.hs

https://github.com/pepeiborra/ghc · Haskell · 169 lines · 115 code · 42 blank · 12 comment · 4 complexity · 1eb046f2c48356dcb6e2c656e72173a0 MD5 · raw file

  1. -- | Pretty printing of graphs.
  2. module GraphPpr (
  3. dumpGraph,
  4. dotGraph
  5. )
  6. where
  7. import GraphBase
  8. import Outputable
  9. import Unique
  10. import UniqSet
  11. import UniqFM
  12. import Data.List
  13. import Data.Maybe
  14. -- | Pretty print a graph in a somewhat human readable format.
  15. dumpGraph
  16. :: (Outputable k, Outputable cls, Outputable color)
  17. => Graph k cls color -> SDoc
  18. dumpGraph graph
  19. = text "Graph"
  20. $$ (vcat $ map dumpNode $ eltsUFM $ graphMap graph)
  21. dumpNode
  22. :: (Outputable k, Outputable cls, Outputable color)
  23. => Node k cls color -> SDoc
  24. dumpNode node
  25. = text "Node " <> ppr (nodeId node)
  26. $$ text "conflicts "
  27. <> parens (int (sizeUniqSet $ nodeConflicts node))
  28. <> text " = "
  29. <> ppr (nodeConflicts node)
  30. $$ text "exclusions "
  31. <> parens (int (sizeUniqSet $ nodeExclusions node))
  32. <> text " = "
  33. <> ppr (nodeExclusions node)
  34. $$ text "coalesce "
  35. <> parens (int (sizeUniqSet $ nodeCoalesce node))
  36. <> text " = "
  37. <> ppr (nodeCoalesce node)
  38. $$ space
  39. -- | Pretty print a graph in graphviz .dot format.
  40. -- Conflicts get solid edges.
  41. -- Coalescences get dashed edges.
  42. dotGraph
  43. :: ( Uniquable k
  44. , Outputable k, Outputable cls, Outputable color)
  45. => (color -> SDoc) -- ^ What graphviz color to use for each node color
  46. -- It's usually safe to return X11 style colors here,
  47. -- ie "red", "green" etc or a hex triplet #aaff55 etc
  48. -> Triv k cls color
  49. -> Graph k cls color -> SDoc
  50. dotGraph colorMap triv graph
  51. = let nodes = eltsUFM $ graphMap graph
  52. in vcat
  53. ( [ text "graph G {" ]
  54. ++ map (dotNode colorMap triv) nodes
  55. ++ (catMaybes $ snd $ mapAccumL dotNodeEdges emptyUniqSet nodes)
  56. ++ [ text "}"
  57. , space ])
  58. dotNode :: ( Uniquable k
  59. , Outputable k, Outputable cls, Outputable color)
  60. => (color -> SDoc)
  61. -> Triv k cls color
  62. -> Node k cls color -> SDoc
  63. dotNode colorMap triv node
  64. = let name = ppr $ nodeId node
  65. cls = ppr $ nodeClass node
  66. excludes
  67. = hcat $ punctuate space
  68. $ map (\n -> text "-" <> ppr n)
  69. $ uniqSetToList $ nodeExclusions node
  70. preferences
  71. = hcat $ punctuate space
  72. $ map (\n -> text "+" <> ppr n)
  73. $ nodePreference node
  74. expref = if and [isEmptyUniqSet (nodeExclusions node), null (nodePreference node)]
  75. then empty
  76. else text "\\n" <> (excludes <+> preferences)
  77. -- if the node has been colored then show that,
  78. -- otherwise indicate whether it looks trivially colorable.
  79. color
  80. | Just c <- nodeColor node
  81. = text "\\n(" <> ppr c <> text ")"
  82. | triv (nodeClass node) (nodeConflicts node) (nodeExclusions node)
  83. = text "\\n(" <> text "triv" <> text ")"
  84. | otherwise
  85. = text "\\n(" <> text "spill?" <> text ")"
  86. label = name <> text " :: " <> cls
  87. <> expref
  88. <> color
  89. pcolorC = case nodeColor node of
  90. Nothing -> text "style=filled fillcolor=white"
  91. Just c -> text "style=filled fillcolor=" <> doubleQuotes (colorMap c)
  92. pout = text "node [label=" <> doubleQuotes label <> space <> pcolorC <> text "]"
  93. <> space <> doubleQuotes name
  94. <> text ";"
  95. in pout
  96. -- | Nodes in the graph are doubly linked, but we only want one edge for each
  97. -- conflict if the graphviz graph. Traverse over the graph, but make sure
  98. -- to only print the edges for each node once.
  99. dotNodeEdges
  100. :: ( Uniquable k
  101. , Outputable k, Outputable cls, Outputable color)
  102. => UniqSet k
  103. -> Node k cls color
  104. -> (UniqSet k, Maybe SDoc)
  105. dotNodeEdges visited node
  106. | elementOfUniqSet (nodeId node) visited
  107. = ( visited
  108. , Nothing)
  109. | otherwise
  110. = let dconflicts
  111. = map (dotEdgeConflict (nodeId node))
  112. $ uniqSetToList
  113. $ minusUniqSet (nodeConflicts node) visited
  114. dcoalesces
  115. = map (dotEdgeCoalesce (nodeId node))
  116. $ uniqSetToList
  117. $ minusUniqSet (nodeCoalesce node) visited
  118. out = vcat dconflicts
  119. $$ vcat dcoalesces
  120. in ( addOneToUniqSet visited (nodeId node)
  121. , Just out)
  122. where dotEdgeConflict u1 u2
  123. = doubleQuotes (ppr u1) <> text " -- " <> doubleQuotes (ppr u2)
  124. <> text ";"
  125. dotEdgeCoalesce u1 u2
  126. = doubleQuotes (ppr u1) <> text " -- " <> doubleQuotes (ppr u2)
  127. <> space <> text "[ style = dashed ];"