Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ stack.yaml.lock
*.chi
*.chs.h
*.prof
*.hp
*.ps
.liquid/

# Agda
Expand Down
2 changes: 2 additions & 0 deletions nix/shell.nix
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ let
fourmolu = "0.17.0.0";
hlint = "3.8";
stylish-haskell = "latest";
hp2ps = "latest";
hp2pretty = "latest";
};

# Pre-commit hooks for the repo. Injects into shell via shellHook.
Expand Down
42 changes: 33 additions & 9 deletions plutus-tx-plugin/plutus-tx-plugin.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -54,20 +54,20 @@ library
import: lang, ghc-version-support, os-support
hs-source-dirs: src
exposed-modules:
PlutusTx.Compiler.Builtins
PlutusTx.Compiler.Error
PlutusTx.Compiler.Types
PlutusTx.Options
PlutusTx.Plugin

other-modules:
PlutusTx.Compiler.Binders
PlutusTx.Compiler.Builtins
PlutusTx.Compiler.Expr
PlutusTx.Compiler.Kind
PlutusTx.Compiler.Laziness
PlutusTx.Compiler.Names
PlutusTx.Compiler.Trace
PlutusTx.Compiler.Type
PlutusTx.Compiler.Types
PlutusTx.Compiler.Utils
PlutusTx.PIRTypes
PlutusTx.PLCTypes
Expand Down Expand Up @@ -124,10 +124,6 @@ test-suite plutus-tx-plugin-tests
AssocMap.Properties3
AssocMap.Semantics
AssocMap.Spec
Blueprint.Tests
Blueprint.Tests.Lib
Blueprint.Tests.Lib.AsData.Blueprint
Blueprint.Tests.Lib.AsData.Decls
Budget.Spec
Budget.WithGHCOptimisations
Budget.WithoutGHCOptimisations
Expand All @@ -136,7 +132,6 @@ test-suite plutus-tx-plugin-tests
ByteStringLiterals.Spec
CallTrace.Lib
CallTrace.OtherModule
CallTrace.Spec
DataList.Budget.Spec
Inline.Spec
IntegerLiterals.NoStrict.NegativeLiterals.Spec
Expand Down Expand Up @@ -177,10 +172,15 @@ test-suite plutus-tx-plugin-tests
ShortCircuit.WithoutGHCOptimisations
StdLib.Spec
Strictness.Spec
TH.Spec
TH.TestTH
Unicode.Spec

-- Blueprint.Tests
-- Blueprint.Tests.Lib
-- Blueprint.Tests.Lib.AsData.Blueprint
-- Blueprint.Tests.Lib.AsData.Decls
-- CallTrace.Spec
-- TH.Spec
-- TH.TestTH
build-depends:
, base >=4.9 && <5
, base16-bytestring
Expand Down Expand Up @@ -241,3 +241,27 @@ test-suite size
ghc-options:
-fno-strictness -fno-unbox-strict-fields
-fno-unbox-small-strict-fields -fno-full-laziness

test-suite plutus-tx-plugin-profile-test
import: lang, ghc-version-support, os-support
type: exitcode-stdio-1.0
main-is: ProfileTest.hs
hs-source-dirs: test/Plugin/Profiling
build-depends:
, base >=4.9 && <5
, containers
, data-default
, ghc
, ghc-paths
, mtl
, plutus-core ^>=1.55
, plutus-core:plutus-ir
, plutus-tx-plugin ^>=1.55

default-extensions: Strict
ghc-options: -threaded -rtsopts -with-rtsopts=-N

