Hannes Siebenhandl pushed to branch wip/fendor/no-code-output-constr at Glasgow Haskell Compiler / GHC
Commits:
10 changed files:
- compiler/GHC/Driver/Backend.hs
- compiler/GHC/Driver/CodeOutput.hs
- compiler/GHC/Driver/Main/Compile.hs
- compiler/GHC/Driver/Pipeline.hs
- compiler/GHC/Driver/Session.hs
- testsuite/tests/ghci/scripts/all.T
- + testsuite/tests/ghci/scripts/bytecodeIPE.hs
- + testsuite/tests/ghci/scripts/bytecodeIPE.script
- + testsuite/tests/ghci/scripts/bytecodeIPE.stderr
- + testsuite/tests/ghci/scripts/bytecodeIPE.stdout
Changes:
| ... | ... | @@ -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
|
| ... | ... | @@ -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 | }
|
| ... | ... | @@ -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
|
| ... | ... | @@ -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 |
| ... | ... | @@ -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")
|
| ... | ... | @@ -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',
|
| 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 |
| 1 | +:load bytecodeIPE.hs
|
|
| 2 | +probe |
| 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 |
| 1 | +False |