never executed always true always false
1 -- | One ounce of sanity checking is worth 10000000000000000 ounces
2 -- of staring blindly at assembly code trying to find the problem..
3 module GHC.CmmToAsm.SPARC.CodeGen.Sanity (
4 checkBlock
5 )
6
7 where
8
9 import GHC.Prelude
10 import GHC.Platform
11
12 import GHC.CmmToAsm.SPARC.Instr
13 import GHC.CmmToAsm.SPARC.Ppr () -- For Outputable instances
14 import GHC.CmmToAsm.Types
15
16 import GHC.Cmm
17
18 import GHC.Utils.Outputable
19 import GHC.Utils.Panic
20
21
22 -- | Enforce intra-block invariants.
23 --
24 checkBlock :: Platform
25 -> CmmBlock
26 -> NatBasicBlock Instr
27 -> NatBasicBlock Instr
28
29 checkBlock platform cmm block@(BasicBlock _ instrs)
30 | checkBlockInstrs instrs
31 = block
32
33 | otherwise
34 = pprPanic
35 ("SPARC.CodeGen: bad block\n")
36 ( vcat [ text " -- cmm -----------------\n"
37 , pdoc platform cmm
38 , text " -- native code ---------\n"
39 , pdoc platform block ])
40
41
42 checkBlockInstrs :: [Instr] -> Bool
43 checkBlockInstrs ii
44
45 -- An unconditional jumps end the block.
46 -- There must be an unconditional jump in the block, otherwise
47 -- the register liveness determinator will get the liveness
48 -- information wrong.
49 --
50 -- If the block ends with a cmm call that never returns
51 -- then there can be unreachable instructions after the jump,
52 -- but we don't mind here.
53 --
54 | instr : NOP : _ <- ii
55 , isUnconditionalJump instr
56 = True
57
58 -- All jumps must have a NOP in their branch delay slot.
59 -- The liveness determinator and register allocators aren't smart
60 -- enough to handle branch delay slots.
61 --
62 | instr : NOP : is <- ii
63 , isJumpishInstr instr
64 = checkBlockInstrs is
65
66 -- keep checking
67 | _:i2:is <- ii
68 = checkBlockInstrs (i2:is)
69
70 -- this block is no good
71 | otherwise
72 = False