PageRenderTime 42ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/compiler/utils/GraphPpr.hs

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