(Var f, args) -> return $ Just body
-- Body is more complicated, try normalizing it
_ -> do
- norm_maybe <- Trans.lift $ getNormalized_maybe f
+ norm_maybe <- Trans.lift $ getNormalized_maybe False f
case norm_maybe of
-- Noth normalizeable
Nothing -> return Nothing
-- | Returns the normalized version of the given function, or an error
-- if it is not a known global binder.
getNormalized ::
- CoreBndr -- ^ The function to get
+ Bool -- ^ Allow the result to be unrepresentable?
+ -> CoreBndr -- ^ The function to get
-> TranslatorSession CoreExpr -- The normalized function body
-getNormalized bndr = do
- norm <- getNormalized_maybe bndr
+getNormalized result_nonrep bndr = do
+ norm <- getNormalized_maybe result_nonrep bndr
return $ Maybe.fromMaybe
(error $ "Normalize.getNormalized: Unknown or non-representable function requested: " ++ show bndr)
norm
-- | Returns the normalized version of the given function, or Nothing
-- when the binder is not a known global binder or is not normalizeable.
getNormalized_maybe ::
- CoreBndr -- ^ The function to get
+ Bool -- ^ Allow the result to be unrepresentable?
+ -> CoreBndr -- ^ The function to get
-> TranslatorSession (Maybe CoreExpr) -- The normalized function body
-getNormalized_maybe bndr = do
+getNormalized_maybe result_nonrep bndr = do
expr_maybe <- getGlobalBind bndr
- normalizeable <- isNormalizeable' bndr
+ normalizeable <- isNormalizeable result_nonrep bndr
if not normalizeable || Maybe.isNothing expr_maybe
then
-- Binder not normalizeable or not found
return Nothing
- else if is_poly (Var bndr)
- then
- -- This should really only happen at the top level... TODO: Give
- -- a different error if this happens down in the recursion.
- error $ "\nNormalize.normalizeBind: Function " ++ show bndr ++ " is polymorphic, can't normalize"
- else do
- -- Binder found and is monomorphic. Normalize the expression
- -- and cache the result.
- normalized <- Utils.makeCached bndr tsNormalized $
- normalizeExpr (show bndr) (Maybe.fromJust expr_maybe)
- return (Just normalized)
+ else do
+ -- Binder found and is monomorphic. Normalize the expression
+ -- and cache the result.
+ normalized <- Utils.makeCached bndr tsNormalized $
+ normalizeExpr (show bndr) (Maybe.fromJust expr_maybe)
+ return (Just normalized)
-- | Normalize an expression
normalizeExpr ::
where
str = Name.getOccString bndr
--- Is the given binder normalizable? This means that its type signature can be
+-- | Is the given binder normalizable? This means that its type signature can be
-- represented in hardware, which should (?) guarantee that it can be made
--- into hardware. Note that if a binder is not normalizable, it might become
--- so using argument propagation.
-isNormalizeable :: CoreBndr -> TransformMonad Bool
-isNormalizeable bndr = Trans.lift (isNormalizeable' bndr)
-
-isNormalizeable' :: CoreBndr -> TranslatorSession Bool
-isNormalizeable' bndr = do
+-- into hardware. This checks whether all the arguments and (optionally)
+-- the return value are
+-- representable.
+isNormalizeable ::
+ Bool -- ^ Allow the result to be unrepresentable?
+ -> CoreBndr -- ^ The binder to check
+ -> TranslatorSession Bool -- ^ Is it normalizeable?
+isNormalizeable result_nonrep bndr = do
let ty = Id.idType bndr
let (arg_tys, res_ty) = Type.splitFunTys ty
- -- This function is normalizable if all its arguments and return value are
- -- representable.
- andM $ mapM isRepr' (res_ty:arg_tys)
+ let check_tys = if result_nonrep then arg_tys else (res_ty:arg_tys)
+ andM $ mapM isRepr' check_tys
-> TranslatorSession Entity -- ^ The resulting entity
getEntity fname = makeCached fname tsEntities $ do
- expr <- Normalize.getNormalized fname
+ expr <- Normalize.getNormalized False fname
-- Split the normalized expression
let (args, binds, res) = Normalize.splitNormalized expr
-- Generate ports for all non-empty types
-- ^ The architecture for this function
getArchitecture fname = makeCached fname tsArchitectures $ do
- expr <- Normalize.getNormalized fname
+ expr <- Normalize.getNormalized False fname
-- Split the normalized expression
let (args, binds, res) = Normalize.splitNormalized expr