/compiler/GHC/CmmToAsm/Reg/Linear/Stats.hs

https://github.com/bgamari/ghc · Haskell · 91 lines · 65 code · 19 blank · 7 comment · 1 complexity · 0d42c1a4810fb61ebc4d8cd2701ed27d MD5 · raw file

  1. module GHC.CmmToAsm.Reg.Linear.Stats (
  2. binSpillReasons,
  3. countRegRegMovesNat,
  4. pprStats
  5. )
  6. where
  7. import GHC.Prelude
  8. import GHC.CmmToAsm.Reg.Linear.Base
  9. import GHC.CmmToAsm.Reg.Liveness
  10. import GHC.CmmToAsm.Instr
  11. import GHC.Types.Unique (Unique)
  12. import GHC.CmmToAsm.Types
  13. import GHC.Types.Unique.FM
  14. import GHC.Utils.Outputable
  15. import GHC.Utils.Monad.State.Strict
  16. -- | Build a map of how many times each reg was alloced, clobbered, loaded etc.
  17. binSpillReasons
  18. :: [SpillReason] -> UniqFM Unique [Int]
  19. -- See Note [UniqFM and the register allocator]
  20. binSpillReasons reasons
  21. = addListToUFM_C
  22. (zipWith (+))
  23. emptyUFM
  24. (map (\reason -> case reason of
  25. SpillAlloc r -> (r, [1, 0, 0, 0, 0])
  26. SpillClobber r -> (r, [0, 1, 0, 0, 0])
  27. SpillLoad r -> (r, [0, 0, 1, 0, 0])
  28. SpillJoinRR r -> (r, [0, 0, 0, 1, 0])
  29. SpillJoinRM r -> (r, [0, 0, 0, 0, 1])) reasons)
  30. -- | Count reg-reg moves remaining in this code.
  31. countRegRegMovesNat
  32. :: Instruction instr
  33. => NatCmmDecl statics instr -> Int
  34. countRegRegMovesNat cmm
  35. = execState (mapGenBlockTopM countBlock cmm) 0
  36. where
  37. countBlock b@(BasicBlock _ instrs)
  38. = do mapM_ countInstr instrs
  39. return b
  40. countInstr instr
  41. | Just _ <- takeRegRegMoveInstr instr
  42. = do modify (+ 1)
  43. return instr
  44. | otherwise
  45. = return instr
  46. -- | Pretty print some RegAllocStats
  47. pprStats
  48. :: Instruction instr
  49. => [NatCmmDecl statics instr] -> [RegAllocStats] -> SDoc
  50. pprStats code statss
  51. = let -- sum up all the instrs inserted by the spiller
  52. -- See Note [UniqFM and the register allocator]
  53. spills :: UniqFM Unique [Int]
  54. spills = foldl' (plusUFM_C (zipWith (+)))
  55. emptyUFM
  56. $ map ra_spillInstrs statss
  57. spillTotals = foldl' (zipWith (+))
  58. [0, 0, 0, 0, 0]
  59. $ nonDetEltsUFM spills
  60. -- See Note [Unique Determinism and code generation]
  61. -- count how many reg-reg-moves remain in the code
  62. moves = sum $ map countRegRegMovesNat code
  63. pprSpill (reg, spills)
  64. = parens $ (hcat $ punctuate (text ", ") (doubleQuotes (ppr reg) : map ppr spills))
  65. in ( text "-- spills-added-total"
  66. $$ text "-- (allocs, clobbers, loads, joinRR, joinRM, reg_reg_moves_remaining)"
  67. $$ (parens $ (hcat $ punctuate (text ", ") (map ppr spillTotals ++ [ppr moves])))
  68. $$ text ""
  69. $$ text "-- spills-added"
  70. $$ text "-- (reg_name, allocs, clobbers, loads, joinRR, joinRM)"
  71. $$ (pprUFMWithKeys spills (vcat . map pprSpill))
  72. $$ text "")