ShortcutJump.hs 1.86 KB
Newer Older
1
module SPARC.ShortcutJump (
2 3 4 5 6
        JumpDest(..), getJumpDestBlockId,
        canShortcut,
        shortcutJump,
        shortcutStatics,
        shortBlockId
7 8 9 10
)

where

11 12
import GhcPrelude

13 14 15 16 17
import SPARC.Instr
import SPARC.Imm

import CLabel
import BlockId
18
import Cmm
19 20 21 22

import Panic


23 24 25
data JumpDest
        = DestBlockId BlockId
        | DestImm Imm
26

27 28 29 30
getJumpDestBlockId :: JumpDest -> Maybe BlockId
getJumpDestBlockId (DestBlockId bid) = Just bid
getJumpDestBlockId _                 = Nothing

31 32 33 34 35 36 37 38 39 40

canShortcut :: Instr -> Maybe JumpDest
canShortcut _ = Nothing


shortcutJump :: (BlockId -> Maybe JumpDest) -> Instr -> Instr
shortcutJump _ other = other



41 42 43 44 45
shortcutStatics :: (BlockId -> Maybe JumpDest) -> CmmStatics -> CmmStatics
shortcutStatics fn (Statics lbl statics)
  = Statics lbl $ map (shortcutStatic fn) statics
  -- we need to get the jump tables, so apply the mapping to the entries
  -- of a CmmData too.
46

47 48
shortcutLabel :: (BlockId -> Maybe JumpDest) -> CLabel -> CLabel
shortcutLabel fn lab
49 50
  | Just blkId <- maybeLocalBlockLabel lab = shortBlockId fn blkId
  | otherwise                              = lab
51

52 53
shortcutStatic :: (BlockId -> Maybe JumpDest) -> CmmStatic -> CmmStatic
shortcutStatic fn (CmmStaticLit (CmmLabel lab))
54
        = CmmStaticLit (CmmLabel (shortcutLabel fn lab))
55
shortcutStatic fn (CmmStaticLit (CmmLabelDiffOff lbl1 lbl2 off))
56
        = CmmStaticLit (CmmLabelDiffOff (shortcutLabel fn lbl1) lbl2 off)
57 58 59 60 61 62 63
-- slightly dodgy, we're ignoring the second label, but this
-- works with the way we use CmmLabelDiffOff for jump tables now.
shortcutStatic _ other_static
        = other_static


shortBlockId :: (BlockId -> Maybe JumpDest) -> BlockId -> CLabel
64
shortBlockId fn blockid =
65
   case fn blockid of
66
      Nothing -> blockLbl blockid
67 68 69
      Just (DestBlockId blockid')  -> shortBlockId fn blockid'
      Just (DestImm (ImmCLbl lbl)) -> lbl
      _other -> panic "shortBlockId"