1 -- | Register coalescing.
24 -- | Do register coalescing on this top level thing
25 -- For Reg -> Reg moves, if the first reg dies at the same time the second reg is born
26 -- then the mov only serves to join live ranges. The two regs can be renamed to be
27 -- the same and the move instruction safely erased.
29 regCoalesce :: [LiveCmmTop] -> UniqSM [LiveCmmTop]
32 let joins = foldl' unionBags emptyBag
33 $ map slurpJoinMovs code
35 let alloc = foldl' buildAlloc emptyUFM
38 let patched = map (patchEraseLive (sinkReg alloc)) code
43 buildAlloc :: UniqFM Reg -> (Reg, Reg) -> UniqFM Reg
44 buildAlloc fm (r1, r2)
45 = let rmin = min r1 r2
47 in addToUFM fm rmax rmin
49 sinkReg :: UniqFM Reg -> Reg -> Reg
51 = case lookupUFM fm r of
53 Just r' -> sinkReg fm r'
56 -- | Slurp out mov instructions that only serve to join live ranges.
57 -- During a mov, if the source reg dies and the destiation reg is born
58 -- then we can rename the two regs to the same thing and eliminate the move.
60 slurpJoinMovs :: LiveCmmTop -> Bag (Reg, Reg)
62 = slurpCmm emptyBag live
64 slurpCmm rs CmmData{} = rs
65 slurpCmm rs (CmmProc _ _ _ (ListGraph blocks)) = foldl' slurpComp rs blocks
66 slurpComp rs (BasicBlock _ blocks) = foldl' slurpBlock rs blocks
67 slurpBlock rs (BasicBlock _ instrs) = foldl' slurpLI rs instrs
69 slurpLI rs (Instr _ Nothing) = rs
70 slurpLI rs (Instr instr (Just live))
71 | Just (r1, r2) <- isRegRegMove instr
72 , elementOfUniqSet r1 $ liveDieRead live
73 , elementOfUniqSet r2 $ liveBorn live
75 -- only coalesce movs between two virtuals for now, else we end up with
76 -- allocatable regs in the live regs list..
77 , isVirtualReg r1 && isVirtualReg r2