2 -- | Register coalescing.
6 -- The above warning supression flag is a temporary kludge.
7 -- While working on this module you are encouraged to remove it and fix
8 -- any warnings in the module. See
9 -- http://hackage.haskell.org/trac/ghc/wiki/WorkingConventions#Warnings
32 -- | Do register coalescing on this top level thing
33 -- For Reg -> Reg moves, if the first reg dies at the same time the second reg is born
34 -- then the mov only serves to join live ranges. The two regs can be renamed to be
35 -- the same and the move instruction safely erased.
37 regCoalesce :: [LiveCmmTop] -> UniqSM [LiveCmmTop]
40 let joins = foldl' unionBags emptyBag
41 $ map slurpJoinMovs code
43 let alloc = foldl' buildAlloc emptyUFM
46 let patched = map (patchEraseLive (sinkReg alloc)) code
51 buildAlloc :: UniqFM Reg -> (Reg, Reg) -> UniqFM Reg
52 buildAlloc fm (r1, r2)
53 = let rmin = min r1 r2
55 in addToUFM fm rmax rmin
57 sinkReg :: UniqFM Reg -> Reg -> Reg
59 = case lookupUFM fm r of
61 Just r' -> sinkReg fm r'
64 -- | Slurp out mov instructions that only serve to join live ranges.
65 -- During a mov, if the source reg dies and the destiation reg is born
66 -- then we can rename the two regs to the same thing and eliminate the move.
68 slurpJoinMovs :: LiveCmmTop -> Bag (Reg, Reg)
70 = slurpCmm emptyBag live
72 slurpCmm rs CmmData{} = rs
73 slurpCmm rs (CmmProc _ _ _ blocks) = foldl' slurpComp rs blocks
74 slurpComp rs (BasicBlock i blocks) = foldl' slurpBlock rs blocks
75 slurpBlock rs (BasicBlock i instrs) = foldl' slurpLI rs instrs
77 slurpLI rs (Instr _ Nothing) = rs
78 slurpLI rs (Instr instr (Just live))
79 | Just (r1, r2) <- isRegRegMove instr
80 , elementOfUniqSet r1 $ liveDieRead live
81 , elementOfUniqSet r2 $ liveBorn live
83 -- only coalesce movs between two virtuals for now, else we end up with
84 -- allocatable regs in the live regs list..
85 , isVirtualReg r1 && isVirtualReg r2