From d88787027d4a1c0e54a62083fca4c8b38b9f13aa Mon Sep 17 00:00:00 2001 From: Ilya Rezvov Date: Wed, 23 May 2018 15:03:03 -0700 Subject: [PATCH] store only unique constants --- rts/index.html | 184 +++++++++++++++++++++++++++++++++++----- src/IRTS/CodegenWasm.hs | 73 +++++++++++++--- 2 files changed, 228 insertions(+), 29 deletions(-) diff --git a/rts/index.html b/rts/index.html index 231cc5d..aa0b4cf 100644 --- a/rts/index.html +++ b/rts/index.html @@ -1,5 +1,6 @@ \ No newline at end of file diff --git a/src/IRTS/CodegenWasm.hs b/src/IRTS/CodegenWasm.hs index 2385b78..eb0779a 100644 --- a/src/IRTS/CodegenWasm.hs +++ b/src/IRTS/CodegenWasm.hs @@ -45,7 +45,6 @@ mkWasm defs stackSize heapSize = raiseError <- importFunction "rts" "raiseError" (FuncType [I32] []) strEq <- importFunction "rts" "strEq" (FuncType [I32, I32] [I32]) strHead <- importFunction "rts" "strHead" (FuncType [I32] [I32]) - strConcat <- importFunction "rts" "strConcat" (FuncType [I32, I32] [I32]) strWrite <- importFunction "rts" "strWrite" (FuncType [I32] [I32]) intStr <- importFunction "rts" "intStr" (FuncType [I32] [I32]) exportMemory "mem" =<< memory 20 Nothing @@ -120,6 +119,28 @@ mkWasm defs stackSize heapSize = (const $ for (i .= stackTop) (i `lt_u` newStackTop) (i .= (i `add` i32c 4)) $ const $ do store i (i32c 0) 0 2 ) + memcpy <- fun $ do + dst <- param i32 + src <- param i32 + len <- param i32 + i <- local i32 + for (i .= i32c 0) (i `lt_u` len) (i .= (i `add` i32c 1)) $ const $ do + store8 (dst `add` i) (load8u i32 (src `add` i) 0 0) 0 0 + strConcat <- fun $ do + a <- param i32 + b <- param i32 + result i32 + aSize <- local i32 + bSize <- local i32 + addr <- local i32 + aSize .= load i32 a 4 2 + bSize .= load i32 b 4 2 + addr .= call i32 alloc [aSize `add` bSize `sub` i32c 12] + store8 addr (i32c $ fromEnum String) 0 0 + store addr (load i32 a 8 2 `add` load i32 b 8 2) 8 2 + invoke memcpy [arg (addr `add` i32c 12), arg (a `add` i32c 12), arg (aSize `sub` i32c 12)] + invoke memcpy [arg (addr `add` aSize), arg (b `add` i32c 12), arg (bSize `sub` i32c 12)] + ret addr defsStartFrom <- nextFuncIndex let bindings = GB { stackStartIdx = stackStart, @@ -158,11 +179,14 @@ mkWasm defs stackSize heapSize = data GenState = GS { constSectionEnd :: Word32, constSection :: BSBuilder.Builder, - strCache :: Map.Map String Word32 + strCache :: Map.Map String Word32, + intCache :: Map.Map Int Word32, + bigCache :: Map.Map Integer Word32, + doubleCache :: Map.Map Double Word32 } emptyState :: GenState -emptyState = GS 0 mempty mempty +emptyState = GS 0 mempty mempty mempty mempty mempty data GlobalBindings = GB { stackBaseIdx :: Glob I32, @@ -576,23 +600,51 @@ asAddr expr = do return $ i32c addr makeConst :: Const -> WasmGen (GenFun (Proxy I32)) -makeConst (I i) = asAddr $ addToConstSection (mkInt i) -makeConst (BI i) = asAddr $ addToConstSection (mkBigInt i) -makeConst (Fl f) = asAddr $ addToConstSection (mkFloat f) -makeConst (Ch c) = asAddr $ addToConstSection (mkInt $ Char.ord c) +makeConst (I i) = makeIntConst i +makeConst (BI i) = do + cache <- gets bigCache + case Map.lookup i cache of + Just addr -> return $ i32c addr + Nothing -> do + addr <- addToConstSection (mkBigInt i) + modify $ \st -> st { bigCache = Map.insert i addr cache } + return $ i32c addr +makeConst (Fl f) = do + cache <- gets doubleCache + case Map.lookup f cache of + Just addr -> return $ i32c addr + Nothing -> do + addr <- addToConstSection (mkFloat f) + modify $ \st -> st { doubleCache = Map.insert f addr cache } + return $ i32c addr +makeConst (Ch c) = makeIntConst $ Char.ord c makeConst (Str s) = do cache <- gets strCache case Map.lookup s cache of Just addr -> return $ i32c addr - Nothing -> asAddr $ addToConstSection (mkStr s) -makeConst (B8 w) = asAddr $ addToConstSection (mkInt w) -makeConst (B16 w) = asAddr $ addToConstSection (mkInt w) + Nothing -> do + addr <- addToConstSection (mkStr s) + modify $ \st -> st { strCache = Map.insert s addr cache } + return $ i32c addr +makeConst (B8 w) = makeIntConst w +makeConst (B16 w) = makeIntConst w makeConst (B32 w) = asAddr $ addToConstSection (mkBit32 w) makeConst (B64 w) = asAddr $ addToConstSection (mkBit64 w) makeConst c | isTypeConst c = asAddr $ addToConstSection (mkInt 42424242) | otherwise = error $ "mkConst of (" ++ show c ++ ") not implemented" +makeIntConst :: (Integral i) => i -> WasmGen (GenFun (Proxy I32)) +makeIntConst val = do + let i = fromIntegral val + cache <- gets intCache + case Map.lookup i cache of + Just addr -> return $ i32c addr + Nothing -> do + addr <- addToConstSection (mkInt i) + modify $ \st -> st { intCache = Map.insert i addr cache } + return $ i32c addr + aligned :: (Integral i) => i -> Word32 aligned sz = (fromIntegral sz + 3) .&. 0xFFFFFFFC @@ -701,6 +753,7 @@ instance Serialize.Serialize StrVal where put SV { hdr, len, val } = do Serialize.put hdr Serialize.putWord32le len + Serialize.putLazyByteString val get = do hdr <- Serialize.get len <- Serialize.getWord32le