summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Smeding <tom@tomsmeding.com>2025-03-21 22:45:46 +0100
committerTom Smeding <tom@tomsmeding.com>2025-03-21 22:45:46 +0100
commitf87bcb545ce7aae62a1121665a7050154858c75d (patch)
tree1bd3f7afa223670cb2829577fe152252a9946c09
parentd62a195efdc63829175915530ace9c4c3927fdb9 (diff)
Compile: Decrement array elements when freeing array
-rw-r--r--src/Compile.hs19
1 files changed, 15 insertions, 4 deletions
diff --git a/src/Compile.hs b/src/Compile.hs
index cb8b424..b9dbd41 100644
--- a/src/Compile.hs
+++ b/src/Compile.hs
@@ -860,7 +860,7 @@ incrementVar inc ty =
incrementVarAlways :: Increment -> STy a -> String -> CompM ()
incrementVarAlways inc ty var = maybe (pure ()) ($ var) (incrementVar inc ty)
-data ArrayTree = ATArray -- ^ we've arrived at an array we need to decrement the refcount of
+data ArrayTree = ATArray (Some SNat) (Some STy) -- ^ we've arrived at an array we need to decrement the refcount of (contains rank and element type of the array)
| ATNoop -- ^ don't do anything here
| ATProj String ArrayTree -- ^ descend one field deeper
| ATCondTag ArrayTree ArrayTree -- ^ if tag is 0, first; if 1, second
@@ -886,16 +886,27 @@ makeArrayTree (STPair a b) = smartATBoth (smartATProj "a" (makeArrayTree a))
makeArrayTree (STEither a b) = smartATCondTag (smartATProj "l" (makeArrayTree a))
(smartATProj "r" (makeArrayTree b))
makeArrayTree (STMaybe t) = smartATCondTag ATNoop (makeArrayTree t)
-makeArrayTree (STArr _ _) = ATArray
+makeArrayTree (STArr n t) = ATArray (Some n) (Some t)
makeArrayTree (STScal _) = ATNoop
makeArrayTree (STAccum _) = ATNoop
incrementVar' :: Increment -> String -> ArrayTree -> CompM ()
-incrementVar' inc path ATArray =
+incrementVar' inc path (ATArray (Some n) (Some eltty)) =
case inc of
Increment -> emit $ SVerbatim (path ++ ".buf->refc++;")
Decrement ->
- emit $ SVerbatim $ "if (--" ++ path ++ ".buf->refc == 0) free(" ++ path ++ ".buf);"
+ case incrementVar Decrement eltty of
+ Nothing -> emit $ SVerbatim $ "if (--" ++ path ++ ".buf->refc == 0) free(" ++ path ++ ".buf);"
+ Just f -> do
+ shszvar <- genName' "frshsz"
+ ivar <- genName' "i"
+ ((), eltDecrStmts) <- scope $ f (path ++ ".buf->xs[" ++ ivar ++ "]")
+ emit $ SIf (CELit ("--" ++ path ++ ".buf->refc == 0"))
+ (BList [SVarDecl True "size_t" shszvar (compileArrShapeSize n path)
+ ,SLoop "size_t" ivar (CELit "0") (CELit shszvar) $
+ BList eltDecrStmts
+ ,SVerbatim $ "free(" ++ path ++ ".buf);"])
+ mempty
incrementVar' _ _ ATNoop = pure ()
incrementVar' inc path (ATProj field t) = incrementVar' inc (path ++ "." ++ field) t
incrementVar' inc path (ATCondTag t1 t2) = do