Add graph coloring register allocator.
[ghc-hetmet.git] / compiler / nativeGen / RegArchX86.hs
1
2 -- | A description of the register set of the X86.
3 --      This isn't used directly in GHC proper.
4 --
5 --      See RegArchBase.hs for the reference.
6 --      See MachRegs.hs for the actual trivColorable function used in GHC.
7 --
8 module RegArchX86 (
9         classOfReg,
10         regsOfClass,
11         regName,
12         regAlias,
13         worst,
14         squeese,
15 ) where
16
17 import RegArchBase              (Reg(..), RegSub(..), RegClass(..))
18
19 import qualified Data.Set       as Set
20 import Data.Set                 (Set)
21
22 -- | Determine the class of a register
23 classOfReg :: Reg -> RegClass
24 classOfReg reg
25  = case reg of
26         Reg c i         -> c
27         
28         RegSub SubL16 r -> ClassG16
29         RegSub SubL8  r -> ClassG8
30         RegSub SubL8H r -> ClassG8
31
32         
33 -- | Determine all the regs that make up a certain class.
34 --
35 regsOfClass :: RegClass -> Set Reg
36 regsOfClass c
37  = case c of
38         ClassG32        
39          -> Set.fromList [ Reg ClassG32  i                      | i <- [0..7] ]
40
41         ClassG16        
42          -> Set.fromList [ RegSub SubL16 (Reg ClassG32 i)       | i <- [0..7] ]
43
44         ClassG8 
45          -> Set.union
46                 (Set.fromList [ RegSub SubL8  (Reg ClassG32 i)  | i <- [0..3] ])
47                 (Set.fromList [ RegSub SubL8H (Reg ClassG32 i)  | i <- [0..3] ])
48                         
49         ClassF64        
50          -> Set.fromList [ Reg ClassF64  i                      | i <- [0..5] ]
51         
52
53 -- | Determine the common name of a reg
54 --      returns Nothing if this reg is not part of the machine.
55         
56 regName :: Reg -> Maybe String
57 regName reg
58  = case reg of
59         Reg ClassG32 i  
60          | i <= 7       -> Just ([ "eax", "ebx", "ecx", "edx", "ebp", "esi", "edi", "esp" ] !! i)
61
62         RegSub SubL16 (Reg ClassG32 i)
63          | i <= 7       -> Just ([ "ax", "bx", "cx", "dx", "bp", "si", "di", "sp"] !! i)
64          
65         RegSub SubL8  (Reg ClassG32 i)
66          | i <= 3       -> Just ([ "al", "bl", "cl", "dl"] !! i)
67          
68         RegSub SubL8H (Reg ClassG32 i)
69          | i <= 3       -> Just ([ "ah", "bh", "ch", "dh"] !! i)
70
71         _               -> Nothing
72
73         
74 -- | Which regs alias what other regs
75 regAlias :: Reg -> Set Reg
76 regAlias reg
77  = case reg of
78
79         -- 32 bit regs alias all of the subregs
80         Reg ClassG32 i
81          
82          -- for eax, ebx, ecx, eds
83          |  i <= 3              
84          -> Set.fromList $ [ Reg ClassG32 i, RegSub SubL16 reg, RegSub SubL8 reg, RegSub SubL8H reg ]
85          
86          -- for esi, edi, esp, ebp
87          | 4 <= i && i <= 7     
88          -> Set.fromList $ [ Reg ClassG32 i, RegSub SubL16 reg ]
89         
90         
91         -- 16 bit subregs alias the whole reg
92         RegSub SubL16 r@(Reg ClassG32 i)        
93          ->     regAlias r
94         
95         -- 8 bit subregs alias the 32 and 16, but not the other 8 bit subreg
96         RegSub SubL8  r@(Reg ClassG32 i)
97          -> Set.fromList $ [ r, RegSub SubL16 r, RegSub SubL8 r ]
98
99         RegSub SubL8H r@(Reg ClassG32 i)
100          -> Set.fromList $ [ r, RegSub SubL16 r, RegSub SubL8H r ]
101         
102         -- fp
103         Reg ClassF64 i  
104          -> Set.singleton reg
105
106         _ -> error "regAlias: invalid register"
107
108
109 -- | Optimised versions of RegColorBase.{worst, squeese} specific to x86
110
111 worst :: Int -> RegClass -> RegClass -> Int
112 worst n classN classC
113  = case classN of
114         ClassG32
115          -> case classC of
116                 ClassG32        -> min n 8
117                 ClassG16        -> min n 8
118                 ClassG8         -> min n 4
119                 ClassF64        -> 0
120                 
121         ClassG16
122          -> case classC of
123                 ClassG32        -> min n 8
124                 ClassG16        -> min n 8
125                 ClassG8         -> min n 4
126                 ClassF64        -> 0
127                 
128         ClassG8
129          -> case classC of
130                 ClassG32        -> min (n*2) 8
131                 ClassG16        -> min (n*2) 8
132                 ClassG8         -> min n 8
133                 ClassF64        -> 0
134                 
135         ClassF64
136          -> case classC of
137                 ClassF64        -> min n 6
138                 _               -> 0
139                 
140 squeese :: RegClass -> [(Int, RegClass)] -> Int
141 squeese classN countCs
142         = sum (map (\(i, classC) -> worst i classN classC) countCs)
143         
144
145
146
147