never executed always true always false
1 -- | An architecture independent description of a register.
2 -- This needs to stay architecture independent because it is used
3 -- by NCGMonad and the register allocators, which are shared
4 -- by all architectures.
5 --
6 module GHC.Platform.Reg (
7 RegNo,
8 Reg(..),
9 regPair,
10 regSingle,
11 realRegSingle,
12 isRealReg, takeRealReg,
13 isVirtualReg, takeVirtualReg,
14
15 VirtualReg(..),
16 renameVirtualReg,
17 classOfVirtualReg,
18 getHiVirtualRegFromLo,
19 getHiVRegFromLo,
20
21 RealReg(..),
22 regNosOfRealReg,
23 realRegsAlias,
24
25 liftPatchFnToRegReg
26 )
27
28 where
29
30 import GHC.Prelude
31
32 import GHC.Utils.Outputable
33 import GHC.Utils.Panic
34 import GHC.Types.Unique
35 import GHC.Builtin.Uniques
36 import GHC.Platform.Reg.Class
37
38 -- | An identifier for a primitive real machine register.
39 type RegNo
40 = Int
41
42 -- VirtualRegs are virtual registers. The register allocator will
43 -- eventually have to map them into RealRegs, or into spill slots.
44 --
45 -- VirtualRegs are allocated on the fly, usually to represent a single
46 -- value in the abstract assembly code (i.e. dynamic registers are
47 -- usually single assignment).
48 --
49 -- The single assignment restriction isn't necessary to get correct code,
50 -- although a better register allocation will result if single
51 -- assignment is used -- because the allocator maps a VirtualReg into
52 -- a single RealReg, even if the VirtualReg has multiple live ranges.
53 --
54 -- Virtual regs can be of either class, so that info is attached.
55 --
56 data VirtualReg
57 = VirtualRegI {-# UNPACK #-} !Unique
58 | VirtualRegHi {-# UNPACK #-} !Unique -- High part of 2-word register
59 | VirtualRegF {-# UNPACK #-} !Unique
60 | VirtualRegD {-# UNPACK #-} !Unique
61
62 deriving (Eq, Show)
63
64 -- This is laborious, but necessary. We can't derive Ord because
65 -- Unique doesn't have an Ord instance. Note nonDetCmpUnique in the
66 -- implementation. See Note [No Ord for Unique]
67 -- This is non-deterministic but we do not currently support deterministic
68 -- code-generation. See Note [Unique Determinism and code generation]
69 instance Ord VirtualReg where
70 compare (VirtualRegI a) (VirtualRegI b) = nonDetCmpUnique a b
71 compare (VirtualRegHi a) (VirtualRegHi b) = nonDetCmpUnique a b
72 compare (VirtualRegF a) (VirtualRegF b) = nonDetCmpUnique a b
73 compare (VirtualRegD a) (VirtualRegD b) = nonDetCmpUnique a b
74
75 compare VirtualRegI{} _ = LT
76 compare _ VirtualRegI{} = GT
77 compare VirtualRegHi{} _ = LT
78 compare _ VirtualRegHi{} = GT
79 compare VirtualRegF{} _ = LT
80 compare _ VirtualRegF{} = GT
81
82
83
84 instance Uniquable VirtualReg where
85 getUnique reg
86 = case reg of
87 VirtualRegI u -> u
88 VirtualRegHi u -> u
89 VirtualRegF u -> u
90 VirtualRegD u -> u
91
92 instance Outputable VirtualReg where
93 ppr reg
94 = case reg of
95 VirtualRegI u -> text "%vI_" <> pprUniqueAlways u
96 VirtualRegHi u -> text "%vHi_" <> pprUniqueAlways u
97 -- this code is kinda wrong on x86
98 -- because float and double occupy the same register set
99 -- namely SSE2 register xmm0 .. xmm15
100 VirtualRegF u -> text "%vFloat_" <> pprUniqueAlways u
101 VirtualRegD u -> text "%vDouble_" <> pprUniqueAlways u
102
103
104
105 renameVirtualReg :: Unique -> VirtualReg -> VirtualReg
106 renameVirtualReg u r
107 = case r of
108 VirtualRegI _ -> VirtualRegI u
109 VirtualRegHi _ -> VirtualRegHi u
110 VirtualRegF _ -> VirtualRegF u
111 VirtualRegD _ -> VirtualRegD u
112
113
114 classOfVirtualReg :: VirtualReg -> RegClass
115 classOfVirtualReg vr
116 = case vr of
117 VirtualRegI{} -> RcInteger
118 VirtualRegHi{} -> RcInteger
119 VirtualRegF{} -> RcFloat
120 VirtualRegD{} -> RcDouble
121
122
123
124 -- Determine the upper-half vreg for a 64-bit quantity on a 32-bit platform
125 -- when supplied with the vreg for the lower-half of the quantity.
126 -- (NB. Not reversible).
127 getHiVirtualRegFromLo :: VirtualReg -> VirtualReg
128 getHiVirtualRegFromLo reg
129 = case reg of
130 -- makes a pseudo-unique with tag 'H'
131 VirtualRegI u -> VirtualRegHi (newTagUnique u 'H')
132 _ -> panic "Reg.getHiVirtualRegFromLo"
133
134 getHiVRegFromLo :: Reg -> Reg
135 getHiVRegFromLo reg
136 = case reg of
137 RegVirtual vr -> RegVirtual (getHiVirtualRegFromLo vr)
138 RegReal _ -> panic "Reg.getHiVRegFromLo"
139
140
141 ------------------------------------------------------------------------------------
142 -- | RealRegs are machine regs which are available for allocation, in
143 -- the usual way. We know what class they are, because that's part of
144 -- the processor's architecture.
145 --
146 -- RealRegPairs are pairs of real registers that are allocated together
147 -- to hold a larger value, such as with Double regs on SPARC.
148 --
149 data RealReg
150 = RealRegSingle {-# UNPACK #-} !RegNo
151 | RealRegPair {-# UNPACK #-} !RegNo {-# UNPACK #-} !RegNo
152 deriving (Eq, Show, Ord)
153
154 instance Uniquable RealReg where
155 getUnique reg
156 = case reg of
157 RealRegSingle i -> mkRegSingleUnique i
158 RealRegPair r1 r2 -> mkRegPairUnique (r1 * 65536 + r2)
159
160 instance Outputable RealReg where
161 ppr reg
162 = case reg of
163 RealRegSingle i -> text "%r" <> int i
164 RealRegPair r1 r2 -> text "%r(" <> int r1
165 <> vbar <> int r2 <> text ")"
166
167 regNosOfRealReg :: RealReg -> [RegNo]
168 regNosOfRealReg rr
169 = case rr of
170 RealRegSingle r1 -> [r1]
171 RealRegPair r1 r2 -> [r1, r2]
172
173
174 realRegsAlias :: RealReg -> RealReg -> Bool
175 realRegsAlias rr1 rr2 =
176 -- used to be `not $ null $ intersect (regNosOfRealReg rr1) (regNosOfRealReg rr2)`
177 -- but that resulted in some gnarly, gnarly, allocating code. So we manually
178 -- write out all the cases which gives us nice non-allocating code.
179 case rr1 of
180 RealRegSingle r1 ->
181 case rr2 of RealRegPair r2 r3 -> r1 == r2 || r1 == r3
182 RealRegSingle r2 -> r1 == r2
183 RealRegPair r1 r2 ->
184 case rr2 of RealRegPair r3 r4 -> r1 == r3 || r1 == r4 || r2 == r3 || r2 == r4
185 RealRegSingle r3 -> r1 == r3 || r2 == r3
186
187 --------------------------------------------------------------------------------
188 -- | A register, either virtual or real
189 data Reg
190 = RegVirtual !VirtualReg
191 | RegReal !RealReg
192 deriving (Eq, Ord, Show)
193
194 regSingle :: RegNo -> Reg
195 regSingle regNo = RegReal (realRegSingle regNo)
196
197 realRegSingle :: RegNo -> RealReg
198 realRegSingle regNo = RealRegSingle regNo
199
200 regPair :: RegNo -> RegNo -> Reg
201 regPair regNo1 regNo2 = RegReal $ RealRegPair regNo1 regNo2
202
203
204 -- We like to have Uniques for Reg so that we can make UniqFM and UniqSets
205 -- in the register allocator.
206 instance Uniquable Reg where
207 getUnique reg
208 = case reg of
209 RegVirtual vr -> getUnique vr
210 RegReal rr -> getUnique rr
211
212 -- | Print a reg in a generic manner
213 -- If you want the architecture specific names, then use the pprReg
214 -- function from the appropriate Ppr module.
215 instance Outputable Reg where
216 ppr reg
217 = case reg of
218 RegVirtual vr -> ppr vr
219 RegReal rr -> ppr rr
220
221
222 isRealReg :: Reg -> Bool
223 isRealReg reg
224 = case reg of
225 RegReal _ -> True
226 RegVirtual _ -> False
227
228 takeRealReg :: Reg -> Maybe RealReg
229 takeRealReg reg
230 = case reg of
231 RegReal rr -> Just rr
232 _ -> Nothing
233
234
235 isVirtualReg :: Reg -> Bool
236 isVirtualReg reg
237 = case reg of
238 RegReal _ -> False
239 RegVirtual _ -> True
240
241 takeVirtualReg :: Reg -> Maybe VirtualReg
242 takeVirtualReg reg
243 = case reg of
244 RegReal _ -> Nothing
245 RegVirtual vr -> Just vr
246
247
248 -- | The patch function supplied by the allocator maps VirtualReg to RealReg
249 -- regs, but sometimes we want to apply it to plain old Reg.
250 --
251 liftPatchFnToRegReg :: (VirtualReg -> RealReg) -> (Reg -> Reg)
252 liftPatchFnToRegReg patchF reg
253 = case reg of
254 RegVirtual vr -> RegReal (patchF vr)
255 RegReal _ -> reg