PageRenderTime 36ms CodeModel.GetById 6ms RepoModel.GetById 0ms app.codeStats 0ms

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

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