Make StgWord a portable type too
[ghc.git] / compiler / cmm / CmmUtils.hs
1 {-# LANGUAGE GADTs #-}
2
3 {-# OPTIONS_GHC -fno-warn-deprecations #-}
4 -- Warnings from deprecated blockToNodeList
5
6
7 -----------------------------------------------------------------------------
8 --
9 -- Cmm utilities.
10 --
11 -- (c) The University of Glasgow 2004-2006
12 --
13 -----------------------------------------------------------------------------
14
15 module CmmUtils(
16 -- CmmType
17 primRepCmmType, primRepForeignHint,
18 typeCmmType, typeForeignHint,
19
20 -- CmmLit
21 zeroCLit, mkIntCLit,
22 mkWordCLit, packHalfWordsCLit,
23 mkByteStringCLit,
24 mkDataLits, mkRODataLits,
25
26 -- CmmExpr
27 mkIntExpr, zeroExpr,
28 mkLblExpr,
29 cmmRegOff, cmmOffset, cmmLabelOff, cmmOffsetLit, cmmOffsetExpr,
30 cmmRegOffB, cmmOffsetB, cmmLabelOffB, cmmOffsetLitB, cmmOffsetExprB,
31 cmmRegOffW, cmmOffsetW, cmmLabelOffW, cmmOffsetLitW, cmmOffsetExprW,
32 cmmIndex, cmmIndexExpr, cmmLoadIndex, cmmLoadIndexW,
33 cmmNegate,
34 cmmULtWord, cmmUGeWord, cmmUGtWord, cmmSubWord,
35 cmmNeWord, cmmEqWord, cmmOrWord, cmmAndWord,
36 cmmUShrWord, cmmAddWord, cmmMulWord, cmmQuotWord,
37
38 isTrivialCmmExpr, hasNoGlobalRegs,
39
40 -- Statics
41 blankWord,
42
43 -- Tagging
44 cmmTagMask, cmmPointerMask, cmmUntag, cmmGetTag, cmmIsTagged,
45 cmmConstrTag, cmmConstrTag1,
46
47 -- Liveness and bitmaps
48 mkLiveness,
49
50 -- * Operations that probably don't belong here
51 modifyGraph,
52
53 lastNode, replaceLastNode,
54 ofBlockMap, toBlockMap, insertBlock,
55 ofBlockList, toBlockList, bodyToBlockList,
56 foldGraphBlocks, mapGraphNodes, postorderDfs, mapGraphNodes1,
57
58 analFwd, analBwd, analRewFwd, analRewBwd,
59 dataflowPassFwd, dataflowPassBwd, dataflowAnalFwd, dataflowAnalBwd,
60 dataflowAnalFwdBlocks
61 ) where
62
63 #include "HsVersions.h"
64
65 import TyCon ( PrimRep(..) )
66 import Type ( UnaryType, typePrimRep )
67
68 import SMRep
69 import Cmm
70 import BlockId
71 import CLabel
72 import Outputable
73 import Unique
74 import UniqSupply
75 import DynFlags
76 import Util
77
78 import Data.Word
79 import Data.Maybe
80 import Data.Bits
81 import Hoopl
82
83 ---------------------------------------------------
84 --
85 -- CmmTypes
86 --
87 ---------------------------------------------------
88
89 primRepCmmType :: DynFlags -> PrimRep -> CmmType
90 primRepCmmType _ VoidRep = panic "primRepCmmType:VoidRep"
91 primRepCmmType dflags PtrRep = gcWord dflags
92 primRepCmmType dflags IntRep = bWord dflags
93 primRepCmmType dflags WordRep = bWord dflags
94 primRepCmmType _ Int64Rep = b64
95 primRepCmmType _ Word64Rep = b64
96 primRepCmmType dflags AddrRep = bWord dflags
97 primRepCmmType _ FloatRep = f32
98 primRepCmmType _ DoubleRep = f64
99
100 typeCmmType :: DynFlags -> UnaryType -> CmmType
101 typeCmmType dflags ty = primRepCmmType dflags (typePrimRep ty)
102
103 primRepForeignHint :: PrimRep -> ForeignHint
104 primRepForeignHint VoidRep = panic "primRepForeignHint:VoidRep"
105 primRepForeignHint PtrRep = AddrHint
106 primRepForeignHint IntRep = SignedHint
107 primRepForeignHint WordRep = NoHint
108 primRepForeignHint Int64Rep = SignedHint
109 primRepForeignHint Word64Rep = NoHint
110 primRepForeignHint AddrRep = AddrHint -- NB! AddrHint, but NonPtrArg
111 primRepForeignHint FloatRep = NoHint
112 primRepForeignHint DoubleRep = NoHint
113
114 typeForeignHint :: UnaryType -> ForeignHint
115 typeForeignHint = primRepForeignHint . typePrimRep
116
117 ---------------------------------------------------
118 --
119 -- CmmLit
120 --
121 ---------------------------------------------------
122
123 mkIntCLit :: DynFlags -> Int -> CmmLit
124 mkIntCLit dflags i = CmmInt (toInteger i) (wordWidth dflags)
125
126 mkIntExpr :: DynFlags -> Int -> CmmExpr
127 mkIntExpr dflags i = CmmLit $! mkIntCLit dflags i
128
129 zeroCLit :: DynFlags -> CmmLit
130 zeroCLit dflags = CmmInt 0 (wordWidth dflags)
131
132 zeroExpr :: DynFlags -> CmmExpr
133 zeroExpr dflags = CmmLit (zeroCLit dflags)
134
135 mkByteStringCLit :: Unique -> [Word8] -> (CmmLit, GenCmmDecl CmmStatics info stmt)
136 -- We have to make a top-level decl for the string,
137 -- and return a literal pointing to it
138 mkByteStringCLit uniq bytes
139 = (CmmLabel lbl, CmmData ReadOnlyData $ Statics lbl [CmmString bytes])
140 where
141 lbl = mkStringLitLabel uniq
142 mkDataLits :: Section -> CLabel -> [CmmLit] -> GenCmmDecl CmmStatics info stmt
143 -- Build a data-segment data block
144 mkDataLits section lbl lits
145 = CmmData section (Statics lbl $ map CmmStaticLit lits)
146
147 mkRODataLits :: CLabel -> [CmmLit] -> GenCmmDecl CmmStatics info stmt
148 -- Build a read-only data block
149 mkRODataLits lbl lits
150 = mkDataLits section lbl lits
151 where
152 section | any needsRelocation lits = RelocatableReadOnlyData
153 | otherwise = ReadOnlyData
154 needsRelocation (CmmLabel _) = True
155 needsRelocation (CmmLabelOff _ _) = True
156 needsRelocation _ = False
157
158 mkWordCLit :: DynFlags -> StgWord -> CmmLit
159 mkWordCLit dflags wd = CmmInt (fromStgWord wd) (wordWidth dflags)
160
161 packHalfWordsCLit :: DynFlags -> StgHalfWord -> StgHalfWord -> CmmLit
162 -- Make a single word literal in which the lower_half_word is
163 -- at the lower address, and the upper_half_word is at the
164 -- higher address
165 -- ToDo: consider using half-word lits instead
166 -- but be careful: that's vulnerable when reversed
167 packHalfWordsCLit dflags lower_half_word upper_half_word
168 = if wORDS_BIGENDIAN dflags
169 then mkWordCLit dflags ((l `shiftL` hALF_WORD_SIZE_IN_BITS) .|. u)
170 else mkWordCLit dflags (l .|. (u `shiftL` hALF_WORD_SIZE_IN_BITS))
171 where l = toStgWord dflags (fromStgHalfWord lower_half_word)
172 u = toStgWord dflags (fromStgHalfWord upper_half_word)
173
174 ---------------------------------------------------
175 --
176 -- CmmExpr
177 --
178 ---------------------------------------------------
179
180 mkLblExpr :: CLabel -> CmmExpr
181 mkLblExpr lbl = CmmLit (CmmLabel lbl)
182
183 cmmOffsetExpr :: DynFlags -> CmmExpr -> CmmExpr -> CmmExpr
184 -- assumes base and offset have the same CmmType
185 cmmOffsetExpr dflags e (CmmLit (CmmInt n _)) = cmmOffset dflags e (fromInteger n)
186 cmmOffsetExpr dflags e byte_off = CmmMachOp (MO_Add (cmmExprWidth dflags e)) [e, byte_off]
187
188 -- NB. Do *not* inspect the value of the offset in these smart constructors!!!
189 -- because the offset is sometimes involved in a loop in the code generator
190 -- (we don't know the real Hp offset until we've generated code for the entire
191 -- basic block, for example). So we cannot eliminate zero offsets at this
192 -- stage; they're eliminated later instead (either during printing or
193 -- a later optimisation step on Cmm).
194 --
195 cmmOffset :: DynFlags -> CmmExpr -> Int -> CmmExpr
196 cmmOffset _ e 0 = e
197 cmmOffset _ (CmmReg reg) byte_off = cmmRegOff reg byte_off
198 cmmOffset _ (CmmRegOff reg m) byte_off = cmmRegOff reg (m+byte_off)
199 cmmOffset _ (CmmLit lit) byte_off = CmmLit (cmmOffsetLit lit byte_off)
200 cmmOffset _ (CmmMachOp (MO_Add rep) [expr, CmmLit (CmmInt byte_off1 _rep)]) byte_off2
201 = CmmMachOp (MO_Add rep)
202 [expr, CmmLit (CmmInt (byte_off1 + toInteger byte_off2) rep)]
203 cmmOffset dflags expr byte_off
204 = CmmMachOp (MO_Add width) [expr, CmmLit (CmmInt (toInteger byte_off) width)]
205 where
206 width = cmmExprWidth dflags expr
207
208 -- Smart constructor for CmmRegOff. Same caveats as cmmOffset above.
209 cmmRegOff :: CmmReg -> Int -> CmmExpr
210 cmmRegOff reg byte_off = CmmRegOff reg byte_off
211
212 cmmOffsetLit :: CmmLit -> Int -> CmmLit
213 cmmOffsetLit (CmmLabel l) byte_off = cmmLabelOff l byte_off
214 cmmOffsetLit (CmmLabelOff l m) byte_off = cmmLabelOff l (m+byte_off)
215 cmmOffsetLit (CmmInt m rep) byte_off = CmmInt (m + fromIntegral byte_off) rep
216 cmmOffsetLit _ byte_off = pprPanic "cmmOffsetLit" (ppr byte_off)
217
218 cmmLabelOff :: CLabel -> Int -> CmmLit
219 -- Smart constructor for CmmLabelOff
220 cmmLabelOff lbl 0 = CmmLabel lbl
221 cmmLabelOff lbl byte_off = CmmLabelOff lbl byte_off
222
223 -- | Useful for creating an index into an array, with a staticaly known offset.
224 -- The type is the element type; used for making the multiplier
225 cmmIndex :: DynFlags
226 -> Width -- Width w
227 -> CmmExpr -- Address of vector of items of width w
228 -> Int -- Which element of the vector (0 based)
229 -> CmmExpr -- Address of i'th element
230 cmmIndex dflags width base idx = cmmOffset dflags base (idx * widthInBytes width)
231
232 -- | Useful for creating an index into an array, with an unknown offset.
233 cmmIndexExpr :: DynFlags
234 -> Width -- Width w
235 -> CmmExpr -- Address of vector of items of width w
236 -> CmmExpr -- Which element of the vector (0 based)
237 -> CmmExpr -- Address of i'th element
238 cmmIndexExpr dflags width base (CmmLit (CmmInt n _)) = cmmIndex dflags width base (fromInteger n)
239 cmmIndexExpr dflags width base idx =
240 cmmOffsetExpr dflags base byte_off
241 where
242 idx_w = cmmExprWidth dflags idx
243 byte_off = CmmMachOp (MO_Shl idx_w) [idx, mkIntExpr dflags (widthInLog width)]
244
245 cmmLoadIndex :: DynFlags -> CmmType -> CmmExpr -> Int -> CmmExpr
246 cmmLoadIndex dflags ty expr ix = CmmLoad (cmmIndex dflags (typeWidth ty) expr ix) ty
247
248 -- The "B" variants take byte offsets
249 cmmRegOffB :: CmmReg -> ByteOff -> CmmExpr
250 cmmRegOffB = cmmRegOff
251
252 cmmOffsetB :: DynFlags -> CmmExpr -> ByteOff -> CmmExpr
253 cmmOffsetB = cmmOffset
254
255 cmmOffsetExprB :: DynFlags -> CmmExpr -> CmmExpr -> CmmExpr
256 cmmOffsetExprB = cmmOffsetExpr
257
258 cmmLabelOffB :: CLabel -> ByteOff -> CmmLit
259 cmmLabelOffB = cmmLabelOff
260
261 cmmOffsetLitB :: CmmLit -> ByteOff -> CmmLit
262 cmmOffsetLitB = cmmOffsetLit
263
264 -----------------------
265 -- The "W" variants take word offsets
266 cmmOffsetExprW :: DynFlags -> CmmExpr -> CmmExpr -> CmmExpr
267 -- The second arg is a *word* offset; need to change it to bytes
268 cmmOffsetExprW dflags e (CmmLit (CmmInt n _)) = cmmOffsetW dflags e (fromInteger n)
269 cmmOffsetExprW dflags e wd_off = cmmIndexExpr dflags (wordWidth dflags) e wd_off
270
271 cmmOffsetW :: DynFlags -> CmmExpr -> WordOff -> CmmExpr
272 cmmOffsetW dflags e n = cmmOffsetB dflags e (wORD_SIZE dflags * n)
273
274 cmmRegOffW :: DynFlags -> CmmReg -> WordOff -> CmmExpr
275 cmmRegOffW dflags reg wd_off = cmmRegOffB reg (wd_off * wORD_SIZE dflags)
276
277 cmmOffsetLitW :: DynFlags -> CmmLit -> WordOff -> CmmLit
278 cmmOffsetLitW dflags lit wd_off = cmmOffsetLitB lit (wORD_SIZE dflags * wd_off)
279
280 cmmLabelOffW :: DynFlags -> CLabel -> WordOff -> CmmLit
281 cmmLabelOffW dflags lbl wd_off = cmmLabelOffB lbl (wORD_SIZE dflags * wd_off)
282
283 cmmLoadIndexW :: DynFlags -> CmmExpr -> Int -> CmmType -> CmmExpr
284 cmmLoadIndexW dflags base off ty = CmmLoad (cmmOffsetW dflags base off) ty
285
286 -----------------------
287 cmmULtWord, cmmUGeWord, cmmUGtWord, cmmSubWord,
288 cmmNeWord, cmmEqWord, cmmOrWord, cmmAndWord,
289 cmmUShrWord, cmmAddWord, cmmMulWord, cmmQuotWord
290 :: DynFlags -> CmmExpr -> CmmExpr -> CmmExpr
291 cmmOrWord dflags e1 e2 = CmmMachOp (mo_wordOr dflags) [e1, e2]
292 cmmAndWord dflags e1 e2 = CmmMachOp (mo_wordAnd dflags) [e1, e2]
293 cmmNeWord dflags e1 e2 = CmmMachOp (mo_wordNe dflags) [e1, e2]
294 cmmEqWord dflags e1 e2 = CmmMachOp (mo_wordEq dflags) [e1, e2]
295 cmmULtWord dflags e1 e2 = CmmMachOp (mo_wordULt dflags) [e1, e2]
296 cmmUGeWord dflags e1 e2 = CmmMachOp (mo_wordUGe dflags) [e1, e2]
297 cmmUGtWord dflags e1 e2 = CmmMachOp (mo_wordUGt dflags) [e1, e2]
298 --cmmShlWord dflags e1 e2 = CmmMachOp (mo_wordShl dflags) [e1, e2]
299 cmmUShrWord dflags e1 e2 = CmmMachOp (mo_wordUShr dflags) [e1, e2]
300 cmmAddWord dflags e1 e2 = CmmMachOp (mo_wordAdd dflags) [e1, e2]
301 cmmSubWord dflags e1 e2 = CmmMachOp (mo_wordSub dflags) [e1, e2]
302 cmmMulWord dflags e1 e2 = CmmMachOp (mo_wordMul dflags) [e1, e2]
303 cmmQuotWord dflags e1 e2 = CmmMachOp (mo_wordUQuot dflags) [e1, e2]
304
305 cmmNegate :: DynFlags -> CmmExpr -> CmmExpr
306 cmmNegate _ (CmmLit (CmmInt n rep)) = CmmLit (CmmInt (-n) rep)
307 cmmNegate dflags e = CmmMachOp (MO_S_Neg (cmmExprWidth dflags e)) [e]
308
309 blankWord :: DynFlags -> CmmStatic
310 blankWord dflags = CmmUninitialised (wORD_SIZE dflags)
311
312 ---------------------------------------------------
313 --
314 -- CmmExpr predicates
315 --
316 ---------------------------------------------------
317
318 isTrivialCmmExpr :: CmmExpr -> Bool
319 isTrivialCmmExpr (CmmLoad _ _) = False
320 isTrivialCmmExpr (CmmMachOp _ _) = False
321 isTrivialCmmExpr (CmmLit _) = True
322 isTrivialCmmExpr (CmmReg _) = True
323 isTrivialCmmExpr (CmmRegOff _ _) = True
324 isTrivialCmmExpr (CmmStackSlot _ _) = panic "isTrivialCmmExpr CmmStackSlot"
325
326 hasNoGlobalRegs :: CmmExpr -> Bool
327 hasNoGlobalRegs (CmmLoad e _) = hasNoGlobalRegs e
328 hasNoGlobalRegs (CmmMachOp _ es) = all hasNoGlobalRegs es
329 hasNoGlobalRegs (CmmLit _) = True
330 hasNoGlobalRegs (CmmReg (CmmLocal _)) = True
331 hasNoGlobalRegs (CmmRegOff (CmmLocal _) _) = True
332 hasNoGlobalRegs _ = False
333
334 ---------------------------------------------------
335 --
336 -- Tagging
337 --
338 ---------------------------------------------------
339
340 -- Tag bits mask
341 --cmmTagBits = CmmLit (mkIntCLit tAG_BITS)
342 cmmTagMask, cmmPointerMask :: DynFlags -> CmmExpr
343 cmmTagMask dflags = mkIntExpr dflags (tAG_MASK dflags)
344 cmmPointerMask dflags = mkIntExpr dflags (complement (tAG_MASK dflags))
345
346 -- Used to untag a possibly tagged pointer
347 -- A static label need not be untagged
348 cmmUntag, cmmGetTag :: DynFlags -> CmmExpr -> CmmExpr
349 cmmUntag _ e@(CmmLit (CmmLabel _)) = e
350 -- Default case
351 cmmUntag dflags e = cmmAndWord dflags e (cmmPointerMask dflags)
352
353 cmmGetTag dflags e = cmmAndWord dflags e (cmmTagMask dflags)
354
355 -- Test if a closure pointer is untagged
356 cmmIsTagged :: DynFlags -> CmmExpr -> CmmExpr
357 cmmIsTagged dflags e = cmmNeWord dflags (cmmAndWord dflags e (cmmTagMask dflags)) (zeroExpr dflags)
358
359 cmmConstrTag, cmmConstrTag1 :: DynFlags -> CmmExpr -> CmmExpr
360 cmmConstrTag dflags e = cmmSubWord dflags (cmmAndWord dflags e (cmmTagMask dflags)) (mkIntExpr dflags 1)
361 -- Get constructor tag, but one based.
362 cmmConstrTag1 dflags e = cmmAndWord dflags e (cmmTagMask dflags)
363
364
365 --------------------------------------------
366 --
367 -- mkLiveness
368 --
369 ---------------------------------------------
370
371 mkLiveness :: DynFlags -> [Maybe LocalReg] -> Liveness
372 mkLiveness _ [] = []
373 mkLiveness dflags (reg:regs)
374 = take sizeW bits ++ mkLiveness dflags regs
375 where
376 sizeW = case reg of
377 Nothing -> 1
378 Just r -> (widthInBytes (typeWidth (localRegType r)) + wORD_SIZE dflags - 1)
379 `quot` wORD_SIZE dflags
380 -- number of words, rounded up
381 bits = repeat $ is_non_ptr reg -- True <=> Non Ptr
382
383 is_non_ptr Nothing = True
384 is_non_ptr (Just reg) = not $ isGcPtrType (localRegType reg)
385
386
387 -- ============================================== -
388 -- ============================================== -
389 -- ============================================== -
390
391 ---------------------------------------------------
392 --
393 -- Manipulating CmmGraphs
394 --
395 ---------------------------------------------------
396
397 modifyGraph :: (Graph n C C -> Graph n' C C) -> GenCmmGraph n -> GenCmmGraph n'
398 modifyGraph f g = CmmGraph {g_entry=g_entry g, g_graph=f (g_graph g)}
399
400 toBlockMap :: CmmGraph -> BlockEnv CmmBlock
401 toBlockMap (CmmGraph {g_graph=GMany NothingO body NothingO}) = body
402
403 ofBlockMap :: BlockId -> BlockEnv CmmBlock -> CmmGraph
404 ofBlockMap entry bodyMap = CmmGraph {g_entry=entry, g_graph=GMany NothingO bodyMap NothingO}
405
406 insertBlock :: CmmBlock -> BlockEnv CmmBlock -> BlockEnv CmmBlock
407 insertBlock block map =
408 ASSERT (isNothing $ mapLookup id map)
409 mapInsert id block map
410 where id = entryLabel block
411
412 toBlockList :: CmmGraph -> [CmmBlock]
413 toBlockList g = mapElems $ toBlockMap g
414
415 ofBlockList :: BlockId -> [CmmBlock] -> CmmGraph
416 ofBlockList entry blocks = CmmGraph { g_entry = entry
417 , g_graph = GMany NothingO body NothingO }
418 where body = foldr addBlock emptyBody blocks
419
420 bodyToBlockList :: Body CmmNode -> [CmmBlock]
421 bodyToBlockList body = mapElems body
422
423 mapGraphNodes :: ( CmmNode C O -> CmmNode C O
424 , CmmNode O O -> CmmNode O O
425 , CmmNode O C -> CmmNode O C)
426 -> CmmGraph -> CmmGraph
427 mapGraphNodes funs@(mf,_,_) g =
428 ofBlockMap (entryLabel $ mf $ CmmEntry $ g_entry g) $ mapMap (mapBlock3' funs) $ toBlockMap g
429
430 mapGraphNodes1 :: (forall e x. CmmNode e x -> CmmNode e x) -> CmmGraph -> CmmGraph
431 mapGraphNodes1 f = modifyGraph (mapGraph f)
432
433
434 foldGraphBlocks :: (CmmBlock -> a -> a) -> a -> CmmGraph -> a
435 foldGraphBlocks k z g = mapFold k z $ toBlockMap g
436
437 postorderDfs :: CmmGraph -> [CmmBlock]
438 postorderDfs g = {-# SCC "postorderDfs" #-} postorder_dfs_from (toBlockMap g) (g_entry g)
439
440 -------------------------------------------------
441 -- Running dataflow analysis and/or rewrites
442
443 -- Constructing forward and backward analysis-only pass
444 analFwd :: DataflowLattice f -> FwdTransfer n f -> FwdPass UniqSM n f
445 analBwd :: DataflowLattice f -> BwdTransfer n f -> BwdPass UniqSM n f
446
447 analFwd lat xfer = analRewFwd lat xfer noFwdRewrite
448 analBwd lat xfer = analRewBwd lat xfer noBwdRewrite
449
450 -- Constructing forward and backward analysis + rewrite pass
451 analRewFwd :: DataflowLattice f -> FwdTransfer n f
452 -> FwdRewrite UniqSM n f
453 -> FwdPass UniqSM n f
454
455 analRewBwd :: DataflowLattice f
456 -> BwdTransfer n f
457 -> BwdRewrite UniqSM n f
458 -> BwdPass UniqSM n f
459
460 analRewFwd lat xfer rew = FwdPass {fp_lattice = lat, fp_transfer = xfer, fp_rewrite = rew}
461 analRewBwd lat xfer rew = BwdPass {bp_lattice = lat, bp_transfer = xfer, bp_rewrite = rew}
462
463 -- Running forward and backward dataflow analysis + optional rewrite
464 dataflowPassFwd :: NonLocal n =>
465 GenCmmGraph n -> [(BlockId, f)]
466 -> FwdPass UniqSM n f
467 -> UniqSM (GenCmmGraph n, BlockEnv f)
468 dataflowPassFwd (CmmGraph {g_entry=entry, g_graph=graph}) facts fwd = do
469 (graph, facts, NothingO) <- analyzeAndRewriteFwd fwd (JustC [entry]) graph (mkFactBase (fp_lattice fwd) facts)
470 return (CmmGraph {g_entry=entry, g_graph=graph}, facts)
471
472 dataflowAnalFwd :: NonLocal n =>
473 GenCmmGraph n -> [(BlockId, f)]
474 -> FwdPass UniqSM n f
475 -> BlockEnv f
476 dataflowAnalFwd (CmmGraph {g_entry=entry, g_graph=graph}) facts fwd =
477 analyzeFwd fwd (JustC [entry]) graph (mkFactBase (fp_lattice fwd) facts)
478
479 dataflowAnalFwdBlocks :: NonLocal n =>
480 GenCmmGraph n -> [(BlockId, f)]
481 -> FwdPass UniqSM n f
482 -> UniqSM (BlockEnv f)
483 dataflowAnalFwdBlocks (CmmGraph {g_entry=entry, g_graph=graph}) facts fwd = do
484 -- (graph, facts, NothingO) <- analyzeAndRewriteFwd fwd (JustC [entry]) graph (mkFactBase (fp_lattice fwd) facts)
485 -- return facts
486 return (analyzeFwdBlocks fwd (JustC [entry]) graph (mkFactBase (fp_lattice fwd) facts))
487
488 dataflowAnalBwd :: NonLocal n =>
489 GenCmmGraph n -> [(BlockId, f)]
490 -> BwdPass UniqSM n f
491 -> BlockEnv f
492 dataflowAnalBwd (CmmGraph {g_entry=entry, g_graph=graph}) facts bwd =
493 analyzeBwd bwd (JustC [entry]) graph (mkFactBase (bp_lattice bwd) facts)
494
495 dataflowPassBwd :: NonLocal n =>
496 GenCmmGraph n -> [(BlockId, f)]
497 -> BwdPass UniqSM n f
498 -> UniqSM (GenCmmGraph n, BlockEnv f)
499 dataflowPassBwd (CmmGraph {g_entry=entry, g_graph=graph}) facts bwd = do
500 (graph, facts, NothingO) <- analyzeAndRewriteBwd bwd (JustC [entry]) graph (mkFactBase (bp_lattice bwd) facts)
501 return (CmmGraph {g_entry=entry, g_graph=graph}, facts)