/testsuite/tests/tcplugins/RewritePerfPlugin.hs

https://github.com/bgamari/ghc · Haskell · 97 lines · 77 code · 11 blank · 9 comment · 1 complexity · 4e57fef5b9df0da1654c0f06b3c710d9 MD5 · raw file

  1. {-# LANGUAGE TupleSections #-}
  2. module RewritePerfPlugin where
  3. -- Testing performance of rewriting type-family applications.
  4. -- ghc
  5. import GHC.Core
  6. ( Expr(Coercion) )
  7. import GHC.Core.Coercion
  8. ( mkUnivCo )
  9. import GHC.Core.TyCo.Rep
  10. ( Type, UnivCoProvenance(PluginProv) )
  11. import GHC.Core.TyCon
  12. ( TyCon )
  13. import GHC.Core.Type
  14. ( eqType, mkTyConApp, splitTyConApp_maybe )
  15. import GHC.Plugins
  16. ( Plugin(..), defaultPlugin, purePlugin )
  17. import GHC.Tc.Plugin
  18. ( TcPluginM
  19. , findImportedModule, lookupOrig
  20. , tcLookupClass, tcLookupDataCon, tcLookupTyCon
  21. , unsafeTcPluginTcM
  22. )
  23. import GHC.Tc.Types
  24. ( TcPlugin(..)
  25. , TcPluginSolveResult(..), TcPluginRewriteResult(..)
  26. , TcPluginRewriter, RewriteEnv
  27. )
  28. import GHC.Tc.Types.Constraint
  29. ( Ct(..), CanEqLHS(..)
  30. , ctPred
  31. )
  32. import GHC.Types.Name.Occurrence
  33. ( mkTcOcc )
  34. import GHC.Types.Unique.FM
  35. ( UniqFM, listToUFM )
  36. import GHC.Types.PkgQual
  37. import GHC.Unit.Finder
  38. ( FindResult(..) )
  39. import GHC.Unit.Module
  40. ( Module
  41. , mkModuleName
  42. )
  43. --------------------------------------------------------------------------------
  44. -- In this test, we write a plugin which returns "TcPluginNoRewrite"
  45. -- for all the type families in RewritePerfDefs.
  46. --
  47. -- Comparing the result with T9872b gives an indication of the performance
  48. -- impact of rewriting plugins in code that heavily rewrites type families.
  49. type PluginDefs = [ TyCon ]
  50. definitionsModule :: TcPluginM Module
  51. definitionsModule = do
  52. findResult <- findImportedModule ( mkModuleName "RewritePerfDefs" ) NoPkgQual
  53. case findResult of
  54. Found _ res -> pure res
  55. FoundMultiple _ -> error $ "RewritePerfPlugin: found multiple modules named 'RewritePerfDefs'."
  56. _ -> error $ "RewritePerfPlugin: could not find any module named 'RewritePerfDefs'."
  57. lookupDefs :: TcPluginM PluginDefs
  58. lookupDefs = do
  59. defs <- definitionsModule
  60. traverse ( \ tyConName -> lookupOrig defs ( mkTcOcc tyConName ) >>= tcLookupTyCon )
  61. [ "And", "NE", "EQ", "All", "ListConcat", "AppendIf", "Apply"
  62. , "Map", "MapAppend", "MapAppend2", "MapAppend3"
  63. , "Iterate2", "Iterate3", "Iterate4"
  64. , "Orientations", "Compatible", "Allowed"
  65. , "MatchingOrientations", "AllowedCombinations"
  66. , "Solutions"
  67. ]
  68. plugin :: Plugin
  69. plugin =
  70. defaultPlugin
  71. { tcPlugin = \ _args -> Just $ rewritingPlugin
  72. , pluginRecompile = purePlugin
  73. }
  74. rewritingPlugin :: TcPlugin
  75. rewritingPlugin =
  76. TcPlugin
  77. { tcPluginInit = lookupDefs
  78. , tcPluginSolve = \ _ _ _ _ -> pure $ TcPluginOk [] []
  79. , tcPluginRewrite = rewriter
  80. , tcPluginStop = \ _ -> pure ()
  81. }
  82. rewriter :: PluginDefs -> UniqFM TyCon TcPluginRewriter
  83. rewriter tyCons =
  84. listToUFM $ map ( , don'tRewrite ) tyCons
  85. don'tRewrite :: RewriteEnv -> [ Ct ] -> [ Type ] -> TcPluginM TcPluginRewriteResult
  86. don'tRewrite _ _ _ = pure TcPluginNoRewrite