Hannes Siebenhandl pushed to branch wip/fendor/no-code-output-constr at Glasgow Haskell Compiler / GHC

Commits:

10 changed files:

Changes:

  • compiler/GHC/Driver/Backend.hs
    ... ... @@ -99,6 +99,7 @@ module GHC.Driver.Backend
    99 99
        , backendPostHscPipeline
    
    100 100
        , backendNormalSuccessorPhase
    
    101 101
        , backendName
    
    102
    +   , backendInfoTableMapValidity
    
    102 103
        , backendValidityOfCImport
    
    103 104
        , backendValidityOfCExport
    
    104 105
     
    
    ... ... @@ -117,7 +118,6 @@ import GHC.Driver.Phases
    117 118
     
    
    118 119
     
    
    119 120
     import GHC.Utils.Error
    
    120
    -import GHC.Utils.Panic
    
    121 121
     
    
    122 122
     import GHC.Driver.Pipeline.Monad
    
    123 123
     import GHC.Platform
    
    ... ... @@ -368,7 +368,8 @@ data PrimitiveImplementation
    368 368
     -- We expect one function per back end—or more precisely, one function
    
    369 369
     -- for each back end that writes code to a file.  (The interpreter
    
    370 370
     -- does not write to files; its output lives only in memory.)
    
    371
    -
    
    371
    +--
    
    372
    +-- See Note [Backend Defunctionalization]
    
    372 373
     data DefunctionalizedCodeOutput
    
    373 374
       = NcgCodeOutput
    
    374 375
       | ViaCCodeOutput
    
    ... ... @@ -680,6 +681,18 @@ backendSupportsBreakpoints = \case
    680 681
       Named Bytecode -> True
    
    681 682
       Named NoBackend   -> False
    
    682 683
     
    
    684
    +-- | Return is 'IsValid' if the backend supports @-finfo-table-map@.
    
    685
    +-- If 'backendInfoTableMapValidity' returns 'NotValid', then the driver ignores
    
    686
    +-- the flag @-finfo-table-map@, since the backend doesn't support generating
    
    687
    +-- the info table map.
    
    688
    +backendInfoTableMapValidity :: Backend -> Validity' String
    
    689
    +backendInfoTableMapValidity (Named NCG)        = IsValid
    
    690
    +backendInfoTableMapValidity (Named LLVM)       = NotValid "-finfo-table-map is incompatible with -fllvm and is disabled (See #26435)"
    
    691
    +backendInfoTableMapValidity (Named ViaC)       = IsValid
    
    692
    +backendInfoTableMapValidity (Named JavaScript) = NotValid "-finfo-table-map is incompatible with the javascript backend"
    
    693
    +backendInfoTableMapValidity (Named Bytecode)   = NotValid "-finfo-table-map is incompatible with -fbyte-code and is disabled"
    
    694
    +backendInfoTableMapValidity (Named NoBackend)  = IsValid -- We are not generating code, so we ignore it any way
    
    695
    +
    
    683 696
     -- | If this flag is set, then the driver forces the
    
    684 697
     -- optimization level to 0, issuing a warning message if
    
    685 698
     -- the command line requested a higher optimization level.
    
    ... ... @@ -768,20 +781,33 @@ backendCDefs (Named NoBackend) = NoCDefs
    768 781
     -- > -> Set UnitId -- ^ dependencies
    
    769 782
     -- > -> Stream IO RawCmmGroup a -- results from `StgToCmm`
    
    770 783
     -- > -> IO a
    
    771
    -backendCodeOutput :: Backend -> DefunctionalizedCodeOutput
    
    772
    -backendCodeOutput (Named NCG)         = NcgCodeOutput
    
    773
    -backendCodeOutput (Named LLVM)        = LlvmCodeOutput
    
    774
    -backendCodeOutput (Named ViaC)        = ViaCCodeOutput
    
    775
    -backendCodeOutput (Named JavaScript)  = JSCodeOutput
    
    776
    -backendCodeOutput (Named Bytecode) = panic "backendCodeOutput: bytecodeBackend"
    
    777
    -backendCodeOutput (Named NoBackend)   = panic "backendCodeOutput: noBackend"
    
    784
    +--
    
    785
    +-- See Note [Backend Defunctionalization]
    
    786
    +--
    
    787
    +-- === __WARNING__
    
    788
    +--
    
    789
    +-- Do NOT use 'backendCodeOutput' (or other functions in this module) as a
    
    790
    +-- proxy for the 'Backend', which is __abstract by design__.
    
    791
    +--
    
    792
    +-- If you need to determine some property of the backend, do NOT match on
    
    793
    +-- 'DefunctionalizedCodeOutput'; Instead, write a new property predicate in
    
    794
    +-- this module. This makes it easier to add new backends because essentially
    
    795
    +-- all backend properties depended upon throughout the compiler are all found
    
    796
    +-- here.
    
    797
    +backendCodeOutput :: Backend -> Maybe DefunctionalizedCodeOutput
    
    798
    +backendCodeOutput (Named NCG)         = Just NcgCodeOutput
    
    799
    +backendCodeOutput (Named LLVM)        = Just LlvmCodeOutput
    
    800
    +backendCodeOutput (Named ViaC)        = Just ViaCCodeOutput
    
    801
    +backendCodeOutput (Named JavaScript)  = Just JSCodeOutput
    
    802
    +backendCodeOutput (Named Bytecode)    = Nothing
    
    803
    +backendCodeOutput (Named NoBackend)   = Nothing
    
    778 804
     
    
    779 805
     backendUseJSLinker :: Backend -> Bool
    
    780 806
     backendUseJSLinker (Named NCG)         = False
    
    781 807
     backendUseJSLinker (Named LLVM)        = False
    
    782 808
     backendUseJSLinker (Named ViaC)        = False
    
    783 809
     backendUseJSLinker (Named JavaScript)  = True
    
    784
    -backendUseJSLinker (Named Bytecode) = False
    
    810
    +backendUseJSLinker (Named Bytecode)    = False
    
    785 811
     backendUseJSLinker (Named NoBackend)   = False
    
    786 812
     
    
    787 813
     -- | This (defunctionalized) function tells the compiler
    

  • compiler/GHC/Driver/CodeOutput.hs
    ... ... @@ -4,7 +4,6 @@
    4 4
     \section{Code output phase}
    
    5 5
     -}
    
    6 6
     
    
    7
    -
    
    8 7
     module GHC.Driver.CodeOutput
    
    9 8
        ( codeOutput
    
    10 9
        , outputForeignStubs
    
    ... ... @@ -50,7 +49,7 @@ import GHC.Utils.Outputable
    50 49
     import GHC.Utils.Logger
    
    51 50
     import GHC.Utils.Exception ( bracket )
    
    52 51
     import GHC.Utils.Ppr (Mode(..))
    
    53
    -import GHC.Utils.Panic.Plain ( pgmError )
    
    52
    +import GHC.Utils.Panic.Plain ( panic, pgmError )
    
    54 53
     
    
    55 54
     import GHC.Unit
    
    56 55
     import GHC.Unit.Finder      ( mkStubPaths )
    
    ... ... @@ -124,11 +123,12 @@ codeOutput logger tmpfs llvm_config dflags unit_state this_mod filenm location g
    124 123
     
    
    125 124
             ; let dus1 = newTagDUniqSupply CodeGenTag dus0
    
    126 125
             ; (stubs, a) <- case backendCodeOutput (backend dflags) of
    
    127
    -                 NcgCodeOutput  -> outputAsm logger dflags this_mod location filenm dus1
    
    128
    -                                             final_stream
    
    129
    -                 ViaCCodeOutput -> outputC logger dflags filenm dus1 final_stream pkg_deps
    
    130
    -                 LlvmCodeOutput -> outputLlvm logger llvm_config dflags filenm dus1 final_stream
    
    131
    -                 JSCodeOutput   -> outputJS logger llvm_config dflags filenm final_stream
    
    126
    +             Just NcgCodeOutput  -> outputAsm logger dflags this_mod location filenm dus1
    
    127
    +                                              final_stream
    
    128
    +             Just ViaCCodeOutput -> outputC logger dflags filenm dus1 final_stream pkg_deps
    
    129
    +             Just LlvmCodeOutput -> outputLlvm logger llvm_config dflags filenm dus1 final_stream
    
    130
    +             Just JSCodeOutput   -> outputJS logger llvm_config dflags filenm final_stream
    
    131
    +             Nothing             -> panic $ "backendCodeOutput: " ++ show (backend dflags) ++ " doesn't support code output"
    
    132 132
             ; stubs_exist <- outputForeignStubs logger tmpfs dflags unit_state this_mod location stubs
    
    133 133
             ; return (filenm, stubs_exist, foreign_fps, a)
    
    134 134
             }
    

  • compiler/GHC/Driver/Main/Compile.hs
    ... ... @@ -670,7 +670,7 @@ hscGenHardCode hsc_env cgguts mod_loc output_filename = do
    670 670
             -- next withTiming after this will be "Assembler" (hard code only).
    
    671 671
             withTiming logger (text "CodeGen"<+>brackets (ppr this_mod)) (const ())
    
    672 672
              $ case backendCodeOutput (backend dflags) of
    
    673
    -            JSCodeOutput ->
    
    673
    +            Just JSCodeOutput ->
    
    674 674
                   do
    
    675 675
                   let js_config = initStgToJSConfig dflags
    
    676 676
     
    
    ... ... @@ -696,7 +696,7 @@ hscGenHardCode hsc_env cgguts mod_loc output_filename = do
    696 696
                   stgToJS logger js_config stg_binds this_mod spt_entries foreign_stubs0 cost_centre_info output_filename
    
    697 697
                   return (output_filename, stub_c_exists, foreign_fps, Just stg_cg_infos, Just cmm_cg_infos)
    
    698 698
     
    
    699
    -            _          ->
    
    699
    +            Just _          ->
    
    700 700
                   do
    
    701 701
                   cmms <- {-# SCC "StgToCmm" #-}
    
    702 702
                     doCodeGen hsc_env this_mod denv tycons
    
    ... ... @@ -724,6 +724,7 @@ hscGenHardCode hsc_env cgguts mod_loc output_filename = do
    724 724
                         foreign_stubs foreign_files dependencies (initDUniqSupply 'n' 0) rawcmms1
    
    725 725
                   return  ( output_filename, stub_c_exists, foreign_fps
    
    726 726
                           , Just stg_cg_infos, Just cmm_cg_infos)
    
    727
    +            Nothing -> panic $ "backendCodeOutput: " ++ show (backend dflags) ++ " doesn't support code output"
    
    727 728
     
    
    728 729
     
    
    729 730
     -- The part of CgGuts that we need for HscInteractive
    

  • compiler/GHC/Driver/Pipeline.hs
    ... ... @@ -741,7 +741,7 @@ compileEmptyStub dflags hsc_env basename location mod_name = do
    741 741
       let home_unit = hsc_home_unit hsc_env
    
    742 742
     
    
    743 743
       case backendCodeOutput (backend dflags) of
    
    744
    -    JSCodeOutput -> do
    
    744
    +    Just JSCodeOutput -> do
    
    745 745
           empty_stub <- newTempName logger tmpfs (tmpDir dflags) TFL_CurrentModule "js"
    
    746 746
           let src = ppr (mkHomeModule home_unit mod_name) <+> text "= 0;"
    
    747 747
           writeFile empty_stub (showSDoc dflags (pprCode src))
    
    ... ... @@ -750,7 +750,7 @@ compileEmptyStub dflags hsc_env basename location mod_name = do
    750 750
           _ <- runPipeline (hsc_hooks hsc_env) pipeline
    
    751 751
           pure ()
    
    752 752
     
    
    753
    -    _ -> do
    
    753
    +    Just _ -> do
    
    754 754
           empty_stub <- newTempName logger tmpfs (tmpDir dflags) TFL_CurrentModule "c"
    
    755 755
           let src = text "int" <+> ppr (mkHomeModule home_unit mod_name) <+> text "= 0;"
    
    756 756
           writeFile empty_stub (showSDoc dflags (pprCode src))
    
    ... ... @@ -758,6 +758,7 @@ compileEmptyStub dflags hsc_env basename location mod_name = do
    758 758
               pipeline = viaCPipeline HCc pipe_env hsc_env (Just location) empty_stub
    
    759 759
           _ <- runPipeline (hsc_hooks hsc_env) pipeline
    
    760 760
           pure ()
    
    761
    +    Nothing -> panic $ "backendCodeOutput: " ++ show (backend dflags) ++ " doesn't support code output"
    
    761 762
     
    
    762 763
     
    
    763 764
     
    

  • compiler/GHC/Driver/Session.hs
    ... ... @@ -276,7 +276,7 @@ import GHC.Data.FastString
    276 276
     import GHC.Utils.TmpFs
    
    277 277
     import GHC.Utils.Fingerprint
    
    278 278
     import GHC.Utils.Outputable
    
    279
    -import GHC.Utils.Error (emptyDiagOpts, logInfo)
    
    279
    +import GHC.Utils.Error (emptyDiagOpts, logInfo, Validity'(..))
    
    280 280
     import GHC.Settings
    
    281 281
     import GHC.CmmToAsm.CFG.Weight
    
    282 282
     import GHC.Core.Opt.CallerCC
    
    ... ... @@ -3855,8 +3855,8 @@ makeDynFlagsConsistent dflags
    3855 3855
        && os == OSMinGW32
    
    3856 3856
        && arch == ArchAArch64
    
    3857 3857
         = case backendCodeOutput (backend dflags) of
    
    3858
    -        LlvmCodeOutput -> pgmError "-fllvm is incompatible with enabled TablesNextToCode at Windows Aarch64"
    
    3859
    -        NcgCodeOutput -> pgmError "-fasm is incompatible with enabled TablesNextToCode at Windows Aarch64"
    
    3858
    +        Just LlvmCodeOutput -> pgmError "-fllvm is incompatible with enabled TablesNextToCode at Windows Aarch64"
    
    3859
    +        Just NcgCodeOutput -> pgmError "-fasm is incompatible with enabled TablesNextToCode at Windows Aarch64"
    
    3860 3860
             _ -> (dflags, mempty, mempty)
    
    3861 3861
     
    
    3862 3862
       -- When we do ghci, force using dyn ways if the target RTS linker
    
    ... ... @@ -3902,9 +3902,8 @@ makeDynFlagsConsistent dflags
    3902 3902
             in dflags_c
    
    3903 3903
     
    
    3904 3904
      | gopt Opt_InfoTableMap dflags
    
    3905
    - , LlvmCodeOutput <- backendCodeOutput (backend dflags)
    
    3906
    -    = loop (gopt_unset dflags Opt_InfoTableMap)
    
    3907
    -           "-finfo-table-map is incompatible with -fllvm and is disabled (See #26435)"
    
    3905
    + , NotValid msg <- backendInfoTableMapValidity (backend dflags)
    
    3906
    +    = loop (gopt_unset dflags Opt_InfoTableMap) msg
    
    3908 3907
     
    
    3909 3908
      | otherwise = (dflags, mempty, mempty)
    
    3910 3909
         where loc = mkGeneralSrcSpan (fsLit "when making flags consistent")
    

  • testsuite/tests/ghci/scripts/all.T
    ... ... @@ -385,6 +385,14 @@ test('ListTuplePunsPpr', normal, ghci_script, ['ListTuplePunsPpr.script'])
    385 385
     test('ListTuplePunsPprNoAbbrevTuple', [limit_stdout_lines(14)], ghci_script, ['ListTuplePunsPprNoAbbrevTuple.script'])
    
    386 386
     test('T24459', normal, ghci_script, ['T24459.script'])
    
    387 387
     test('T24632', normal, ghci_script, ['T24632.script'])
    
    388
    +# bytecode backend doesn't support '-finfo-table-map' (#27039)
    
    389
    +test('bytecodeIPE',
    
    390
    +     [ extra_hc_opts('-finfo-table-map')
    
    391
    +     , extra_files(['bytecodeIPE.hs'])
    
    392
    +     , req_rts_linker
    
    393
    +     , when(arch('wasm32') or arch('javascript'), skip)
    
    394
    +     ],
    
    395
    +     ghci_script, ['bytecodeIPE.script'])
    
    388 396
     
    
    389 397
     # Test package renaming in GHCi session
    
    390 398
     test('GhciPackageRename',
    

  • testsuite/tests/ghci/scripts/bytecodeIPE.hs
    1
    +module BytecodeIPE where
    
    2
    +
    
    3
    +import Data.Maybe (isJust)
    
    4
    +import GHC.InfoProv (whereFrom)
    
    5
    +
    
    6
    +marker :: String
    
    7
    +marker = id "bytecode-stub-init"
    
    8
    +{-# NOINLINE marker #-}
    
    9
    +
    
    10
    +-- `whereFrom` only succeeds if the module's IPE initializer ran.
    
    11
    +probe :: IO Bool
    
    12
    +probe = isJust <$> whereFrom marker

  • testsuite/tests/ghci/scripts/bytecodeIPE.script
    1
    +:load bytecodeIPE.hs
    
    2
    +probe

  • testsuite/tests/ghci/scripts/bytecodeIPE.stderr
    1
    +when making flags consistent: warning: [GHC-74335] [-Winconsistent-flags (in -Wdefault)]
    
    2
    +    -finfo-table-map is incompatible with -fbyte-code interpreter and is disabled

  • testsuite/tests/ghci/scripts/bytecodeIPE.stdout
    1
    +False