Hannes Siebenhandl pushed to branch wip/fendor/hpc-bc-support at Glasgow Haskell Compiler / GHC

Commits:

16 changed files:

Changes:

  • compiler/GHC/ByteCode/Asm.hs
    ... ... @@ -855,6 +855,12 @@ assembleI platform i = case i of
    855 855
         emit_ bci_BRK_FUN [ Op p1, Op info_addr, Op info_unitid_addr
    
    856 856
                           , SmallOp ix_hi, SmallOp ix_lo, Op np ]
    
    857 857
     
    
    858
    +  HPC_TICK lbl ix -> do
    
    859
    +    p <- lit1 (BCONPtrLbl lbl)
    
    860
    +    let ix_hi = fromIntegral (ix `shiftR` 16)
    
    861
    +        ix_lo = fromIntegral (ix .&. 0xffff)
    
    862
    +    emit_ bci_HPC_TICK [Op p, SmallOp ix_hi, SmallOp ix_lo]
    
    863
    +
    
    858 864
     #if MIN_VERSION_rts(1,0,3)
    
    859 865
       BCO_NAME name            -> do np <- lit1 (BCONPtrStr name)
    
    860 866
                                      emit_ bci_BCO_NAME [Op np]
    

  • compiler/GHC/ByteCode/Instr.hs
    ... ... @@ -15,6 +15,7 @@ import GHC.ByteCode.Types
    15 15
     import GHC.Cmm.Type (Width)
    
    16 16
     import GHC.StgToCmm.Layout     ( ArgRep(..) )
    
    17 17
     import GHC.Utils.Outputable
    
    18
    +import GHC.Data.FastString     ( FastString )
    
    18 19
     import GHC.Types.Name
    
    19 20
     import GHC.Types.Literal
    
    20 21
     import GHC.Types.Unique
    
    ... ... @@ -257,6 +258,7 @@ data BCInstr
    257 258
     
    
    258 259
        -- Breakpoints
    
    259 260
        | BRK_FUN          !InternalBreakpointId
    
    261
    +   | HPC_TICK         !FastString !Word32
    
    260 262
     
    
    261 263
     #if MIN_VERSION_rts(1,0,3)
    
    262 264
        -- | A "meta"-instruction for recording the name of a BCO for debugging purposes.
    
    ... ... @@ -452,6 +454,7 @@ instance Outputable BCInstr where
    452 454
                                  = text "BRK_FUN" <+> text "<breakarray>"
    
    453 455
                                    <+> ppr info_mod <+> ppr infox
    
    454 456
                                    <+> text "<cc>"
    
    457
    +   ppr (HPC_TICK lbl ix)     = text "HPC_TICK" <+> ppr lbl <+> ppr ix
    
    455 458
     #if MIN_VERSION_rts(1,0,3)
    
    456 459
        ppr (BCO_NAME nm)         = text "BCO_NAME" <+> text (show nm)
    
    457 460
     #endif
    
    ... ... @@ -577,6 +580,7 @@ bciStackUse OP_INDEX_ADDR{} = 0
    577 580
     
    
    578 581
     bciStackUse SWIZZLE{}             = 0
    
    579 582
     bciStackUse BRK_FUN{}             = 0
    
    583
    +bciStackUse HPC_TICK{}            = 0
    
    580 584
     
    
    581 585
     -- These insns actually reduce stack use, but we need the high-tide level,
    
    582 586
     -- so can't use this info.  Not that it matters much.
    

  • compiler/GHC/Driver/Backend.hs
    ... ... @@ -712,8 +712,7 @@ backendSupportsHpc (Named NCG) = True
    712 712
     backendSupportsHpc (Named LLVM)        = True
    
    713 713
     backendSupportsHpc (Named ViaC)        = True
    
    714 714
     backendSupportsHpc (Named JavaScript)  = False
    
    715
    --- TODO: @terrorjack thinks that the bytecode backend should support HPC now since (!13493)
    
    716
    -backendSupportsHpc (Named Bytecode) = False
    
    715
    +backendSupportsHpc (Named Bytecode) = True
    
    717 716
     backendSupportsHpc (Named NoBackend)   = True
    
    718 717
     
    
    719 718
     -- | This flag says whether the back end supports foreign
    

  • compiler/GHC/Driver/CodeOutput.hs
    ... ... @@ -276,14 +276,15 @@ outputForeignStubs logger tmpfs dflags unit_state mod location stubs
    276 276
          NoStubs ->
    
    277 277
             return (False, Nothing)
    
    278 278
     
    
    279
    -     ForeignStubs (CHeader h_code) (CStub c_code _ _) -> do
    
    279
    +     ForeignStubs (CHeader h_code) cstub -> do
    
    280 280
             let
    
    281
    -            stub_c_output_d = pprCode c_code
    
    281
    +            stub_c_output_d = pprCode (getCStub cstub $$ pprCStubInitFiniDecls platform cstub)
    
    282 282
                 stub_c_output_w = showSDoc dflags stub_c_output_d
    
    283 283
     
    
    284 284
                 -- Header file protos for "foreign export"ed functions.
    
    285 285
                 stub_h_output_d = pprCode h_code
    
    286 286
                 stub_h_output_w = showSDoc dflags stub_h_output_d
    
    287
    +            platform = targetPlatform dflags
    
    287 288
     
    
    288 289
             putDumpFileMaybe logger Opt_D_dump_foreign
    
    289 290
                           "Foreign export header file"
    
    ... ... @@ -343,6 +344,28 @@ outputForeignStubs logger tmpfs dflags unit_state mod location stubs
    343 344
        cplusplus_hdr = "#if defined(__cplusplus)\nextern \"C\" {\n#endif\n"
    
    344 345
        cplusplus_ftr = "#if defined(__cplusplus)\n}\n#endif\n"
    
    345 346
     
    
    347
    +pprCStubInitFiniDecls :: Platform -> CStub -> SDoc
    
    348
    +pprCStubInitFiniDecls platform cstub =
    
    349
    +  vcat (zipWith (pprInitOrFiniDecl ".init_array") [0 :: Int ..] (getInitializers cstub))
    
    350
    +  $$ vcat (zipWith (pprInitOrFiniDecl ".fini_array") [0 :: Int ..] (getFinalizers cstub))
    
    351
    +  where
    
    352
    +    pprInitOrFiniDecl :: String -> Int -> CLabel -> SDoc
    
    353
    +    pprInitOrFiniDecl section_name n lbl =
    
    354
    +      vcat
    
    355
    +        [ hsep [text "extern void", pprCLabel platform lbl, text "(void);"]
    
    356
    +        , hsep [ text "static void (*"
    
    357
    +               <> text "__ghc_init_fini_"
    
    358
    +               <> int n
    
    359
    +               <> text ")(void)"
    
    360
    +               , text "__attribute__((used, section("
    
    361
    +                 <> doubleQuotes (text section_name)
    
    362
    +                 <> text ")))"
    
    363
    +               , equals
    
    364
    +               , pprCLabel platform lbl
    
    365
    +               <> semi
    
    366
    +               ]
    
    367
    +        ]
    
    368
    +
    
    346 369
     
    
    347 370
     -- It is more than likely that the stubs file will
    
    348 371
     -- turn out to be empty, in which case no file should be created.
    

  • compiler/GHC/Driver/Session.hs
    ... ... @@ -3790,12 +3790,6 @@ makeDynFlagsConsistent dflags
    3790 3790
                pgmError (backendDescription (backend dflags) ++
    
    3791 3791
                          " supports only unregisterised ABI but target platform doesn't use it.")
    
    3792 3792
     
    
    3793
    - | gopt Opt_Hpc dflags && not (backendSupportsHpc (backend dflags))
    
    3794
    -    = let dflags' = gopt_unset dflags Opt_Hpc
    
    3795
    -          warn = "Hpc can't be used with " ++ backendDescription (backend dflags) ++
    
    3796
    -                 ". Ignoring -fhpc."
    
    3797
    -      in loop dflags' warn
    
    3798
    -
    
    3799 3793
      | backendSwappableWithViaC (backend dflags) &&
    
    3800 3794
        platformUnregisterised (targetPlatform dflags)
    
    3801 3795
         = loop (dflags { backend = viaCBackend })
    

  • compiler/GHC/HsToCore.hs
    ... ... @@ -163,20 +163,20 @@ deSugar hsc_env
    163 163
                                            export_set (typeEnvTyCons type_env) binds
    
    164 164
                                   else return (binds, Nothing)
    
    165 165
             ; let modBreaks
    
    166
    -                | Just (_, specs) <- m_tickInfo
    
    166
    +                | Just (_, _, breakpointSpecs) <- m_tickInfo
    
    167 167
                     , breakpointsAllowed dflags
    
    168
    -                = Just $ mkModBreaks (interpreterProfiled $ hscInterp hsc_env) mod specs
    
    168
    +                = Just $ mkModBreaks (interpreterProfiled $ hscInterp hsc_env) mod breakpointSpecs
    
    169 169
                     | otherwise
    
    170 170
                     = Nothing
    
    171 171
     
    
    172 172
             ; ds_hpc_info <- case m_tickInfo of
    
    173
    -            Just (orig_file2, ticks)
    
    173
    +            Just (orig_file2, hpcTicks, _)
    
    174 174
                   | gopt Opt_Hpc $ hsc_dflags hsc_env
    
    175 175
                   -> do
    
    176 176
                   hashNo <- if gopt Opt_Hpc $ hsc_dflags hsc_env
    
    177
    -                then writeMixEntries (hpcDir dflags) mod ticks orig_file2
    
    177
    +                then writeMixEntries (hpcDir dflags) mod hpcTicks orig_file2
    
    178 178
                     else return 0 -- dummy hash when none are written
    
    179
    -              pure $ HpcInfo (fromIntegral $ sizeSS ticks) hashNo
    
    179
    +              pure $ HpcInfo (fromIntegral $ sizeSS hpcTicks) hashNo
    
    180 180
                 _ -> pure $ emptyHpcInfo
    
    181 181
     
    
    182 182
             ; (msgs, mb_res) <- initDs hsc_env tcg_env $
    

  • compiler/GHC/HsToCore/Ticks.hs
    ... ... @@ -100,7 +100,7 @@ addTicksToBinds
    100 100
                                     -- hasn't set it), so we have to work from this set.
    
    101 101
             -> [TyCon]              -- ^ Type constructors in this module
    
    102 102
             -> LHsBinds GhcTc
    
    103
    -        -> IO (LHsBinds GhcTc, Maybe (FilePath, SizedSeq Tick))
    
    103
    +        -> IO (LHsBinds GhcTc, Maybe (FilePath, SizedSeq Tick, SizedSeq Tick))
    
    104 104
     
    
    105 105
     addTicksToBinds logger cfg
    
    106 106
                     mod mod_loc exports tyCons binds
    
    ... ... @@ -133,12 +133,13 @@ addTicksToBinds logger cfg
    133 133
     
    
    134 134
               (binds1,st) = foldr tickPass (binds, initTTState) passes
    
    135 135
     
    
    136
    -          extendedMixEntries = ticks st
    
    136
    +          hpcEntries = hpcTicks st
    
    137
    +          breakpointEntries = breakpointTicks st
    
    137 138
     
    
    138 139
          putDumpFileMaybe logger Opt_D_dump_ticked "HPC" FormatHaskell
    
    139 140
            (pprLHsBinds binds1)
    
    140 141
     
    
    141
    -     return (binds1, Just (orig_file2, extendedMixEntries))
    
    142
    +     return (binds1, Just (orig_file2, hpcEntries, breakpointEntries))
    
    142 143
     
    
    143 144
       | otherwise = return (binds, Nothing)
    
    144 145
     
    
    ... ... @@ -1049,23 +1050,31 @@ addTickArithSeqInfo (FromThenTo e1 e2 e3) =
    1049 1050
                     (addTickLHsExpr e2)
    
    1050 1051
                     (addTickLHsExpr e3)
    
    1051 1052
     
    
    1052
    -data TickTransState = TT { ticks       :: !(SizedSeq Tick)
    
    1053
    -                         , ccIndices   :: !CostCentreState
    
    1054
    -                         , recSelTicks :: !(IdEnv CoreTickish)
    
    1053
    +data TickTransState = TT { hpcTicks        :: !(SizedSeq Tick)
    
    1054
    +                         , breakpointTicks :: !(SizedSeq Tick)
    
    1055
    +                         , ccIndices       :: !CostCentreState
    
    1056
    +                         , recSelTicks     :: !(IdEnv CoreTickish)
    
    1055 1057
                              }
    
    1056 1058
     
    
    1057 1059
     initTTState :: TickTransState
    
    1058
    -initTTState = TT { ticks        = emptySS
    
    1059
    -                 , ccIndices    = newCostCentreState
    
    1060
    -                 , recSelTicks  = emptyVarEnv
    
    1060
    +initTTState = TT { hpcTicks        = emptySS
    
    1061
    +                 , breakpointTicks = emptySS
    
    1062
    +                 , ccIndices       = newCostCentreState
    
    1063
    +                 , recSelTicks     = emptyVarEnv
    
    1061 1064
                      }
    
    1062 1065
     
    
    1063
    -addMixEntry :: Tick -> TM Int
    
    1064
    -addMixEntry ent = do
    
    1065
    -  c <- fromIntegral . sizeSS . ticks <$> getState
    
    1066
    +addHpcEntry :: Tick -> TM Int
    
    1067
    +addHpcEntry ent = do
    
    1068
    +  c <- fromIntegral . sizeSS . hpcTicks <$> getState
    
    1066 1069
       setState $ \st ->
    
    1067
    -    st { ticks = addToSS (ticks st) ent
    
    1068
    -       }
    
    1070
    +    st { hpcTicks = addToSS (hpcTicks st) ent }
    
    1071
    +  return c
    
    1072
    +
    
    1073
    +addBreakpointEntry :: Tick -> TM Int
    
    1074
    +addBreakpointEntry ent = do
    
    1075
    +  c <- fromIntegral . sizeSS . breakpointTicks <$> getState
    
    1076
    +  setState $ \st ->
    
    1077
    +    st { breakpointTicks = addToSS (breakpointTicks st) ent }
    
    1069 1078
       return c
    
    1070 1079
     
    
    1071 1080
     addRecSelTick :: Id -> CoreTickish -> TM ()
    
    ... ... @@ -1290,7 +1299,7 @@ mkTickish boxLabel countEntries topOnly pos fvs decl_path = do
    1290 1299
     
    
    1291 1300
       env <- getEnv
    
    1292 1301
       case tickishType env of
    
    1293
    -    HpcTicks -> HpcTick (this_mod env) <$> addMixEntry me
    
    1302
    +    HpcTicks -> HpcTick (this_mod env) <$> addHpcEntry me
    
    1294 1303
     
    
    1295 1304
         ProfNotes -> do
    
    1296 1305
           flavour <- mkHpcCCFlavour <$> getCCIndexM cc_name
    
    ... ... @@ -1299,7 +1308,7 @@ mkTickish boxLabel countEntries topOnly pos fvs decl_path = do
    1299 1308
           return $ ProfNote cc count True{-scopes-}
    
    1300 1309
     
    
    1301 1310
         Breakpoints -> do
    
    1302
    -      i <- addMixEntry me
    
    1311
    +      i <- addBreakpointEntry me
    
    1303 1312
           pure (Breakpoint noExtField (BreakpointId (this_mod env) i) ids)
    
    1304 1313
     
    
    1305 1314
         SourceNotes | RealSrcSpan pos' _ <- pos ->
    
    ... ... @@ -1324,19 +1333,19 @@ mkBinTickBoxHpc :: (Bool -> BoxLabel) -> SrcSpan -> LHsExpr GhcTc
    1324 1333
     mkBinTickBoxHpc boxLabel pos e = do
    
    1325 1334
       env <- getEnv
    
    1326 1335
       binTick <- HsBinTick
    
    1327
    -    <$> addMixEntry (Tick { tick_loc = pos
    
    1336
    +    <$> addHpcEntry (Tick { tick_loc = pos
    
    1328 1337
                               , tick_path = declPath env
    
    1329 1338
                               , tick_ids = []
    
    1330 1339
                               , tick_label = boxLabel True
    
    1331 1340
                               })
    
    1332
    -    <*> addMixEntry (Tick { tick_loc = pos
    
    1341
    +    <*> addHpcEntry (Tick { tick_loc = pos
    
    1333 1342
                               , tick_path = declPath env
    
    1334 1343
                               , tick_ids = []
    
    1335 1344
                               , tick_label = boxLabel False
    
    1336 1345
                               })
    
    1337 1346
         <*> pure e
    
    1338 1347
       tick <- HpcTick (this_mod env)
    
    1339
    -    <$> addMixEntry (Tick { tick_loc = pos
    
    1348
    +    <$> addHpcEntry (Tick { tick_loc = pos
    
    1340 1349
                               , tick_path = declPath env
    
    1341 1350
                               , tick_ids = []
    
    1342 1351
                               , tick_label = ExpBox False
    

  • compiler/GHC/StgToByteCode.hs
    ... ... @@ -20,6 +20,7 @@ import GHC.ByteCode.Types
    20 20
     
    
    21 21
     import GHC.Cmm.CallConv
    
    22 22
     import GHC.Cmm.Expr
    
    23
    +import GHC.Cmm.CLabel (mkHpcTicksLabel, pprCLabel)
    
    23 24
     import GHC.Cmm.Reg ( GlobalArgRegs(..) )
    
    24 25
     import GHC.Cmm.Node
    
    25 26
     import GHC.Cmm.Utils
    
    ... ... @@ -73,6 +74,7 @@ import Data.List ( genericReplicate, intersperse
    73 74
     import Foreign hiding (shiftL, shiftR)
    
    74 75
     import Control.Monad
    
    75 76
     import Data.Char
    
    77
    +import Data.Word
    
    76 78
     
    
    77 79
     import GHC.Unit.Module
    
    78 80
     
    
    ... ... @@ -603,6 +605,11 @@ schemeE _d _s _p (StgTick (Breakpoint _ bp_id _) _rhs)
    603 605
        = pprPanic "schemeE: Breakpoint without let binding:"
    
    604 606
             (ppr bp_id <+> text "forgot to run bcPrep?")
    
    605 607
     
    
    608
    +schemeE d s p (StgTick (HpcTick mod ix) rhs) = do
    
    609
    +   platform <- profilePlatform <$> getProfile
    
    610
    +   rhs_code <- schemeE d s p rhs
    
    611
    +   pure (unitOL (HPC_TICK (mkHpcTickLabel platform mod) (fromIntegral ix)) `appOL` rhs_code)
    
    612
    +
    
    606 613
     -- ignore other kinds of tick
    
    607 614
     schemeE d s p (StgTick _ rhs) = schemeE d s p rhs
    
    608 615
     
    
    ... ... @@ -2767,6 +2774,10 @@ getLastBreakTick = BcM $ \env st ->
    2767 2774
     tickFS :: FastString
    
    2768 2775
     tickFS = fsLit "ticked"
    
    2769 2776
     
    
    2777
    +mkHpcTickLabel :: Platform -> Module -> FastString
    
    2778
    +mkHpcTickLabel platform mod =
    
    2779
    +  fsLit (showSDocOneLine defaultSDocContext (pprCode (pprCLabel platform (mkHpcTicksLabel mod))))
    
    2780
    +
    
    2770 2781
     -- Dehydrating CgBreakInfo
    
    2771 2782
     
    
    2772 2783
     dehydrateCgBreakInfo :: [TyVar] -> [Maybe (Id, Word)] -> Type -> Either InternalBreakLoc BreakpointId -> CgBreakInfo
    

  • rts/Disassembler.c
    ... ... @@ -101,6 +101,13 @@ disInstr ( StgBCO *bco, int pc )
    101 101
              }
    
    102 102
              debugBelch("\n");
    
    103 103
              break; }
    
    104
    +      case bci_HPC_TICK: {
    
    105
    +         W_ p1, info_wix;
    
    106
    +         p1       = BCO_GET_LARGE_ARG;
    
    107
    +         info_wix = BCO_READ_NEXT_32;
    
    108
    +         debugBelch("HPC_TICK "); printPtr((StgPtr)literals[p1]);
    
    109
    +         debugBelch(" %" FMT_Word "\n", info_wix);
    
    110
    +         break; }
    
    104 111
           case bci_SWIZZLE: {
    
    105 112
              W_     stkoff = BCO_GET_LARGE_ARG;
    
    106 113
              StgInt by     = BCO_GET_LARGE_ARG;
    

  • rts/Hpc.c
    ... ... @@ -270,6 +270,9 @@ hs_hpc_module(char *modName,
    270 270
       HpcModuleInfo *tmpModule;
    
    271 271
       uint32_t i;
    
    272 272
     
    
    273
    +  debugTrace(DEBUG_hpc, "hs_hpc_module(%s, count=%u, hash=%u)\n",
    
    274
    +             modName, modCount, modHashNo);
    
    275
    +
    
    273 276
       if (moduleHash == NULL) {
    
    274 277
           moduleHash = allocStrHashTable();
    
    275 278
       }
    
    ... ... @@ -320,6 +323,8 @@ hs_hpc_module(char *modName,
    320 323
           }
    
    321 324
           tmpModule->from_file = false;
    
    322 325
       }
    
    326
    +
    
    327
    +  startupHpc();
    
    323 328
     }
    
    324 329
     
    
    325 330
     static void
    

  • rts/Interpreter.c
    ... ... @@ -1739,6 +1739,7 @@ run_BCO:
    1739 1739
                 &&lbl_bci_TESTEQ_W8 - &&lbl_bci_DEFAULT,
    
    1740 1740
                 &&lbl_bci_PRIMCALL - &&lbl_bci_DEFAULT,
    
    1741 1741
                 &&lbl_bci_BCO_NAME - &&lbl_bci_DEFAULT,
    
    1742
    +            &&lbl_bci_HPC_TICK - &&lbl_bci_DEFAULT,
    
    1742 1743
                 &&lbl_bci_DEFAULT - &&lbl_bci_DEFAULT,
    
    1743 1744
                 &&lbl_bci_OP_ADD_64 - &&lbl_bci_DEFAULT,
    
    1744 1745
                 &&lbl_bci_OP_SUB_64 - &&lbl_bci_DEFAULT,
    
    ... ... @@ -2106,6 +2107,15 @@ run_BCO:
    2106 2107
                 NEXT_INSTRUCTION;
    
    2107 2108
             }
    
    2108 2109
     
    
    2110
    +        INSTRUCTION(bci_HPC_TICK): {
    
    2111
    +            W_ arg1_ticks_array, arg2_tick_index;
    
    2112
    +            arg1_ticks_array = BCO_GET_LARGE_ARG;
    
    2113
    +            arg2_tick_index  = BCO_READ_NEXT_32;
    
    2114
    +
    
    2115
    +            ((StgWord64*)BCO_LIT(arg1_ticks_array))[arg2_tick_index]++;
    
    2116
    +            NEXT_INSTRUCTION;
    
    2117
    +        }
    
    2118
    +
    
    2109 2119
             INSTRUCTION(bci_STKCHECK): {
    
    2110 2120
                 // Explicit stack check at the beginning of a function
    
    2111 2121
                 // *only* (stack checks in case alternatives are
    

  • rts/include/rts/Bytecodes.h
    ... ... @@ -118,6 +118,7 @@
    118 118
     #define bci_PRIMCALL                    87
    
    119 119
     
    
    120 120
     #define bci_BCO_NAME                    88
    
    121
    +#define bci_HPC_TICK                    89
    
    121 122
     
    
    122 123
     #define bci_OP_ADD_64                   90
    
    123 124
     #define bci_OP_SUB_64                   91
    

  • testsuite/tests/hpc/ghc_ghci/BytecodeMain.hs
    1
    +module Main where
    
    2
    +
    
    3
    +inc :: Int -> Int
    
    4
    +inc x = x + 1
    
    5
    +
    
    6
    +double :: Int -> Int
    
    7
    +double x = x * 2
    
    8
    +
    
    9
    +main :: IO ()
    
    10
    +main = print (double (inc 1011))

  • testsuite/tests/hpc/ghc_ghci/Makefile
    ... ... @@ -7,3 +7,9 @@ hpc_ghc_ghci:
    7 7
     	'$(TEST_HC)' $(TEST_HC_OPTS) -fhpc -c A.hs
    
    8 8
     	echo b | '$(TEST_HC)' $(TEST_HC_OPTS_INTERACTIVE) B.hs
    
    9 9
     
    
    10
    +hpc_ghc_ghci_bytecode:
    
    11
    +	rm -f ./*.tix
    
    12
    +	printf "main\n:quit\n" | '$(TEST_HC)' $(TEST_HC_OPTS_INTERACTIVE) -fhpc -fbyte-code-and-object-code -fprefer-byte-code BytecodeMain.hs
    
    13
    +	@[ -f .hpc/Main.mix ] || (echo "ERROR: Expected .hpc/Main.mix file not found"; exit 1)
    
    14
    +	@set -- ./*.tix; [ -f "$$1" ] || (echo "ERROR: Expected .tix file not found"; exit 1); '$(HPC)' report "$$1" Main > hpc-report.txt
    
    15
    +	@grep -F "100% expressions used" hpc-report.txt >/dev/null || (echo "ERROR: Expected full expression coverage in hpc report"; cat hpc-report.txt; exit 1)

  • testsuite/tests/hpc/ghc_ghci/hpc_ghc_ghci_bytecode.stdout
    1
    +2024

  • testsuite/tests/hpc/ghc_ghci/test.T
    ... ... @@ -3,3 +3,8 @@ test('hpc_ghc_ghci',
    3 3
          [extra_files(['A.hs', 'B.hs']),
    
    4 4
           only_ways(['normal']), when(compiler_profiled(), skip), req_interp],
    
    5 5
          run_command, ['$MAKE -s --no-print-directory hpc_ghc_ghci'])
    
    6
    +
    
    7
    +test('hpc_ghc_ghci_bytecode',
    
    8
    +     [extra_files(['BytecodeMain.hs']),
    
    9
    +      only_ways(['normal']), when(compiler_profiled(), skip), req_interp],
    
    10
    +     run_command, ['$MAKE -s --no-print-directory hpc_ghc_ghci_bytecode'])