PageRenderTime 1491ms CodeModel.GetById 43ms RepoModel.GetById 1ms app.codeStats 0ms

/compiler/nativeGen/RegAlloc/Liveness.hs

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