From c6ce242e846a3ca05eb04abf0e7d34dbcaa62906 Mon Sep 17 00:00:00 2001 From: Cheng Shao <terrorjack@type.dance> Date: Fri, 26 Jan 2024 02:30:10 +0000 Subject: [PATCH] compiler: enable generic cmm optimizations in wasm backend NCG This commit enables the generic cmm optimizations in other NCGs to be run in the wasm backend as well, followed by a late cmm control-flow optimization pass. The added optimizations do catch some corner cases not handled by the pre-NCG cmm pipeline and are useful in generating smaller CFGs. --- compiler/GHC/CmmToAsm.hs | 2 +- compiler/GHC/CmmToAsm/Wasm.hs | 26 ++++++++++++++++++++------ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/compiler/GHC/CmmToAsm.hs b/compiler/GHC/CmmToAsm.hs index 9000573523e8..40647d339151 100644 --- a/compiler/GHC/CmmToAsm.hs +++ b/compiler/GHC/CmmToAsm.hs @@ -153,7 +153,7 @@ nativeCodeGen logger ts config modLoc h us cmms ArchLoongArch64->panic "nativeCodeGen: No NCG for LoongArch64" ArchUnknown -> panic "nativeCodeGen: No NCG for unknown arch" ArchJavaScript-> panic "nativeCodeGen: No NCG for JavaScript" - ArchWasm32 -> Wasm32.ncgWasm logger platform ts us modLoc h cmms + ArchWasm32 -> Wasm32.ncgWasm config logger platform ts us modLoc h cmms -- | Data accumulated during code generation. Mostly about statistics, -- but also collects debug data for DWARF generation. diff --git a/compiler/GHC/CmmToAsm/Wasm.hs b/compiler/GHC/CmmToAsm/Wasm.hs index 285a7d8e9ae5..511af517a687 100644 --- a/compiler/GHC/CmmToAsm/Wasm.hs +++ b/compiler/GHC/CmmToAsm/Wasm.hs @@ -1,6 +1,7 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE Strict #-} +{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} module GHC.CmmToAsm.Wasm (ncgWasm) where @@ -9,6 +10,9 @@ import Data.ByteString.Lazy.Char8 (unpack) import Data.Maybe import Data.Semigroup import GHC.Cmm +import GHC.Cmm.ContFlowOpt +import GHC.Cmm.GenericOpt +import GHC.CmmToAsm.Config import GHC.CmmToAsm.Wasm.Asm import GHC.CmmToAsm.Wasm.FromCmm import GHC.CmmToAsm.Wasm.Types @@ -24,6 +28,7 @@ import GHC.Utils.Outputable (text) import System.IO ncgWasm :: + NCGConfig -> Logger -> Platform -> ToolSettings -> @@ -32,8 +37,8 @@ ncgWasm :: Handle -> Stream IO RawCmmGroup a -> IO a -ncgWasm logger platform ts us loc h cmms = do - (r, s) <- streamCmmGroups platform us cmms +ncgWasm ncg_config logger platform ts us loc h cmms = do + (r, s) <- streamCmmGroups ncg_config platform us cmms outputWasm $ "# " <> string7 (fromJust $ ml_hs_file loc) <> "\n\n" outputWasm $ execWasmAsmM do_tail_call $ asmTellEverything TagI32 s pure r @@ -51,17 +56,26 @@ ncgWasm logger platform ts us loc h cmms = do hPutBuilder h builder streamCmmGroups :: + NCGConfig -> Platform -> UniqSupply -> Stream IO RawCmmGroup a -> IO (a, WasmCodeGenState 'I32) -streamCmmGroups platform us cmms = - go (initialWasmCodeGenState platform us) $ - runStream cmms +streamCmmGroups ncg_config platform us cmms = + go (initialWasmCodeGenState platform us) $ runStream cmms where go s (Done r) = pure (r, s) go s (Effect m) = m >>= go s - go s (Yield cmm k) = go (wasmExecM (onCmmGroup cmm) s) k + go s (Yield decls k) = go (wasmExecM (onCmmGroup $ map opt decls) s) k + where + -- Run the generic cmm optimizations like other NCGs, followed + -- by a late control-flow optimization pass that does shrink + -- the CFG block count in some cases. + opt decl = case decl of + CmmData {} -> decl + CmmProc {} -> CmmProc info lbl live $ cmmCfgOpts False graph + where + (CmmProc info lbl live graph, _) = cmmToCmm ncg_config decl doTailCall :: ToolSettings -> Bool doTailCall ts = Option "-mtail-call" `elem` as_args -- GitLab