reuse string lits

This commit is contained in:
2026-05-26 02:53:50 -06:00
parent 13827f880e
commit 8345763bee
3 changed files with 35 additions and 24 deletions

View File

@@ -50,6 +50,9 @@ import Control.Lens.Unsound
import qualified Data.Bits import qualified Data.Bits
import qualified GHC.IO.Encoding as T import qualified GHC.IO.Encoding as T
import qualified Data.Text.Encoding as T import qualified Data.Text.Encoding as T
import Data.HashMap.Strict (HashMap)
import Effectful.State.Static.Local
import qualified Data.HashMap.Strict as HM
data Val data Val
@@ -277,18 +280,23 @@ lowerInt = QBE.ValConst . QBE.CInt
. fromIntegral . fromIntegral
lowerString lowerString
:: forall es. (GenSym :> es, Writer (Vector QBE.DataDef) :> es) :: forall es. (GenSym :> es, State StringLiterals :> es)
=> Text -> (QBE.Val -> Eff es BlockBuilder) -> Eff es BlockBuilder => Text -> (QBE.Val -> Eff es BlockBuilder) -> Eff es BlockBuilder
lowerString s k = do lowerString s k = do
rawString <- gensym let len = lengthOf each $ T.encodeUtf8 s
rawString <- getRawString
r <- gensym r <- gensym
let bs = T.encodeUtf8 s
len = lengthOf each bs
tell . pure $
QBE.DataDef [] rawString Nothing
[QBE.FieldExtTy QBE.Byte [QBE.String bs]]
Emit (alloc r rawString len) <$> k (QBE.ValTemporary r) Emit (alloc r rawString len) <$> k (QBE.ValTemporary r)
where where
-- getRawString
-- :: forall es. (GenSym :> es, State StringLiterals :> es)
-- => Eff es _
getRawString = do
x <- get
case x ^. at s of
Just s' -> pure s'
Nothing -> do r <- gensym
state \lits -> (r, HM.insert s r lits)
alloc r rs len = alloc r rs len =
[ QBE.Call [ QBE.Call
(Just (r, QBE.AbiBaseTy QBE.Long)) (Just (r, QBE.AbiBaseTy QBE.Long))
@@ -302,8 +310,10 @@ lowerString s k = do
[] []
] ]
type StringLiterals = HashMap Text (QBE.Ident QBE.Global)
lowerVal lowerVal
:: forall es. (GenSym :> es, Writer (Vector QBE.DataDef) :> es) :: forall es. (GenSym :> es, State StringLiterals :> es)
=> Val => Val
-> (QBE.Val -> Eff es BlockBuilder) -> (QBE.Val -> Eff es BlockBuilder)
-> Eff es BlockBuilder -> Eff es BlockBuilder
@@ -353,7 +363,7 @@ sizeofScm :: Integral a => a
sizeofScm = 8 sizeofScm = 8
lowerCons lowerCons
:: (GenSym :> es, Writer (Vector QBE.DataDef) :> es) :: (GenSym :> es, State StringLiterals :> es)
=> Name -> QBE.Val -> QBE.Val -> Exp => Name -> QBE.Val -> QBE.Val -> Exp
-> (QBE.Val -> Eff es BlockBuilder) -> (QBE.Val -> Eff es BlockBuilder)
-> Eff es BlockBuilder -> Eff es BlockBuilder
@@ -442,7 +452,7 @@ smallIntMask :: Integer
smallIntMask = 2 ^ (sizeofScm * 8) - 2 smallIntMask = 2 ^ (sizeofScm * 8) - 2
lowerCar lowerCar
:: (GenSym :> es, Writer (Vector QBE.DataDef) :> es) :: (GenSym :> es, State StringLiterals :> es)
=> Name -> QBE.Val -> _ => Name -> QBE.Val -> _
-> (QBE.Val -> Eff es BlockBuilder) -> Eff es BlockBuilder -> (QBE.Val -> Eff es BlockBuilder) -> Eff es BlockBuilder
lowerCar r x e k = do lowerCar r x e k = do
@@ -451,7 +461,7 @@ lowerCar r x e k = do
<$> lower' e k <$> lower' e k
lowerCdr lowerCdr
:: (GenSym :> es, Writer (Vector QBE.DataDef) :> es) :: (GenSym :> es, State StringLiterals :> es)
=> Name -> QBE.Val -> Exp => Name -> QBE.Val -> Exp
-> (QBE.Val -> Eff es BlockBuilder) -> Eff es BlockBuilder -> (QBE.Val -> Eff es BlockBuilder) -> Eff es BlockBuilder
lowerCdr r x e k = do lowerCdr r x e k = do
@@ -472,7 +482,7 @@ lowerNewline r k =
<$> k (QBE.ValTemporary (lowerName r)) <$> k (QBE.ValTemporary (lowerName r))
lowerPrim lowerPrim
:: forall es. (GenSym :> es, Writer (Vector QBE.DataDef) :> es) :: forall es. (GenSym :> es, State StringLiterals :> es)
=> Name -> Prim Val -> Exp => Name -> Prim Val -> Exp
-> (QBE.Val -> Eff es BlockBuilder) -> (QBE.Val -> Eff es BlockBuilder)
-> Eff es BlockBuilder -> Eff es BlockBuilder
@@ -491,7 +501,7 @@ lowerPrim r p e k =
PrimNewline -> lowerNewline r k PrimNewline -> lowerNewline r k
lower' lower'
:: forall es. (GenSym :> es, Writer (Vector QBE.DataDef) :> es) :: forall es. (GenSym :> es, State StringLiterals :> es)
=> Exp => Exp
-> (QBE.Val -> Eff es BlockBuilder) -> (QBE.Val -> Eff es BlockBuilder)
-> Eff es BlockBuilder -> Eff es BlockBuilder
@@ -517,12 +527,17 @@ lower' (ExpBegin (x:xs)) k = fold1 <$> traverse low (x:|xs)
lower' _ k = _ lower' _ k = _
lower lower
:: (GenSym :> es, Writer (Vector QBE.DataDef) :> es) :: (GenSym :> es, State StringLiterals :> es)
=> QBE.Ident QBE.Label => QBE.Ident QBE.Label
-> Exp -> Exp
-> Eff es QBE.Block -> Eff es QBE.Block
lower n e = buildBlock n <$> lower' e (pure . Exit . QBE.Ret . Just) lower n e = buildBlock n <$> lower' e (pure . Exit . QBE.Ret . Just)
lowerStringLiterals =
ifoldMapOf itraversed \s v ->
[ QBE.DataDef [] v Nothing
[QBE.FieldExtTy QBE.Byte [QBE.String (T.encodeUtf8 s)]]]
lowerProgram lowerProgram
:: (GenSym :> es, Traversable t) :: (GenSym :> es, Traversable t)
=> t Exp -> Eff es QBE.Program => t Exp -> Eff es QBE.Program
@@ -531,17 +546,18 @@ lowerProgram anfs =
-- hack for dev convenience: if there's only one expression, let -- hack for dev convenience: if there's only one expression, let
-- it be the entry point. -- it be the entry point.
[e] -> do [e] -> do
(b,dataDefs) <- runWriter . lower "start" $ e (b,stringLits) <- runState mempty . lower "start" $ e
let f = wrapFunction @NonEmpty "main" [b] let f = wrapFunction @NonEmpty "main" [b]
pure $ QBE.Program [] (dataDefs ^.. each) [f] dataDefs = lowerStringLiterals stringLits
pure $ QBE.Program [] dataDefs [f]
_ -> do _ -> do
let low e = do let low e = do
bl <- gensym' "b" bl <- gensym' "b"
fl <- gensym' "f" fl <- gensym' "f"
b <- lower bl e b <- lower bl e
pure $ wrapFunction @NonEmpty fl [b] pure $ wrapFunction @NonEmpty fl [b]
(fs,dataDefs) <- runWriter $ traverse low anfs (fs,stringLits) <- runState mempty $ traverse low anfs
pure $ QBE.Program [] (dataDefs ^.. each) (fs ^.. traversed) pure $ QBE.Program [] (lowerStringLiterals stringLits) (fs ^.. traversed)
wrapFunction wrapFunction
:: Foldable1 t :: Foldable1 t

View File

@@ -193,7 +193,7 @@ impl std::hash::Hash for Symbol {
} }
} }
pub fn make_symbol_off_heap (name : scm_bits) -> Symbol { fn make_symbol_off_heap (name : scm_bits) -> Symbol {
Symbol ([ tc7_symbol, name ]) Symbol ([ tc7_symbol, name ])
} }

View File

@@ -1,5 +0,0 @@
use gyehoek::scm::*;
pub fn main () {
}