PageRenderTime 47ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/compiler/utils/GraphPpr.hs

http://github.com/ghc/ghc
Haskell | 171 lines | 114 code | 41 blank | 16 comment | 2 complexity | 00898d20dbba31b7269be04a70cce975 MD5 | raw file
Possible License(s): MIT, BSD-3-Clause, GPL-3.0
  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 color)
  17. => Graph k cls color -> SDoc
  18. dumpGraph graph
  19. = text "Graph"
  20. $$ pprUFM (graphMap graph) (vcat . map dumpNode)
  21. dumpNode
  22. :: (Outputable k, 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 = nonDetEltsUFM $ graphMap graph
  52. -- See Note [Unique Determinism and code generation]
  53. in vcat
  54. ( [ text "graph G {" ]
  55. ++ map (dotNode colorMap triv) nodes
  56. ++ (catMaybes $ snd $ mapAccumL dotNodeEdges emptyUniqSet nodes)
  57. ++ [ text "}"
  58. , space ])
  59. dotNode :: ( 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. $ nonDetEltsUFM $ nodeExclusions node
  70. -- See Note [Unique Determinism and code generation]
  71. preferences
  72. = hcat $ punctuate space
  73. $ map (\n -> text "+" <> ppr n)
  74. $ nodePreference node
  75. expref = if and [isEmptyUniqSet (nodeExclusions node), null (nodePreference node)]
  76. then empty
  77. else text "\\n" <> (excludes <+> preferences)
  78. -- if the node has been colored then show that,
  79. -- otherwise indicate whether it looks trivially colorable.
  80. color
  81. | Just c <- nodeColor node
  82. = text "\\n(" <> ppr c <> text ")"
  83. | triv (nodeClass node) (nodeConflicts node) (nodeExclusions node)
  84. = text "\\n(" <> text "triv" <> text ")"
  85. | otherwise
  86. = text "\\n(" <> text "spill?" <> text ")"
  87. label = name <> text " :: " <> cls
  88. <> expref
  89. <> color
  90. pcolorC = case nodeColor node of
  91. Nothing -> text "style=filled fillcolor=white"
  92. Just c -> text "style=filled fillcolor=" <> doubleQuotes (colorMap c)
  93. pout = text "node [label=" <> doubleQuotes label <> space <> pcolorC <> text "]"
  94. <> space <> doubleQuotes name
  95. <> text ";"
  96. in pout
  97. -- | Nodes in the graph are doubly linked, but we only want one edge for each
  98. -- conflict if the graphviz graph. Traverse over the graph, but make sure
  99. -- to only print the edges for each node once.
  100. dotNodeEdges
  101. :: ( Uniquable k
  102. , Outputable k)
  103. => UniqSet k
  104. -> Node k cls color
  105. -> (UniqSet k, Maybe SDoc)
  106. dotNodeEdges visited node
  107. | elementOfUniqSet (nodeId node) visited
  108. = ( visited
  109. , Nothing)
  110. | otherwise
  111. = let dconflicts
  112. = map (dotEdgeConflict (nodeId node))
  113. $ nonDetEltsUFM
  114. -- See Note [Unique Determinism and code generation]
  115. $ minusUniqSet (nodeConflicts node) visited
  116. dcoalesces
  117. = map (dotEdgeCoalesce (nodeId node))
  118. $ nonDetEltsUFM
  119. -- See Note [Unique Determinism and code generation]
  120. $ minusUniqSet (nodeCoalesce node) visited
  121. out = vcat dconflicts
  122. $$ vcat dcoalesces
  123. in ( addOneToUniqSet visited (nodeId node)
  124. , Just out)
  125. where dotEdgeConflict u1 u2
  126. = doubleQuotes (ppr u1) <> text " -- " <> doubleQuotes (ppr u2)
  127. <> text ";"
  128. dotEdgeCoalesce u1 u2
  129. = doubleQuotes (ppr u1) <> text " -- " <> doubleQuotes (ppr u2)
  130. <> space <> text "[ style = dashed ];"