-- See Note [-fno-full-laziness in Plutus Tx]
ghc-options:
-fno-strictness -fno-unbox-strict-fields
-fno-unbox-small-strict-fields -fno-full-laziness
24 changes: 18 additions & 6 deletions plutus-tx-plugin/src/PlutusTx/Plugin.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
-- For some reason this module is very slow to compile otherwise
{-# OPTIONS_GHC -O0 #-}

module PlutusTx.Plugin (plugin, plc) where
module PlutusTx.Plugin (plugin, plc, runCompiler) where

import PlutusPrelude
import PlutusTx.AsData.Internal qualified
Expand Down Expand Up @@ -610,23 +610,31 @@ runCompiler moduleName opts expr = do
(opts ^. posPreserveLogging)

-- GHC.Core -> Pir translation.
pirT <- original <$> (PIR.runDefT annMayInline $ compileExprWithDefs expr)
pirT <-
{-# SCC "plinth-plugin-core-to-pir-step" #-}
original <$> (PIR.runDefT annMayInline $ compileExprWithDefs expr)

let pirP = PIR.Program noProvenance plcVersion pirT
when (opts ^. posDumpPir) . liftIO $
dumpFlat (void pirP) "initial PIR program" (moduleName ++ "_initial.pir-flat")

-- Pir -> (Simplified) Pir pass. We can then dump/store a more legible PIR program.
spirP <-
{-# SCC "plinth-plugin-pir-to-simp-step" #-}
flip runReaderT pirCtx $
modifyError (NoContext . PIRError) $
PIR.compileToReadable pirP

when (opts ^. posDumpPir) . liftIO $
dumpFlat (void spirP) "simplified PIR program" (moduleName ++ "_simplified.pir-flat")

-- (Simplified) Pir -> Plc translation.
plcP <- flip runReaderT pirCtx $
modifyError (NoContext . PIRError) $
PIR.compileReadableToPlc spirP
plcP <-
{-# SCC "plinth-plugin-simp-to-plc-step" #-}
flip runReaderT pirCtx $
modifyError (NoContext . PIRError) $
PIR.compileReadableToPlc spirP

when (opts ^. posDumpPlc) . liftIO $
dumpFlat (void plcP) "typed PLC program" (moduleName ++ ".tplc-flat")

Expand All @@ -636,7 +644,11 @@ runCompiler moduleName opts expr = do
modifyError PLC.TypeErrorE $
PLC.inferTypeOfProgram plcTcConfig (plcP $> annMayInline)

(uplcP, _) <- flip runReaderT plcOpts $ PLC.compileProgramWithTrace plcP
(uplcP, _) <-
{-# SCC "plinth-plugin-plc-to-uplc-step" #-}
flip runReaderT plcOpts $ PLC.compileProgramWithTrace plcP


dbP <- liftExcept $ modifyError PLC.FreeVariableErrorE $ traverseOf UPLC.progTerm UPLC.deBruijnTerm uplcP
when (opts ^. posDumpUPlc) . liftIO $
dumpFlat
Expand Down
127 changes: 127 additions & 0 deletions plutus-tx-plugin/test/Plugin/Profiling/ProfileTest.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-}

-- | Standalone executable for profiling the plugin compilation functions.
--
-- This test uses the exposed 'runCompiler' from Plugin.hs to compile a simple
-- Core expression. This allows profiling the plugin code at runtime, including
-- the SCC annotations in Plugin.hs.
--
-- To run with profiling:
-- cabal build plutus-tx-plugin-profile-test --enable-profiling
-- cabal run plutus-tx-plugin-profile-test --enable-profiling -- +RTS -p -hc
module Main where

import Data.Default
import Data.Foldable (fold)
import PlutusCore qualified as PLC
import PlutusCore.Quote
import PlutusCore.Version qualified as PLC
import PlutusIR.Compiler qualified as PIR
import PlutusIR.Compiler.Types qualified as PIR
import PlutusIR.Transform.RewriteRules
import PlutusIR.Transform.RewriteRules.RemoveTrace (rewriteRuleRemoveTrace)
import PlutusTx.Compiler.Types
import PlutusTx.Options (PluginOptions (..), defaultPluginOptions)
import PlutusTx.Plugin (runCompiler)

import GHC qualified as GHC
import GHC.Core.FamInstEnv qualified as GHC
import GHC.Core.Opt.OccurAnal qualified as GHC
import GHC.Driver.Session qualified as GHC
import GHC.Paths as GHC
import GHC.Plugins qualified as GHC

import Control.Monad.Except
import Control.Monad.Reader
import Control.Monad.State
import Control.Monad.Writer

import Data.Map qualified as Map

-- | Create a simple Core expression for testing (a literal integer)
createSimpleCoreExpr :: GHC.DynFlags -> GHC.CoreExpr
createSimpleCoreExpr _flags =
let lit = GHC.Lit (GHC.LitNumber GHC.LitNumInt 42)
in lit

-- | Set up a minimal CompileContext for testing
setupCompileContext
:: GHC.DynFlags
-> GHC.FamInstEnvs
-> NameInfo
-> CompileContext PLC.DefaultUni PLC.DefaultFun
setupCompileContext flags famEnvs nameInfo =
let opts = defaultPluginOptions
coverage = CoverageOpts mempty
in CompileContext
{ ccOpts =
CompileOptions
{ coProfile = _posProfile opts
, coCoverage = coverage
, coDatatypeStyle =
if _posPlcTargetVersion opts < PLC.plcVersion110
then PIR.ScottEncoding
else PIR._dcoStyle $ _posDatatypes opts
, coRemoveTrace = _posRemoveTrace opts
, coInlineFix = _posInlineFix opts
}
, ccFlags = flags
, ccFamInstEnvs = famEnvs
, ccNameInfo = nameInfo
, ccScope = initialScope
, ccBlackholed = mempty
, ccCurDef = Nothing
, ccModBreaks = Nothing
, ccBuiltinsInfo = def
, ccBuiltinCostModel = def
, ccDebugTraceOn = _posDumpCompilationTrace opts
, ccRewriteRules = makeRewriteRules opts
, ccSafeToInline = False
}
where
makeRewriteRules :: PluginOptions -> RewriteRules PLC.DefaultUni PLC.DefaultFun
makeRewriteRules options =
fold
[ mwhen (_posRemoveTrace options) rewriteRuleRemoveTrace
, defaultUniRewriteRules
]
mwhen :: Monoid m => Bool -> m -> m
mwhen b m = if b then m else mempty

-- | Create empty NameInfo (simplified - in real usage would need proper lookups)
createEmptyNameInfo :: NameInfo
createEmptyNameInfo = Map.empty

main :: IO ()
main = do
putStrLn "Setting up for plugin profiling test..."

-- Use GHC's API to get DynFlags
GHC.defaultErrorHandler GHC.defaultFatalMessager GHC.defaultFlushOut $ do
-- Initialize GHC session to get DynFlags
GHC.runGhc (Just GHC.libdir) $ do
-- Get DynFlags
flags <- GHC.getSessionDynFlags

-- Create a simple Core expression (literal integer)
let expr = createSimpleCoreExpr flags

-- Set up minimal context
let famEnvs = (GHC.emptyFamInstEnv, GHC.emptyFamInstEnv)
nameInfo = createEmptyNameInfo
ctx = setupCompileContext flags famEnvs nameInfo
opts = defaultPluginOptions
st = CompileState 0 mempty
moduleNameStr = "ProfileTest"
-- Apply occurrence analysis like the plugin does
expr' = GHC.occurAnalyseExpr expr

-- Call runCompiler - this is where the SCC annotations are!
_ <-
runExceptT . runWriterT . runQuoteT . flip runReaderT ctx . flip evalStateT st $
runCompiler moduleNameStr opts expr'

pure ()
12 changes: 6 additions & 6 deletions plutus-tx-plugin/test/Spec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ module Main (main) where
import Array.Spec qualified as Array
import AsData.Budget.Spec qualified as AsData.Budget
import AssocMap.Spec qualified as AssocMap
import Blueprint.Tests qualified
-- import Blueprint.Tests qualified
import Budget.Spec qualified as Budget
import BuiltinList.Budget.Spec qualified as BuiltinList.Budget
import ByteStringLiterals.Spec qualified as ByteStringLiterals
import CallTrace.Spec qualified as CallTrace
-- import CallTrace.Spec qualified as CallTrace
import DataList.Budget.Spec qualified as DataList.Budget
import Inline.Spec qualified as Inline
import IntegerLiterals.NoStrict.NegativeLiterals.Spec qualified
Expand All @@ -23,7 +23,7 @@ import Recursion.Spec qualified as Recursion
import ShortCircuit.Spec qualified as ShortCircuit
import StdLib.Spec qualified as Lib
import Strictness.Spec qualified as Strictness
import TH.Spec qualified as TH
-- import TH.Spec qualified as TH
import Unicode.Spec qualified as Unicode

import Test.Tasty (TestTree, defaultMain)
Expand All @@ -44,7 +44,7 @@ tests =
, embed ByteStringLiterals.tests
, IsData.tests
, Lift.tests
, TH.tests
-- , TH.tests
, Lib.tests
, Budget.tests
, AsData.Budget.tests
Expand All @@ -54,12 +54,12 @@ tests =
, Recursion.tests
, Optimization.tests
, Strictness.tests
, Blueprint.Tests.tests
-- , Blueprint.Tests.tests
, AssocMap.goldenTests
, embed ShortCircuit.tests
, embed Unicode.tests
, embed AssocMap.propertyTests
, embed List.propertyTests
, Array.smokeTests
, CallTrace.tests
-- , CallTrace.tests
]