Fix an egregious strictness analyser bug (Trac #4924)
[ghc-hetmet.git] / compiler / nativeGen / SPARC / ShortcutJump.hs
1
2 module SPARC.ShortcutJump (
3         JumpDest(..),
4         canShortcut,
5         shortcutJump,
6         shortcutStatic,
7         shortBlockId
8 )
9
10 where
11
12 import SPARC.Instr
13 import SPARC.Imm
14
15 import CLabel
16 import BlockId
17 import Cmm
18
19 import Panic
20
21
22
23 data JumpDest 
24         = DestBlockId BlockId 
25         | DestImm Imm
26
27
28 canShortcut :: Instr -> Maybe JumpDest
29 canShortcut _ = Nothing
30
31
32 shortcutJump :: (BlockId -> Maybe JumpDest) -> Instr -> Instr
33 shortcutJump _ other = other
34
35
36 shortcutStatic :: (BlockId -> Maybe JumpDest) -> CmmStatic -> CmmStatic
37
38 shortcutStatic fn (CmmStaticLit (CmmLabel lab))
39         | Just uq <- maybeAsmTemp lab 
40         = CmmStaticLit (CmmLabel (shortBlockId fn (BlockId uq)))
41
42 shortcutStatic fn (CmmStaticLit (CmmLabelDiffOff lbl1 lbl2 off))
43         | Just uq <- maybeAsmTemp lbl1
44         = CmmStaticLit (CmmLabelDiffOff (shortBlockId fn (BlockId uq)) lbl2 off)
45
46 -- slightly dodgy, we're ignoring the second label, but this
47 -- works with the way we use CmmLabelDiffOff for jump tables now.
48 shortcutStatic _ other_static
49         = other_static
50
51
52 shortBlockId :: (BlockId -> Maybe JumpDest) -> BlockId -> CLabel
53 shortBlockId fn blockid@(BlockId uq) =
54    case fn blockid of
55       Nothing -> mkAsmTempLabel uq
56       Just (DestBlockId blockid')  -> shortBlockId fn blockid'
57       Just (DestImm (ImmCLbl lbl)) -> lbl
58       _other -> panic "shortBlockId"
59
60
61