futhark 0.25.4 → 0.25.5
raw patch · 12 files changed
+124/−71 lines, 12 filesdep ~lspPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependency ranges changed: lsp
API changes (from Hackage documentation)
+ Futhark.Format: parseFormatString :: Text -> Either Text [Either Text Text]
- Futhark.Optimise.CSE: performCSEOnStms :: (AliasableRep rep, CSEInOp (Op (Aliases rep))) => Bool -> Stms rep -> Stms rep
+ Futhark.Optimise.CSE: performCSEOnStms :: (AliasableRep rep, CSEInOp (Op (Aliases rep))) => Stms rep -> Stms rep
Files
- futhark.cabal +3/−2
- rts/c/values.h +3/−3
- src/Futhark/CLI/LSP.hs +3/−1
- src/Futhark/CLI/REPL.hs +49/−11
- src/Futhark/CodeGen/Backends/SimpleRep.hs +3/−20
- src/Futhark/Format.hs +21/−0
- src/Futhark/Internalise/Entry.hs +2/−2
- src/Futhark/Optimise/CSE.hs +15/−18
- src/Futhark/Optimise/InliningDeadFun.hs +1/−1
- src/Futhark/Optimise/Simplify.hs +12/−4
- src/Futhark/Optimise/Simplify/Engine.hs +9/−4
- src/Futhark/Optimise/Simplify/Rules/BasicOp.hs +3/−5
futhark.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: futhark-version: 0.25.4+version: 0.25.5 synopsis: An optimising compiler for a functional, array-oriented language. description: Futhark is a small programming language designed to be compiled to@@ -285,6 +285,7 @@ Futhark.Doc.Generator Futhark.Error Futhark.FreshNames+ Futhark.Format Futhark.IR Futhark.IR.Aliases Futhark.IR.GPU@@ -504,7 +505,7 @@ , haskeline , language-c-quote >= 0.12 , lens- , lsp >= 2.1.0.0+ , lsp >= 2.2.0.0 , lsp-types >= 2.0.1.0 , mainland-pretty >=0.7.1 , cmark-gfm >=0.2.1
rts/c/values.h view
@@ -446,7 +446,7 @@ } else if (isinf(x)) { return fprintf(out, "-f16.inf"); } else {- return fprintf(out, "%.6ff16", x);+ return fprintf(out, "%.*ff16", FLT_DIG, x); } } @@ -459,7 +459,7 @@ } else if (isinf(x)) { return fprintf(out, "-f32.inf"); } else {- return fprintf(out, "%.6ff32", x);+ return fprintf(out, "%.*ff32", FLT_DIG, x); } } @@ -472,7 +472,7 @@ } else if (isinf(x)) { return fprintf(out, "-f64.inf"); } else {- return fprintf(out, "%.6ff64", *src);+ return fprintf(out, "%.*ff64", DBL_DIG, x); } }
src/Futhark/CLI/LSP.hs view
@@ -22,7 +22,9 @@ _ <- runServer $ ServerDefinition- { onConfigurationChange = const $ const $ Right (),+ { onConfigChange = const $ pure (),+ configSection = "Futhark",+ parseConfig = const . const $ Right (), defaultConfig = (), doInitialize = \env _req -> pure $ Right env, staticHandlers = handlers state_mvar,
src/Futhark/CLI/REPL.hs view
@@ -17,8 +17,9 @@ import Data.Text.IO qualified as T import Data.Version import Futhark.Compiler+import Futhark.Format (parseFormatString) import Futhark.MonadFreshNames-import Futhark.Util (fancyTerminal)+import Futhark.Util (fancyTerminal, showText) import Futhark.Util.Options import Futhark.Util.Pretty (AnsiStyle, Color (..), Doc, align, annotate, bgColorDull, bold, brackets, color, docText, docTextForHandle, hardline, italicized, oneLine, pretty, putDoc, putDocLn, unAnnotate, (<+>)) import Futhark.Version@@ -223,7 +224,11 @@ case parseDecOrExp prompt line of Left (SyntaxError _ err) -> liftIO $ T.putStrLn err Right (Left d) -> onDec d- Right (Right e) -> onExp e+ Right (Right e) -> do+ valOrErr <- onExp e+ case valOrErr of+ Left err -> liftIO $ putDoc err+ Right val -> liftIO $ putDocLn $ I.prettyValue val modify $ \s -> s {futharkiCount = futharkiCount s + 1} where inputLine prompt = do@@ -274,22 +279,29 @@ futharkiProg = prog {lpNameSource = src'} } -onExp :: UncheckedExp -> FutharkiM ()+onExp :: UncheckedExp -> FutharkiM (Either (Doc AnsiStyle) I.Value) onExp e = do (imports, src, tenv, ienv) <- getIt case T.checkExp imports src tenv e of- (_, Left err) -> liftIO $ putDoc $ T.prettyTypeErrorNoLoc err+ (_, Left err) -> pure $ Left $ T.prettyTypeErrorNoLoc err (_, Right (tparams, e')) | null tparams -> do r <- runInterpreter $ I.interpretExp ienv e' case r of- Left err -> liftIO $ print err- Right v -> liftIO $ putDoc $ I.prettyValue v <> hardline- | otherwise -> liftIO $ do- putDocLn $ "Inferred type of expression: " <> align (pretty (typeOf e'))- T.putStrLn $- "The following types are ambiguous: "- <> T.intercalate ", " (map (nameToText . toName . typeParamName) tparams)+ Left err -> pure $ Left $ pretty $ showText err+ Right v -> pure $ Right v+ | otherwise ->+ pure $+ Left $+ ("Inferred type of expression: " <> align (pretty (typeOf e')))+ <> hardline+ <> pretty+ ( "The following types are ambiguous: "+ <> T.intercalate+ ", "+ (map (nameToText . toName . typeParamName) tparams)+ )+ <> hardline prettyBreaking :: Breaking -> T.Text prettyBreaking b =@@ -405,6 +417,23 @@ mtypeCommand :: Command mtypeCommand = genTypeCommand parseModExp T.checkModExp $ pretty . fst +formatCommand :: Command+formatCommand input = do+ case parseFormatString input of+ Left err -> liftIO $ T.putStrLn err+ Right parts -> do+ prompt <- getPrompt+ case mapM (traverse $ parseExp prompt) parts of+ Left (SyntaxError _ err) ->+ liftIO $ T.putStr err+ Right parts' -> do+ parts'' <- mapM sequenceA <$> mapM (traverse onExp) parts'+ case parts'' of+ Left err -> liftIO $ putDoc err+ Right parts''' ->+ liftIO . T.putStrLn . mconcat $+ map (either id (docText . I.prettyValue)) parts'''+ unbreakCommand :: Command unbreakCommand _ = do top <- gets $ fmap (NE.head . breakingStack) . futharkiBreaking@@ -483,6 +512,15 @@ second time will replace the previously loaded file. It will also replace any declarations entered at the REPL. +|]+ )+ ),+ ( "format",+ ( formatCommand,+ [text|+Use format strings to print arbitrary futhark expressions. Usage:++ > :format The value of foo: {foo}. The value of 2+2={2+2} |] ) ),
src/Futhark/CodeGen/Backends/SimpleRep.hs view
@@ -36,15 +36,13 @@ ) where -import Data.Bits (shiftR, xor)-import Data.Char (isAlpha, isAlphaNum, isDigit, ord)+import Data.Char (isAlpha, isAlphaNum, isDigit) import Data.Text qualified as T import Futhark.CodeGen.ImpCode import Futhark.CodeGen.RTS.C (scalarF16H, scalarH)-import Futhark.Util (zEncodeText)+import Futhark.Util (hashText, zEncodeText) import Language.C.Quote.C qualified as C import Language.C.Syntax qualified as C-import Text.Printf -- | The C type corresponding to a signed integer type. intTypeToCType :: IntType -> C.Type@@ -137,22 +135,7 @@ && not (isDigit $ T.head s') && T.all ok s' ok c = isAlphaNum c || c == '_'-opaqueName s = "opaque_" <> hash (zipWith xor [0 ..] $ map ord (nameToString s))- where- -- FIXME: a stupid hash algorithm; may have collisions.- hash =- T.pack- . printf "%x"- . foldl xor 0- . map- ( iter- . (* 0x45d9f3b)- . iter- . (* 0x45d9f3b)- . iter- . fromIntegral- )- iter x = ((x :: Word32) `shiftR` 16) `xor` x+opaqueName s = "opaque_" <> hashText (nameToText s) -- | The 'PrimType' (and sign) correspond to a human-readable scalar -- type name (e.g. @f64@). Beware: partial!
+ src/Futhark/Format.hs view
@@ -0,0 +1,21 @@+-- | Parsing of format strings.+module Futhark.Format (parseFormatString) where++import Data.Bifunctor+import Data.Text qualified as T+import Data.Void+import Text.Megaparsec++pFormatString :: Parsec Void T.Text [Either T.Text T.Text]+pFormatString =+ many (choice [Left <$> pLiteral, Right <$> pInterpolation]) <* eof+ where+ pInterpolation = "{" *> takeWhileP Nothing (`notElem` braces) <* "}"+ pLiteral = takeWhile1P Nothing (`notElem` braces)+ braces = "{}" :: String++-- | The Lefts are pure text; the Rights are the contents of+-- interpolations.+parseFormatString :: T.Text -> Either T.Text [Either T.Text T.Text]+parseFormatString =+ first (T.pack . errorBundlePretty) . runParser pFormatString ""
src/Futhark/Internalise/Entry.hs view
@@ -12,7 +12,7 @@ import Data.Map qualified as M import Futhark.IR qualified as I import Futhark.Internalise.TypesValues (internalisedTypeSize)-import Futhark.Util.Pretty (prettyText, prettyTextOneLine)+import Futhark.Util.Pretty (prettyTextOneLine) import Language.Futhark qualified as E hiding (TypeArg) import Language.Futhark.Core (Name, Uniqueness (..), VName, nameFromText) import Language.Futhark.Semantic qualified as E@@ -56,7 +56,7 @@ where f (E.TEArray _ te _) = let (d, te') = withoutDims te- in "arr_" <> typeExpOpaqueName te' <> "_" <> nameFromText (prettyText (1 + d)) <> "d"+ in nameFromText (mconcat (replicate (1 + d) "[]")) <> typeExpOpaqueName te' f te = nameFromText $ prettyTextOneLine te type GenOpaque = State I.OpaqueTypes
src/Futhark/Optimise/CSE.hs view
@@ -71,16 +71,17 @@ . aliasAnalysis $ prog where- onConsts free_in_funs stms =- pure $- fst $- runReader- ( cseInStms- (free_in_funs <> consumedInStms stms)- (stmsToList stms)- (pure ())- )- (newCSEState cse_arrays)+ onConsts free_in_funs stms = do+ let free_list = namesToList free_in_funs+ (res_als, stms_cons) = mkStmsAliases stms $ varsRes free_list+ pure . fst $+ runReader+ ( cseInStms+ (mconcat res_als <> stms_cons)+ (stmsToList stms)+ (pure ())+ )+ (newCSEState cse_arrays) onFun _ = pure . cseInFunDef cse_arrays -- | Perform CSE on a single function.@@ -98,17 +99,11 @@ removeFunDefAliases . cseInFunDef cse_arrays . analyseFun -- | Perform CSE on some statements.------ If the boolean argument is false, the pass will not perform CSE on--- expressions producing arrays. This should be disabled when the rep has--- memory information, since at that point arrays have identity beyond their--- value. performCSEOnStms :: (AliasableRep rep, CSEInOp (Op (Aliases rep))) =>- Bool -> Stms rep -> Stms rep-performCSEOnStms cse_arrays =+performCSEOnStms = fmap removeStmAliases . f . fst . analyseStms mempty where f stms =@@ -119,7 +114,9 @@ (stmsToList stms) (pure ()) )- (newCSEState cse_arrays)+ -- It is never safe to CSE arrays in stms in isolation,+ -- because we might introduce additional aliasing.+ (newCSEState False) cseInFunDef :: (Aliased rep, CSEInOp (Op rep)) =>
src/Futhark/Optimise/InliningDeadFun.hs view
@@ -83,7 +83,7 @@ if any (`calledByConsts` cg) to_inline_now then do consts' <-- simplifyConsts . performCSEOnStms True+ simplifyConsts . performCSEOnStms =<< inlineInStms inlinemap consts pure (ST.insertStms (informStms consts') mempty, consts') else pure (vtable, consts)
src/Futhark/Optimise/Simplify.hs view
@@ -27,6 +27,16 @@ import Futhark.Optimise.Simplify.Rule import Futhark.Pass +funDefUsages :: (FreeIn a) => [a] -> UT.UsageTable+funDefUsages funs =+ -- XXX: treat every constant used in the functions as consumed,+ -- because it is otherwise complicated to ensure we do not introduce+ -- more aliasing than specified by the return types. CSE has the+ -- same problem.+ let free_in_funs = foldMap freeIn funs+ in UT.usages free_in_funs+ <> foldMap UT.consumedUsage (namesToList free_in_funs)+ -- | Simplify the given program. Even if the output differs from the -- output, meaningful simplification may not have taken place - the -- order of bindings may simply have been rearranged.@@ -41,15 +51,13 @@ let consts = progConsts prog funs = progFuns prog (consts_vtable, consts') <-- simplifyConsts (UT.usages $ foldMap freeIn funs) (mempty, informStms consts)+ simplifyConsts (funDefUsages funs) (mempty, informStms consts) -- We deepen the vtable so it will look like the constants are in an -- "outer loop"; this communicates useful information to some -- simplification rules (e.g. see issue #1302). funs' <- parPass (simplifyFun' (ST.deepen consts_vtable) . informFunDef) funs- let funs_uses = UT.usages $ foldMap freeIn funs'-- (_, consts'') <- simplifyConsts funs_uses (mempty, consts')+ (_, consts'') <- simplifyConsts (funDefUsages funs') (mempty, consts') pure $ prog
src/Futhark/Optimise/Simplify/Engine.hs view
@@ -780,11 +780,16 @@ (SimplifiableRep rep) => Stms (Wise rep) -> SimpleM rep (Stms (Wise rep))-simplifyStms stms = do- simplifyStmsWithUsage all_used stms+simplifyStms stms = simplifyStmsWithUsage usage stms where- all_used =- UT.usages (namesFromList (M.keys (scopeOf stms)))+ -- XXX: treat everything as consumed, because when these are+ -- constants it is otherwise complicated to ensure we do not+ -- introduce more aliasing than specified by the return types.+ -- CSE has the same problem.+ all_bound = M.keys (scopeOf stms)+ usage =+ UT.usages (namesFromList all_bound)+ <> foldMap UT.consumedUsage all_bound simplifyStmsWithUsage :: (SimplifiableRep rep) =>
src/Futhark/Optimise/Simplify/Rules/BasicOp.hs view
@@ -239,11 +239,9 @@ ruleBasicOp _ pat _ (Replicate _ se) | [Acc {}] <- patTypes pat = Simplify $ letBind pat $ BasicOp $ SubExp se-ruleBasicOp _ pat _ (Replicate (Shape []) se) = Simplify $ do- se_t <- subExpType se- if primType se_t- then letBind pat $ BasicOp $ SubExp se- else cannotSimplify+ruleBasicOp _ pat _ (Replicate (Shape []) se)+ | [Prim _] <- patTypes pat =+ Simplify $ letBind pat $ BasicOp $ SubExp se ruleBasicOp vtable pat _ (Replicate shape (Var v)) | Just (BasicOp (Replicate shape2 se), cs) <- ST.lookupExp v vtable, ST.subExpAvailable se vtable =