PageRenderTime 54ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/ghc-7.0.4/compiler/nativeGen/RegAlloc/Liveness.hs

http://picorec.googlecode.com/
Haskell | 945 lines | 606 code | 216 blank | 123 comment | 6 complexity | d547498854940bb6280acee9b9dfa1a4 MD5 | raw file
Possible License(s): BSD-3-Clause, BSD-2-Clause
  1. -----------------------------------------------------------------------------
  2. --
  3. -- The register liveness determinator
  4. --
  5. -- (c) The University of Glasgow 2004
  6. --
  7. -----------------------------------------------------------------------------
  8. {-# OPTIONS -Wall -fno-warn-name-shadowing #-}
  9. module RegAlloc.Liveness (
  10. RegSet,
  11. RegMap, emptyRegMap,
  12. BlockMap, emptyBlockMap,
  13. LiveCmmTop,
  14. InstrSR (..),
  15. LiveInstr (..),
  16. Liveness (..),
  17. LiveInfo (..),
  18. LiveBasicBlock,
  19. mapBlockTop, mapBlockTopM, mapSCCM,
  20. mapGenBlockTop, mapGenBlockTopM,
  21. stripLive,
  22. stripLiveBlock,
  23. slurpConflicts,
  24. slurpReloadCoalesce,
  25. eraseDeltasLive,
  26. patchEraseLive,
  27. patchRegsLiveInstr,
  28. reverseBlocksInTops,
  29. regLiveness,
  30. natCmmTopToLive
  31. ) where
  32. import Reg
  33. import Instruction
  34. import BlockId
  35. import Cmm hiding (RegSet)
  36. import PprCmm()
  37. import Digraph
  38. import Outputable
  39. import Unique
  40. import UniqSet
  41. import UniqFM
  42. import UniqSupply
  43. import Bag
  44. import State
  45. import FastString
  46. import Data.List
  47. import Data.Maybe
  48. import Data.Map (Map)
  49. import Data.Set (Set)
  50. import qualified Data.Map as Map
  51. -----------------------------------------------------------------------------
  52. type RegSet = UniqSet Reg
  53. type RegMap a = UniqFM a
  54. emptyRegMap :: UniqFM a
  55. emptyRegMap = emptyUFM
  56. type BlockMap a = BlockEnv a
  57. emptyBlockMap :: BlockEnv a
  58. emptyBlockMap = emptyBlockEnv
  59. -- | A top level thing which carries liveness information.
  60. type LiveCmmTop instr
  61. = GenCmmTop
  62. CmmStatic
  63. LiveInfo
  64. [SCC (LiveBasicBlock instr)]
  65. -- | The register allocator also wants to use SPILL/RELOAD meta instructions,
  66. -- so we'll keep those here.
  67. data InstrSR instr
  68. -- | A real machine instruction
  69. = Instr instr
  70. -- | spill this reg to a stack slot
  71. | SPILL Reg Int
  72. -- | reload this reg from a stack slot
  73. | RELOAD Int Reg
  74. instance Instruction instr => Instruction (InstrSR instr) where
  75. regUsageOfInstr i
  76. = case i of
  77. Instr instr -> regUsageOfInstr instr
  78. SPILL reg _ -> RU [reg] []
  79. RELOAD _ reg -> RU [] [reg]
  80. patchRegsOfInstr i f
  81. = case i of
  82. Instr instr -> Instr (patchRegsOfInstr instr f)
  83. SPILL reg slot -> SPILL (f reg) slot
  84. RELOAD slot reg -> RELOAD slot (f reg)
  85. isJumpishInstr i
  86. = case i of
  87. Instr instr -> isJumpishInstr instr
  88. _ -> False
  89. jumpDestsOfInstr i
  90. = case i of
  91. Instr instr -> jumpDestsOfInstr instr
  92. _ -> []
  93. patchJumpInstr i f
  94. = case i of
  95. Instr instr -> Instr (patchJumpInstr instr f)
  96. _ -> i
  97. mkSpillInstr = error "mkSpillInstr[InstrSR]: Not making SPILL meta-instr"
  98. mkLoadInstr = error "mkLoadInstr[InstrSR]: Not making LOAD meta-instr"
  99. takeDeltaInstr i
  100. = case i of
  101. Instr instr -> takeDeltaInstr instr
  102. _ -> Nothing
  103. isMetaInstr i
  104. = case i of
  105. Instr instr -> isMetaInstr instr
  106. _ -> False
  107. mkRegRegMoveInstr r1 r2 = Instr (mkRegRegMoveInstr r1 r2)
  108. takeRegRegMoveInstr i
  109. = case i of
  110. Instr instr -> takeRegRegMoveInstr instr
  111. _ -> Nothing
  112. mkJumpInstr target = map Instr (mkJumpInstr target)
  113. -- | An instruction with liveness information.
  114. data LiveInstr instr
  115. = LiveInstr (InstrSR instr) (Maybe Liveness)
  116. -- | Liveness information.
  117. -- The regs which die are ones which are no longer live in the *next* instruction
  118. -- in this sequence.
  119. -- (NB. if the instruction is a jump, these registers might still be live
  120. -- at the jump target(s) - you have to check the liveness at the destination
  121. -- block to find out).
  122. data Liveness
  123. = Liveness
  124. { liveBorn :: RegSet -- ^ registers born in this instruction (written to for first time).
  125. , liveDieRead :: RegSet -- ^ registers that died because they were read for the last time.
  126. , liveDieWrite :: RegSet } -- ^ registers that died because they were clobbered by something.
  127. -- | Stash regs live on entry to each basic block in the info part of the cmm code.
  128. data LiveInfo
  129. = LiveInfo
  130. [CmmStatic] -- cmm static stuff
  131. (Maybe BlockId) -- id of the first block
  132. (Maybe (BlockMap RegSet)) -- argument locals live on entry to this block
  133. (Map BlockId (Set Int)) -- stack slots live on entry to this block
  134. -- | A basic block with liveness information.
  135. type LiveBasicBlock instr
  136. = GenBasicBlock (LiveInstr instr)
  137. instance Outputable instr
  138. => Outputable (InstrSR instr) where
  139. ppr (Instr realInstr)
  140. = ppr realInstr
  141. ppr (SPILL reg slot)
  142. = hcat [
  143. ptext (sLit "\tSPILL"),
  144. char ' ',
  145. ppr reg,
  146. comma,
  147. ptext (sLit "SLOT") <> parens (int slot)]
  148. ppr (RELOAD slot reg)
  149. = hcat [
  150. ptext (sLit "\tRELOAD"),
  151. char ' ',
  152. ptext (sLit "SLOT") <> parens (int slot),
  153. comma,
  154. ppr reg]
  155. instance Outputable instr
  156. => Outputable (LiveInstr instr) where
  157. ppr (LiveInstr instr Nothing)
  158. = ppr instr
  159. ppr (LiveInstr instr (Just live))
  160. = ppr instr
  161. $$ (nest 8
  162. $ vcat
  163. [ pprRegs (ptext (sLit "# born: ")) (liveBorn live)
  164. , pprRegs (ptext (sLit "# r_dying: ")) (liveDieRead live)
  165. , pprRegs (ptext (sLit "# w_dying: ")) (liveDieWrite live) ]
  166. $+$ space)
  167. where pprRegs :: SDoc -> RegSet -> SDoc
  168. pprRegs name regs
  169. | isEmptyUniqSet regs = empty
  170. | otherwise = name <> (hcat $ punctuate space $ map ppr $ uniqSetToList regs)
  171. instance Outputable LiveInfo where
  172. ppr (LiveInfo static firstId liveVRegsOnEntry liveSlotsOnEntry)
  173. = (vcat $ map ppr static)
  174. $$ text "# firstId = " <> ppr firstId
  175. $$ text "# liveVRegsOnEntry = " <> ppr liveVRegsOnEntry
  176. $$ text "# liveSlotsOnEntry = " <> text (show liveSlotsOnEntry)
  177. -- | map a function across all the basic blocks in this code
  178. --
  179. mapBlockTop
  180. :: (LiveBasicBlock instr -> LiveBasicBlock instr)
  181. -> LiveCmmTop instr -> LiveCmmTop instr
  182. mapBlockTop f cmm
  183. = evalState (mapBlockTopM (\x -> return $ f x) cmm) ()
  184. -- | map a function across all the basic blocks in this code (monadic version)
  185. --
  186. mapBlockTopM
  187. :: Monad m
  188. => (LiveBasicBlock instr -> m (LiveBasicBlock instr))
  189. -> LiveCmmTop instr -> m (LiveCmmTop instr)
  190. mapBlockTopM _ cmm@(CmmData{})
  191. = return cmm
  192. mapBlockTopM f (CmmProc header label params sccs)
  193. = do sccs' <- mapM (mapSCCM f) sccs
  194. return $ CmmProc header label params sccs'
  195. mapSCCM :: Monad m => (a -> m b) -> SCC a -> m (SCC b)
  196. mapSCCM f (AcyclicSCC x)
  197. = do x' <- f x
  198. return $ AcyclicSCC x'
  199. mapSCCM f (CyclicSCC xs)
  200. = do xs' <- mapM f xs
  201. return $ CyclicSCC xs'
  202. -- map a function across all the basic blocks in this code
  203. mapGenBlockTop
  204. :: (GenBasicBlock i -> GenBasicBlock i)
  205. -> (GenCmmTop d h (ListGraph i) -> GenCmmTop d h (ListGraph i))
  206. mapGenBlockTop f cmm
  207. = evalState (mapGenBlockTopM (\x -> return $ f x) cmm) ()
  208. -- | map a function across all the basic blocks in this code (monadic version)
  209. mapGenBlockTopM
  210. :: Monad m
  211. => (GenBasicBlock i -> m (GenBasicBlock i))
  212. -> (GenCmmTop d h (ListGraph i) -> m (GenCmmTop d h (ListGraph i)))
  213. mapGenBlockTopM _ cmm@(CmmData{})
  214. = return cmm
  215. mapGenBlockTopM f (CmmProc header label params (ListGraph blocks))
  216. = do blocks' <- mapM f blocks
  217. return $ CmmProc header label params (ListGraph blocks')
  218. -- | Slurp out the list of register conflicts and reg-reg moves from this top level thing.
  219. -- Slurping of conflicts and moves is wrapped up together so we don't have
  220. -- to make two passes over the same code when we want to build the graph.
  221. --
  222. slurpConflicts
  223. :: Instruction instr
  224. => LiveCmmTop instr
  225. -> (Bag (UniqSet Reg), Bag (Reg, Reg))
  226. slurpConflicts live
  227. = slurpCmm (emptyBag, emptyBag) live
  228. where slurpCmm rs CmmData{} = rs
  229. slurpCmm rs (CmmProc info _ _ sccs)
  230. = foldl' (slurpSCC info) rs sccs
  231. slurpSCC info rs (AcyclicSCC b)
  232. = slurpBlock info rs b
  233. slurpSCC info rs (CyclicSCC bs)
  234. = foldl' (slurpBlock info) rs bs
  235. slurpBlock info rs (BasicBlock blockId instrs)
  236. | LiveInfo _ _ (Just blockLive) _ <- info
  237. , Just rsLiveEntry <- lookupBlockEnv blockLive blockId
  238. , (conflicts, moves) <- slurpLIs rsLiveEntry rs instrs
  239. = (consBag rsLiveEntry conflicts, moves)
  240. | otherwise
  241. = panic "Liveness.slurpConflicts: bad block"
  242. slurpLIs rsLive (conflicts, moves) []
  243. = (consBag rsLive conflicts, moves)
  244. slurpLIs rsLive rs (LiveInstr _ Nothing : lis)
  245. = slurpLIs rsLive rs lis
  246. slurpLIs rsLiveEntry (conflicts, moves) (LiveInstr instr (Just live) : lis)
  247. = let
  248. -- regs that die because they are read for the last time at the start of an instruction
  249. -- are not live across it.
  250. rsLiveAcross = rsLiveEntry `minusUniqSet` (liveDieRead live)
  251. -- regs live on entry to the next instruction.
  252. -- be careful of orphans, make sure to delete dying regs _after_ unioning
  253. -- in the ones that are born here.
  254. rsLiveNext = (rsLiveAcross `unionUniqSets` (liveBorn live))
  255. `minusUniqSet` (liveDieWrite live)
  256. -- orphan vregs are the ones that die in the same instruction they are born in.
  257. -- these are likely to be results that are never used, but we still
  258. -- need to assign a hreg to them..
  259. rsOrphans = intersectUniqSets
  260. (liveBorn live)
  261. (unionUniqSets (liveDieWrite live) (liveDieRead live))
  262. --
  263. rsConflicts = unionUniqSets rsLiveNext rsOrphans
  264. in case takeRegRegMoveInstr instr of
  265. Just rr -> slurpLIs rsLiveNext
  266. ( consBag rsConflicts conflicts
  267. , consBag rr moves) lis
  268. Nothing -> slurpLIs rsLiveNext
  269. ( consBag rsConflicts conflicts
  270. , moves) lis
  271. -- | For spill\/reloads
  272. --
  273. -- SPILL v1, slot1
  274. -- ...
  275. -- RELOAD slot1, v2
  276. --
  277. -- If we can arrange that v1 and v2 are allocated to the same hreg it's more likely
  278. -- the spill\/reload instrs can be cleaned and replaced by a nop reg-reg move.
  279. --
  280. --
  281. slurpReloadCoalesce
  282. :: forall instr. Instruction instr
  283. => LiveCmmTop instr
  284. -> Bag (Reg, Reg)
  285. slurpReloadCoalesce live
  286. = slurpCmm emptyBag live
  287. where
  288. slurpCmm :: Bag (Reg, Reg)
  289. -> GenCmmTop t t1 [SCC (LiveBasicBlock instr)]
  290. -> Bag (Reg, Reg)
  291. slurpCmm cs CmmData{} = cs
  292. slurpCmm cs (CmmProc _ _ _ sccs)
  293. = slurpComp cs (flattenSCCs sccs)
  294. slurpComp :: Bag (Reg, Reg)
  295. -> [LiveBasicBlock instr]
  296. -> Bag (Reg, Reg)
  297. slurpComp cs blocks
  298. = let (moveBags, _) = runState (slurpCompM blocks) emptyUFM
  299. in unionManyBags (cs : moveBags)
  300. slurpCompM :: [LiveBasicBlock instr]
  301. -> State (UniqFM [UniqFM Reg]) [Bag (Reg, Reg)]
  302. slurpCompM blocks
  303. = do -- run the analysis once to record the mapping across jumps.
  304. mapM_ (slurpBlock False) blocks
  305. -- run it a second time while using the information from the last pass.
  306. -- We /could/ run this many more times to deal with graphical control
  307. -- flow and propagating info across multiple jumps, but it's probably
  308. -- not worth the trouble.
  309. mapM (slurpBlock True) blocks
  310. slurpBlock :: Bool -> LiveBasicBlock instr
  311. -> State (UniqFM [UniqFM Reg]) (Bag (Reg, Reg))
  312. slurpBlock propagate (BasicBlock blockId instrs)
  313. = do -- grab the slot map for entry to this block
  314. slotMap <- if propagate
  315. then getSlotMap blockId
  316. else return emptyUFM
  317. (_, mMoves) <- mapAccumLM slurpLI slotMap instrs
  318. return $ listToBag $ catMaybes mMoves
  319. slurpLI :: UniqFM Reg -- current slotMap
  320. -> LiveInstr instr
  321. -> State (UniqFM [UniqFM Reg]) -- blockId -> [slot -> reg]
  322. -- for tracking slotMaps across jumps
  323. ( UniqFM Reg -- new slotMap
  324. , Maybe (Reg, Reg)) -- maybe a new coalesce edge
  325. slurpLI slotMap li
  326. -- remember what reg was stored into the slot
  327. | LiveInstr (SPILL reg slot) _ <- li
  328. , slotMap' <- addToUFM slotMap slot reg
  329. = return (slotMap', Nothing)
  330. -- add an edge betwen the this reg and the last one stored into the slot
  331. | LiveInstr (RELOAD slot reg) _ <- li
  332. = case lookupUFM slotMap slot of
  333. Just reg2
  334. | reg /= reg2 -> return (slotMap, Just (reg, reg2))
  335. | otherwise -> return (slotMap, Nothing)
  336. Nothing -> return (slotMap, Nothing)
  337. -- if we hit a jump, remember the current slotMap
  338. | LiveInstr (Instr instr) _ <- li
  339. , targets <- jumpDestsOfInstr instr
  340. , not $ null targets
  341. = do mapM_ (accSlotMap slotMap) targets
  342. return (slotMap, Nothing)
  343. | otherwise
  344. = return (slotMap, Nothing)
  345. -- record a slotmap for an in edge to this block
  346. accSlotMap slotMap blockId
  347. = modify (\s -> addToUFM_C (++) s blockId [slotMap])
  348. -- work out the slot map on entry to this block
  349. -- if we have slot maps for multiple in-edges then we need to merge them.
  350. getSlotMap blockId
  351. = do map <- get
  352. let slotMaps = fromMaybe [] (lookupUFM map blockId)
  353. return $ foldr mergeSlotMaps emptyUFM slotMaps
  354. mergeSlotMaps :: UniqFM Reg -> UniqFM Reg -> UniqFM Reg
  355. mergeSlotMaps map1 map2
  356. = listToUFM
  357. $ [ (k, r1) | (k, r1) <- ufmToList map1
  358. , case lookupUFM map2 k of
  359. Nothing -> False
  360. Just r2 -> r1 == r2 ]
  361. -- | Strip away liveness information, yielding NatCmmTop
  362. stripLive
  363. :: (Outputable instr, Instruction instr)
  364. => LiveCmmTop instr
  365. -> NatCmmTop instr
  366. stripLive live
  367. = stripCmm live
  368. where stripCmm (CmmData sec ds) = CmmData sec ds
  369. stripCmm (CmmProc (LiveInfo info (Just first_id) _ _) label params sccs)
  370. = let final_blocks = flattenSCCs sccs
  371. -- make sure the block that was first in the input list
  372. -- stays at the front of the output. This is the entry point
  373. -- of the proc, and it needs to come first.
  374. ((first':_), rest')
  375. = partition ((== first_id) . blockId) final_blocks
  376. in CmmProc info label params
  377. (ListGraph $ map stripLiveBlock $ first' : rest')
  378. -- procs used for stg_split_markers don't contain any blocks, and have no first_id.
  379. stripCmm (CmmProc (LiveInfo info Nothing _ _) label params [])
  380. = CmmProc info label params (ListGraph [])
  381. -- If the proc has blocks but we don't know what the first one was, then we're dead.
  382. stripCmm proc
  383. = pprPanic "RegAlloc.Liveness.stripLive: no first_id on proc" (ppr proc)
  384. -- | Strip away liveness information from a basic block,
  385. -- and make real spill instructions out of SPILL, RELOAD pseudos along the way.
  386. stripLiveBlock
  387. :: Instruction instr
  388. => LiveBasicBlock instr
  389. -> NatBasicBlock instr
  390. stripLiveBlock (BasicBlock i lis)
  391. = BasicBlock i instrs'
  392. where (instrs', _)
  393. = runState (spillNat [] lis) 0
  394. spillNat acc []
  395. = return (reverse acc)
  396. spillNat acc (LiveInstr (SPILL reg slot) _ : instrs)
  397. = do delta <- get
  398. spillNat (mkSpillInstr reg delta slot : acc) instrs
  399. spillNat acc (LiveInstr (RELOAD slot reg) _ : instrs)
  400. = do delta <- get
  401. spillNat (mkLoadInstr reg delta slot : acc) instrs
  402. spillNat acc (LiveInstr (Instr instr) _ : instrs)
  403. | Just i <- takeDeltaInstr instr
  404. = do put i
  405. spillNat acc instrs
  406. spillNat acc (LiveInstr (Instr instr) _ : instrs)
  407. = spillNat (instr : acc) instrs
  408. -- | Erase Delta instructions.
  409. eraseDeltasLive
  410. :: Instruction instr
  411. => LiveCmmTop instr
  412. -> LiveCmmTop instr
  413. eraseDeltasLive cmm
  414. = mapBlockTop eraseBlock cmm
  415. where
  416. eraseBlock (BasicBlock id lis)
  417. = BasicBlock id
  418. $ filter (\(LiveInstr i _) -> not $ isJust $ takeDeltaInstr i)
  419. $ lis
  420. -- | Patch the registers in this code according to this register mapping.
  421. -- also erase reg -> reg moves when the reg is the same.
  422. -- also erase reg -> reg moves when the destination dies in this instr.
  423. patchEraseLive
  424. :: Instruction instr
  425. => (Reg -> Reg)
  426. -> LiveCmmTop instr -> LiveCmmTop instr
  427. patchEraseLive patchF cmm
  428. = patchCmm cmm
  429. where
  430. patchCmm cmm@CmmData{} = cmm
  431. patchCmm (CmmProc info label params sccs)
  432. | LiveInfo static id (Just blockMap) mLiveSlots <- info
  433. = let
  434. patchRegSet set = mkUniqSet $ map patchF $ uniqSetToList set
  435. blockMap' = mapBlockEnv patchRegSet blockMap
  436. info' = LiveInfo static id (Just blockMap') mLiveSlots
  437. in CmmProc info' label params $ map patchSCC sccs
  438. | otherwise
  439. = panic "RegAlloc.Liveness.patchEraseLive: no blockMap"
  440. patchSCC (AcyclicSCC b) = AcyclicSCC (patchBlock b)
  441. patchSCC (CyclicSCC bs) = CyclicSCC (map patchBlock bs)
  442. patchBlock (BasicBlock id lis)
  443. = BasicBlock id $ patchInstrs lis
  444. patchInstrs [] = []
  445. patchInstrs (li : lis)
  446. | LiveInstr i (Just live) <- li'
  447. , Just (r1, r2) <- takeRegRegMoveInstr i
  448. , eatMe r1 r2 live
  449. = patchInstrs lis
  450. | otherwise
  451. = li' : patchInstrs lis
  452. where li' = patchRegsLiveInstr patchF li
  453. eatMe r1 r2 live
  454. -- source and destination regs are the same
  455. | r1 == r2 = True
  456. -- desination reg is never used
  457. | elementOfUniqSet r2 (liveBorn live)
  458. , elementOfUniqSet r2 (liveDieRead live) || elementOfUniqSet r2 (liveDieWrite live)
  459. = True
  460. | otherwise = False
  461. -- | Patch registers in this LiveInstr, including the liveness information.
  462. --
  463. patchRegsLiveInstr
  464. :: Instruction instr
  465. => (Reg -> Reg)
  466. -> LiveInstr instr -> LiveInstr instr
  467. patchRegsLiveInstr patchF li
  468. = case li of
  469. LiveInstr instr Nothing
  470. -> LiveInstr (patchRegsOfInstr instr patchF) Nothing
  471. LiveInstr instr (Just live)
  472. -> LiveInstr
  473. (patchRegsOfInstr instr patchF)
  474. (Just live
  475. { -- WARNING: have to go via lists here because patchF changes the uniq in the Reg
  476. liveBorn = mkUniqSet $ map patchF $ uniqSetToList $ liveBorn live
  477. , liveDieRead = mkUniqSet $ map patchF $ uniqSetToList $ liveDieRead live
  478. , liveDieWrite = mkUniqSet $ map patchF $ uniqSetToList $ liveDieWrite live })
  479. --------------------------------------------------------------------------------
  480. -- | Convert a NatCmmTop to a LiveCmmTop, with empty liveness information
  481. natCmmTopToLive
  482. :: Instruction instr
  483. => NatCmmTop instr
  484. -> LiveCmmTop instr
  485. natCmmTopToLive (CmmData i d)
  486. = CmmData i d
  487. natCmmTopToLive (CmmProc info lbl params (ListGraph []))
  488. = CmmProc (LiveInfo info Nothing Nothing Map.empty)
  489. lbl params []
  490. natCmmTopToLive (CmmProc info lbl params (ListGraph blocks@(first : _)))
  491. = let first_id = blockId first
  492. sccs = sccBlocks blocks
  493. sccsLive = map (fmap (\(BasicBlock l instrs) ->
  494. BasicBlock l (map (\i -> LiveInstr (Instr i) Nothing) instrs)))
  495. $ sccs
  496. in CmmProc (LiveInfo info (Just first_id) Nothing Map.empty)
  497. lbl params sccsLive
  498. sccBlocks
  499. :: Instruction instr
  500. => [NatBasicBlock instr]
  501. -> [SCC (NatBasicBlock instr)]
  502. sccBlocks blocks = stronglyConnCompFromEdgedVertices graph
  503. where
  504. getOutEdges :: Instruction instr => [instr] -> [BlockId]
  505. getOutEdges instrs = concat $ map jumpDestsOfInstr instrs
  506. graph = [ (block, getUnique id, map getUnique (getOutEdges instrs))
  507. | block@(BasicBlock id instrs) <- blocks ]
  508. ---------------------------------------------------------------------------------
  509. -- Annotate code with register liveness information
  510. --
  511. regLiveness
  512. :: (Outputable instr, Instruction instr)
  513. => LiveCmmTop instr
  514. -> UniqSM (LiveCmmTop instr)
  515. regLiveness (CmmData i d)
  516. = returnUs $ CmmData i d
  517. regLiveness (CmmProc info lbl params [])
  518. | LiveInfo static mFirst _ _ <- info
  519. = returnUs $ CmmProc
  520. (LiveInfo static mFirst (Just emptyBlockEnv) Map.empty)
  521. lbl params []
  522. regLiveness (CmmProc info lbl params sccs)
  523. | LiveInfo static mFirst _ liveSlotsOnEntry <- info
  524. = let (ann_sccs, block_live) = computeLiveness sccs
  525. in returnUs $ CmmProc (LiveInfo static mFirst (Just block_live) liveSlotsOnEntry)
  526. lbl params ann_sccs
  527. -- -----------------------------------------------------------------------------
  528. -- | Check ordering of Blocks
  529. -- The computeLiveness function requires SCCs to be in reverse dependent order.
  530. -- If they're not the liveness information will be wrong, and we'll get a bad allocation.
  531. -- Better to check for this precondition explicitly or some other poor sucker will
  532. -- waste a day staring at bad assembly code..
  533. --
  534. checkIsReverseDependent
  535. :: Instruction instr
  536. => [SCC (LiveBasicBlock instr)] -- ^ SCCs of blocks that we're about to run the liveness determinator on.
  537. -> Maybe BlockId -- ^ BlockIds that fail the test (if any)
  538. checkIsReverseDependent sccs'
  539. = go emptyUniqSet sccs'
  540. where go _ []
  541. = Nothing
  542. go blocksSeen (AcyclicSCC block : sccs)
  543. = let dests = slurpJumpDestsOfBlock block
  544. blocksSeen' = unionUniqSets blocksSeen $ mkUniqSet [blockId block]
  545. badDests = dests `minusUniqSet` blocksSeen'
  546. in case uniqSetToList badDests of
  547. [] -> go blocksSeen' sccs
  548. bad : _ -> Just bad
  549. go blocksSeen (CyclicSCC blocks : sccs)
  550. = let dests = unionManyUniqSets $ map slurpJumpDestsOfBlock blocks
  551. blocksSeen' = unionUniqSets blocksSeen $ mkUniqSet $ map blockId blocks
  552. badDests = dests `minusUniqSet` blocksSeen'
  553. in case uniqSetToList badDests of
  554. [] -> go blocksSeen' sccs
  555. bad : _ -> Just bad
  556. slurpJumpDestsOfBlock (BasicBlock _ instrs)
  557. = unionManyUniqSets
  558. $ map (mkUniqSet . jumpDestsOfInstr)
  559. [ i | LiveInstr i _ <- instrs]
  560. -- | If we've compute liveness info for this code already we have to reverse
  561. -- the SCCs in each top to get them back to the right order so we can do it again.
  562. reverseBlocksInTops :: LiveCmmTop instr -> LiveCmmTop instr
  563. reverseBlocksInTops top
  564. = case top of
  565. CmmData{} -> top
  566. CmmProc info lbl params sccs -> CmmProc info lbl params (reverse sccs)
  567. -- | Computing liveness
  568. --
  569. -- On entry, the SCCs must be in "reverse" order: later blocks may transfer
  570. -- control to earlier ones only, else `panic`.
  571. --
  572. -- The SCCs returned are in the *opposite* order, which is exactly what we
  573. -- want for the next pass.
  574. --
  575. computeLiveness
  576. :: (Outputable instr, Instruction instr)
  577. => [SCC (LiveBasicBlock instr)]
  578. -> ([SCC (LiveBasicBlock instr)], -- instructions annotated with list of registers
  579. -- which are "dead after this instruction".
  580. BlockMap RegSet) -- blocks annontated with set of live registers
  581. -- on entry to the block.
  582. computeLiveness sccs
  583. = case checkIsReverseDependent sccs of
  584. Nothing -> livenessSCCs emptyBlockMap [] sccs
  585. Just bad -> pprPanic "RegAlloc.Liveness.computeLivenss"
  586. (vcat [ text "SCCs aren't in reverse dependent order"
  587. , text "bad blockId" <+> ppr bad
  588. , ppr sccs])
  589. livenessSCCs
  590. :: Instruction instr
  591. => BlockMap RegSet
  592. -> [SCC (LiveBasicBlock instr)] -- accum
  593. -> [SCC (LiveBasicBlock instr)]
  594. -> ( [SCC (LiveBasicBlock instr)]
  595. , BlockMap RegSet)
  596. livenessSCCs blockmap done []
  597. = (done, blockmap)
  598. livenessSCCs blockmap done (AcyclicSCC block : sccs)
  599. = let (blockmap', block') = livenessBlock blockmap block
  600. in livenessSCCs blockmap' (AcyclicSCC block' : done) sccs
  601. livenessSCCs blockmap done
  602. (CyclicSCC blocks : sccs) =
  603. livenessSCCs blockmap' (CyclicSCC blocks':done) sccs
  604. where (blockmap', blocks')
  605. = iterateUntilUnchanged linearLiveness equalBlockMaps
  606. blockmap blocks
  607. iterateUntilUnchanged
  608. :: (a -> b -> (a,c)) -> (a -> a -> Bool)
  609. -> a -> b
  610. -> (a,c)
  611. iterateUntilUnchanged f eq a b
  612. = head $
  613. concatMap tail $
  614. groupBy (\(a1, _) (a2, _) -> eq a1 a2) $
  615. iterate (\(a, _) -> f a b) $
  616. (a, panic "RegLiveness.livenessSCCs")
  617. linearLiveness
  618. :: Instruction instr
  619. => BlockMap RegSet -> [LiveBasicBlock instr]
  620. -> (BlockMap RegSet, [LiveBasicBlock instr])
  621. linearLiveness = mapAccumL livenessBlock
  622. -- probably the least efficient way to compare two
  623. -- BlockMaps for equality.
  624. equalBlockMaps a b
  625. = a' == b'
  626. where a' = map f $ blockEnvToList a
  627. b' = map f $ blockEnvToList b
  628. f (key,elt) = (key, uniqSetToList elt)
  629. -- | Annotate a basic block with register liveness information.
  630. --
  631. livenessBlock
  632. :: Instruction instr
  633. => BlockMap RegSet
  634. -> LiveBasicBlock instr
  635. -> (BlockMap RegSet, LiveBasicBlock instr)
  636. livenessBlock blockmap (BasicBlock block_id instrs)
  637. = let
  638. (regsLiveOnEntry, instrs1)
  639. = livenessBack emptyUniqSet blockmap [] (reverse instrs)
  640. blockmap' = extendBlockEnv blockmap block_id regsLiveOnEntry
  641. instrs2 = livenessForward regsLiveOnEntry instrs1
  642. output = BasicBlock block_id instrs2
  643. in ( blockmap', output)
  644. -- | Calculate liveness going forwards,
  645. -- filling in when regs are born
  646. livenessForward
  647. :: Instruction instr
  648. => RegSet -- regs live on this instr
  649. -> [LiveInstr instr] -> [LiveInstr instr]
  650. livenessForward _ [] = []
  651. livenessForward rsLiveEntry (li@(LiveInstr instr mLive) : lis)
  652. | Nothing <- mLive
  653. = li : livenessForward rsLiveEntry lis
  654. | Just live <- mLive
  655. , RU _ written <- regUsageOfInstr instr
  656. = let
  657. -- Regs that are written to but weren't live on entry to this instruction
  658. -- are recorded as being born here.
  659. rsBorn = mkUniqSet
  660. $ filter (\r -> not $ elementOfUniqSet r rsLiveEntry) written
  661. rsLiveNext = (rsLiveEntry `unionUniqSets` rsBorn)
  662. `minusUniqSet` (liveDieRead live)
  663. `minusUniqSet` (liveDieWrite live)
  664. in LiveInstr instr (Just live { liveBorn = rsBorn })
  665. : livenessForward rsLiveNext lis
  666. livenessForward _ _ = panic "RegLiveness.livenessForward: no match"
  667. -- | Calculate liveness going backwards,
  668. -- filling in when regs die, and what regs are live across each instruction
  669. livenessBack
  670. :: Instruction instr
  671. => RegSet -- regs live on this instr
  672. -> BlockMap RegSet -- regs live on entry to other BBs
  673. -> [LiveInstr instr] -- instructions (accum)
  674. -> [LiveInstr instr] -- instructions
  675. -> (RegSet, [LiveInstr instr])
  676. livenessBack liveregs _ done [] = (liveregs, done)
  677. livenessBack liveregs blockmap acc (instr : instrs)
  678. = let (liveregs', instr') = liveness1 liveregs blockmap instr
  679. in livenessBack liveregs' blockmap (instr' : acc) instrs
  680. -- don't bother tagging comments or deltas with liveness
  681. liveness1
  682. :: Instruction instr
  683. => RegSet
  684. -> BlockMap RegSet
  685. -> LiveInstr instr
  686. -> (RegSet, LiveInstr instr)
  687. liveness1 liveregs _ (LiveInstr instr _)
  688. | isMetaInstr instr
  689. = (liveregs, LiveInstr instr Nothing)
  690. liveness1 liveregs blockmap (LiveInstr instr _)
  691. | not_a_branch
  692. = (liveregs1, LiveInstr instr
  693. (Just $ Liveness
  694. { liveBorn = emptyUniqSet
  695. , liveDieRead = mkUniqSet r_dying
  696. , liveDieWrite = mkUniqSet w_dying }))
  697. | otherwise
  698. = (liveregs_br, LiveInstr instr
  699. (Just $ Liveness
  700. { liveBorn = emptyUniqSet
  701. , liveDieRead = mkUniqSet r_dying_br
  702. , liveDieWrite = mkUniqSet w_dying }))
  703. where
  704. RU read written = regUsageOfInstr instr
  705. -- registers that were written here are dead going backwards.
  706. -- registers that were read here are live going backwards.
  707. liveregs1 = (liveregs `delListFromUniqSet` written)
  708. `addListToUniqSet` read
  709. -- registers that are not live beyond this point, are recorded
  710. -- as dying here.
  711. r_dying = [ reg | reg <- read, reg `notElem` written,
  712. not (elementOfUniqSet reg liveregs) ]
  713. w_dying = [ reg | reg <- written,
  714. not (elementOfUniqSet reg liveregs) ]
  715. -- union in the live regs from all the jump destinations of this
  716. -- instruction.
  717. targets = jumpDestsOfInstr instr -- where we go from here
  718. not_a_branch = null targets
  719. targetLiveRegs target
  720. = case lookupBlockEnv blockmap target of
  721. Just ra -> ra
  722. Nothing -> emptyRegMap
  723. live_from_branch = unionManyUniqSets (map targetLiveRegs targets)
  724. liveregs_br = liveregs1 `unionUniqSets` live_from_branch
  725. -- registers that are live only in the branch targets should
  726. -- be listed as dying here.
  727. live_branch_only = live_from_branch `minusUniqSet` liveregs
  728. r_dying_br = uniqSetToList (mkUniqSet r_dying `unionUniqSets`
  729. live_branch_only)