Simon Jakobi pushed to branch wip/sjakobi/T27368-cbe-compress at Glasgow Haskell Compiler / GHC

Commits:

2 changed files:

Changes:

  • compiler/GHC/Cmm/Lint.hs
    ... ... @@ -68,18 +68,19 @@ lintCmmGraph g = do
    68 68
        let
    
    69 69
           blocks = toBlockList g
    
    70 70
           labels = setFromList (map entryLabel blocks)
    
    71
    -   cmmLocalLiveness platform g `seq` mapM_ (lintCmmBlock labels) blocks
    
    71
    +      reachable = setFromList (map entryLabel (revPostorder g))
    
    72
    +   cmmLocalLiveness platform g `seq` mapM_ (lintCmmBlock labels reachable) blocks
    
    72 73
        -- cmmLiveness throws an error if there are registers
    
    73 74
        -- live on entry to the graph (i.e. undefined
    
    74 75
        -- variables)
    
    75 76
     
    
    76 77
     
    
    77
    -lintCmmBlock :: LabelSet -> CmmBlock -> CmmLint ()
    
    78
    -lintCmmBlock labels block
    
    78
    +lintCmmBlock :: LabelSet -> LabelSet -> CmmBlock -> CmmLint ()
    
    79
    +lintCmmBlock labels reachable block
    
    79 80
       = addLintInfo (text "in basic block " <> ppr (entryLabel block)) $ do
    
    80 81
             let (_, middle, last) = blockSplit block
    
    81 82
             mapM_ lintCmmMiddle (blockToList middle)
    
    82
    -        lintCmmLast labels last
    
    83
    +        lintCmmLast labels reachable last
    
    83 84
     
    
    84 85
     -- -----------------------------------------------------------------------------
    
    85 86
     -- lintCmmExpr
    
    ... ... @@ -188,8 +189,8 @@ lintCmmMiddle node = case node of
    188 189
                 lintTarget arg_tys target
    
    189 190
     
    
    190 191
     
    
    191
    -lintCmmLast :: LabelSet -> CmmNode O C -> CmmLint ()
    
    192
    -lintCmmLast labels node = case node of
    
    192
    +lintCmmLast :: LabelSet -> LabelSet -> CmmNode O C -> CmmLint ()
    
    193
    +lintCmmLast labels reachable node = case node of
    
    193 194
       CmmBranch id -> checkTarget id
    
    194 195
     
    
    195 196
       CmmCondBranch e t f _ -> do
    
    ... ... @@ -208,7 +209,7 @@ lintCmmLast labels node = case node of
    208 209
     
    
    209 210
       CmmCall { cml_target = target, cml_cont = cont } -> do
    
    210 211
               _ <- lintCmmExpr target
    
    211
    -          maybe (return ()) checkTarget cont
    
    212
    +          maybe (return ()) checkCont cont
    
    212 213
     
    
    213 214
       CmmForeignCall tgt _ args succ _ _ _ -> do
    
    214 215
               let lintArg expr = do
    
    ... ... @@ -222,12 +223,22 @@ lintCmmLast labels node = case node of
    222 223
                     lintCmmExpr expr
    
    223 224
               arg_tys <- mapM lintArg args
    
    224 225
               lintTarget arg_tys tgt
    
    225
    -          checkTarget succ
    
    226
    +          checkCont succ
    
    226 227
      where
    
    227 228
       checkTarget id
    
    228 229
          | setMember id labels = return ()
    
    229 230
          | otherwise = cmmLintErr (text "Branch to nonexistent id" <+> ppr id)
    
    230 231
     
    
    232
    +  -- A call continuation must be reachable even when the call itself is
    
    233
    +  -- in an unreachable block: callProcPoints collects continuations from
    
    234
    +  -- the whole block map, but only reachable blocks get stack maps
    
    235
    +  -- (#27368).  See Note [unreachable blocks] in GHC.Cmm.Pipeline.
    
    236
    +  checkCont id = do
    
    237
    +     checkTarget id
    
    238
    +     unless (setMember id reachable) $
    
    239
    +       cmmLintErr (text "Call continuation" <+> ppr id
    
    240
    +                   <+> text "is not reachable")
    
    241
    +
    
    231 242
     lintTarget :: [CmmType] -> ForeignTarget -> CmmLint ()
    
    232 243
     lintTarget _arg_tys (ForeignTarget e _) = do
    
    233 244
         mayNotMentionCallerSavedRegs (text "foreign target") e
    

  • compiler/GHC/Cmm/Pipeline.hs
    ... ... @@ -368,6 +368,9 @@ but no stack map, and setInfoTableStackMap would panic (#27368).
    368 368
     The common block eliminator therefore ensures that the labels in its
    
    369 369
     unreachable leftovers coincide with labels of reachable code, see
    
    370 370
     Note [Resolving the CBE substitution] in GHC.Cmm.CommonBlockElim.
    
    371
    +-dcmm-lint checks the invariant: a call continuation must be
    
    372
    +reachable even when the call itself is not (see checkCont in
    
    373
    +GHC.Cmm.Lint).
    
    371 374
     
    
    372 375
     To make unreachable blocks visible in -ddump-cmm-* output, add -dppr-debug.
    
    373 376
     -}