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

/compiler/nativeGen/RegAlloc/Linear/Base.hs

https://github.com/ezyang/ghc
Haskell | 134 lines | 52 code | 39 blank | 43 comment | 0 complexity | 663ac273dced13460b78e78b5cb9c8b4 MD5 | raw file
  1. -- | Put common type definitions here to break recursive module dependencies.
  2. module RegAlloc.Linear.Base (
  3. BlockAssignment,
  4. Loc(..),
  5. regsOfLoc,
  6. -- for stats
  7. SpillReason(..),
  8. RegAllocStats(..),
  9. -- the allocator monad
  10. RA_State(..),
  11. )
  12. where
  13. import GhcPrelude
  14. import RegAlloc.Linear.StackMap
  15. import RegAlloc.Liveness
  16. import Reg
  17. import DynFlags
  18. import Outputable
  19. import Unique
  20. import UniqFM
  21. import UniqSupply
  22. -- | Used to store the register assignment on entry to a basic block.
  23. -- We use this to handle join points, where multiple branch instructions
  24. -- target a particular label. We have to insert fixup code to make
  25. -- the register assignments from the different sources match up.
  26. --
  27. type BlockAssignment freeRegs
  28. = BlockMap (freeRegs, RegMap Loc)
  29. -- | Where a vreg is currently stored
  30. -- A temporary can be marked as living in both a register and memory
  31. -- (InBoth), for example if it was recently loaded from a spill location.
  32. -- This makes it cheap to spill (no save instruction required), but we
  33. -- have to be careful to turn this into InReg if the value in the
  34. -- register is changed.
  35. -- This is also useful when a temporary is about to be clobbered. We
  36. -- save it in a spill location, but mark it as InBoth because the current
  37. -- instruction might still want to read it.
  38. --
  39. data Loc
  40. -- | vreg is in a register
  41. = InReg !RealReg
  42. -- | vreg is held in a stack slot
  43. | InMem {-# UNPACK #-} !StackSlot
  44. -- | vreg is held in both a register and a stack slot
  45. | InBoth !RealReg
  46. {-# UNPACK #-} !StackSlot
  47. deriving (Eq, Show, Ord)
  48. instance Outputable Loc where
  49. ppr l = text (show l)
  50. -- | Get the reg numbers stored in this Loc.
  51. regsOfLoc :: Loc -> [RealReg]
  52. regsOfLoc (InReg r) = [r]
  53. regsOfLoc (InBoth r _) = [r]
  54. regsOfLoc (InMem _) = []
  55. -- | Reasons why instructions might be inserted by the spiller.
  56. -- Used when generating stats for -ddrop-asm-stats.
  57. --
  58. data SpillReason
  59. -- | vreg was spilled to a slot so we could use its
  60. -- current hreg for another vreg
  61. = SpillAlloc !Unique
  62. -- | vreg was moved because its hreg was clobbered
  63. | SpillClobber !Unique
  64. -- | vreg was loaded from a spill slot
  65. | SpillLoad !Unique
  66. -- | reg-reg move inserted during join to targets
  67. | SpillJoinRR !Unique
  68. -- | reg-mem move inserted during join to targets
  69. | SpillJoinRM !Unique
  70. -- | Used to carry interesting stats out of the register allocator.
  71. data RegAllocStats
  72. = RegAllocStats
  73. { ra_spillInstrs :: UniqFM [Int] }
  74. -- | The register allocator state
  75. data RA_State freeRegs
  76. = RA_State
  77. {
  78. -- | the current mapping from basic blocks to
  79. -- the register assignments at the beginning of that block.
  80. ra_blockassig :: BlockAssignment freeRegs
  81. -- | free machine registers
  82. , ra_freeregs :: !freeRegs
  83. -- | assignment of temps to locations
  84. , ra_assig :: RegMap Loc
  85. -- | current stack delta
  86. , ra_delta :: Int
  87. -- | free stack slots for spilling
  88. , ra_stack :: StackMap
  89. -- | unique supply for generating names for join point fixup blocks.
  90. , ra_us :: UniqSupply
  91. -- | Record why things were spilled, for -ddrop-asm-stats.
  92. -- Just keep a list here instead of a map of regs -> reasons.
  93. -- We don't want to slow down the allocator if we're not going to emit the stats.
  94. , ra_spills :: [SpillReason]
  95. , ra_DynFlags :: DynFlags }