Skip to content

Commit

Permalink
[Builtins] Make 'geq' inlinable (#5061)
Browse files Browse the repository at this point in the history
  • Loading branch information
effectfully authored Feb 16, 2023
1 parent 9a930a8 commit 02d518e
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
### Changed

- Made `geq` faster in certain cases, -1% of total validation time. [#5061](https://github.com/input-output-hk/plutus/pull/5061)

49 changes: 48 additions & 1 deletion plutus-core/plutus-core/src/PlutusCore/Default/Universe.hs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,54 @@ pattern DefaultUniList uniA =
pattern DefaultUniPair uniA uniB =
DefaultUniProtoPair `DefaultUniApply` uniA `DefaultUniApply` uniB

deriveGEq ''DefaultUni
instance GEq DefaultUni where
-- We define 'geq' manually instead of using 'deriveGEq', because the latter creates a single
-- recursive definition and we want two instead. The reason why we want two is because this
-- allows GHC to inline the initial step that appears non-recursive to GHC, because recursion
-- is hidden in the other function that is marked as @NOINLINE@ and is chosen by GHC as a
-- loop-breaker, see https://wiki.haskell.org/Inlining_and_Specialisation#What_is_a_loop-breaker.3F
-- (we're not really sure if this is a reliable solution, but if it stops working, we won't miss
-- very much and we've failed to settle on any other approach).
--
-- This trick gives us a 1% speedup across validation benchmarks (some are up to 4% faster) and
-- a more sensible generated Core where things like @geq DefaulUniBool@ are reduced away.
geq = geqStep where
geqStep :: DefaultUni a1 -> DefaultUni a2 -> Maybe (a1 :~: a2)
geqStep DefaultUniInteger a2 = do
DefaultUniInteger <- Just a2
Just Refl
geqStep DefaultUniByteString a2 = do
DefaultUniByteString <- Just a2
Just Refl
geqStep DefaultUniString a2 = do
DefaultUniString <- Just a2
Just Refl
geqStep DefaultUniUnit a2 = do
DefaultUniUnit <- Just a2
Just Refl
geqStep DefaultUniBool a2 = do
DefaultUniBool <- Just a2
Just Refl
geqStep DefaultUniProtoList a2 = do
DefaultUniProtoList <- Just a2
Just Refl
geqStep DefaultUniProtoPair a2 = do
DefaultUniProtoPair <- Just a2
Just Refl
geqStep (DefaultUniApply f1 x1) a2 = do
DefaultUniApply f2 x2 <- Just a2
Refl <- geqRec f1 f2
Refl <- geqRec x1 x2
Just Refl
geqStep DefaultUniData a2 = do
DefaultUniData <- Just a2
Just Refl
{-# INLINE geqStep #-}

geqRec :: DefaultUni a1 -> DefaultUni a2 -> Maybe (a1 :~: a2)
geqRec = geqStep
{-# NOINLINE geqRec #-}

deriveGCompare ''DefaultUni

-- | For pleasing the coverage checker.
Expand Down

0 comments on commit 02d518e

Please sign in to comment.