Add variant of splitNormalized for non-representable expressions.
[matthijs/master-project/cλash.git] / cλash / CLasH / Normalize.hs
index 36990dffc5e3cb733c12604765739168001ae934..8e6926aa7c4d4ac59b3f159e690a1bee58ffb634 100644 (file)
@@ -128,6 +128,16 @@ castsimpltop = everywhere ("castsimpl", castsimpl)
 -- transformation ensures that the lambda abstractions always contain a
 -- recursive let and that, when the return value is representable, the
 -- let contains a local variable reference in its body.
+retvalsimpl c expr | all (== LambdaBody) c && not (is_lam expr) && not (is_let expr) = do
+  local_var <- Trans.lift $ is_local_var expr
+  repr <- isRepr expr
+  if not local_var && repr
+    then do
+      id <- Trans.lift $ mkBinderFor expr "res" 
+      change $ Let (Rec [(id, expr)]) (Var id)
+    else
+      return expr
+
 retvalsimpl c expr@(Let (Rec binds) body) | all (== LambdaBody) c = do
   -- Don't extract values that are already a local variable, to prevent
   -- loops with ourselves.
@@ -142,15 +152,6 @@ retvalsimpl c expr@(Let (Rec binds) body) | all (== LambdaBody) c = do
     else
       return expr
 
-retvalsimpl c expr | all (== LambdaBody) c && not (is_lam expr) && not (is_let expr) = do
-  local_var <- Trans.lift $ is_local_var expr
-  repr <- isRepr expr
-  if not local_var && repr
-    then do
-      id <- Trans.lift $ mkBinderFor expr "res" 
-      change $ Let (Rec [(id, expr)]) (Var id)
-    else
-      return expr
 
 -- Leave all other expressions unchanged
 retvalsimpl c expr = return expr
@@ -851,14 +852,21 @@ normalizeExpr what expr = do
        return expr'
 
 -- | Split a normalized expression into the argument binders, top level
---   bindings and the result binder.
+--   bindings and the result binder. This function returns an error if
+--   the type of the expression is not representable.
 splitNormalized ::
   CoreExpr -- ^ The normalized expression
   -> ([CoreBndr], [Binding], CoreBndr)
-splitNormalized expr = (args, binds, res)
+splitNormalized expr = 
+  case splitNormalizedNonRep expr of
+    (args, binds, Var res) -> (args, binds, res)
+    _ -> error $ "Normalize.splitNormalized: Not in normal form: " ++ pprString expr ++ "\n"
+
+-- Split a normalized expression, whose type can be unrepresentable.
+splitNormalizedNonRep::
+  CoreExpr -- ^ The normalized expression
+  -> ([CoreBndr], [Binding], CoreExpr)
+splitNormalizedNonRep expr = (args, binds, resexpr)
   where
     (args, letexpr) = CoreSyn.collectBinders expr
     (binds, resexpr) = flattenLets letexpr
-    res = case resexpr of 
-      (Var x) -> x
-      _ -> error $ "Normalize.splitNormalized: Not in normal form: " ++ pprString expr ++ "\n"