Skip to content

Commit 18ea55d

Browse files
committed
Add an inlining pass.
1 parent 544ecc7 commit 18ea55d

22 files changed

+825
-190
lines changed

feldspar-compiler.cabal

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,12 @@ library
4141
Feldspar.Compiler
4242
Feldspar.Compiler.Imperative.ArrayOps
4343
Feldspar.Compiler.Imperative.Representation
44+
Feldspar.Compiler.Imperative.DeadFunElim
4445
Feldspar.Compiler.Imperative.ExternalProgram
4546
Feldspar.Compiler.Imperative.FromCore
4647
Feldspar.Compiler.Imperative.FromCore.Interpretation
4748
Feldspar.Compiler.Imperative.Frontend
49+
Feldspar.Compiler.Imperative.Inline
4850
Feldspar.Compiler.Backend.C.CodeGeneration
4951
Feldspar.Compiler.Backend.C.Library
5052
Feldspar.Compiler.Backend.C.MachineLowering

src/Feldspar/Compiler.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ module Feldspar.Compiler
1919
, Target(..)
2020
, c99PlatformOptions
2121
, c99OpenMpPlatformOptions
22+
, c99InlineOptions
2223
, tic64xPlatformOptions
2324
, feldsparCIncludes
2425
) where

src/Feldspar/Compiler/Backend/C/Options.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ data Platform = Platform {
5656
values :: [(Type, ShowValue)],
5757
includes :: [String],
5858
varFloating :: Bool,
59+
pInline :: Bool,
5960
codeGenerator :: String
6061
} deriving (Show)
6162

src/Feldspar/Compiler/Backend/C/Platforms.hs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ module Feldspar.Compiler.Backend.C.Platforms
3434
, c99
3535
, c99OpenMp
3636
, c99Wool
37+
, c99Inline
3738
, tic64x
3839
, extend
3940
) where
@@ -45,7 +46,7 @@ import Feldspar.Compiler.Imperative.Representation
4546
import Feldspar.Compiler.Imperative.Frontend
4647

4748
availablePlatforms :: [Platform]
48-
availablePlatforms = [ c99, c99OpenMp, c99Wool, ba, tic64x ]
49+
availablePlatforms = [ c99, c99OpenMp, c99Wool, c99Inline, ba, tic64x ]
4950

5051
platformFromName :: String -> Platform
5152
platformFromName str = head $ [pf | pf <- availablePlatforms, name pf == str]
@@ -86,6 +87,7 @@ c99 = Platform {
8687
, "<stdbool.h>"
8788
, "<complex.h>"],
8889
varFloating = True,
90+
pInline = False,
8991
codeGenerator = "c"
9092
}
9193

@@ -100,8 +102,14 @@ c99Wool = c99 { name = "c99Wool"
100102
, varFloating = False
101103
}
102104

105+
c99Inline :: Platform
106+
c99Inline = c99 { name = "c99i"
107+
, pInline = True
108+
}
109+
103110
ba :: Platform
104111
ba = c99 { name = "ba"
112+
, pInline = True
105113
, codeGenerator = "ba"
106114
}
107115

@@ -133,6 +141,7 @@ tic64x = Platform {
133141
includes = [ "feldspar_tic64x.h", "feldspar_array.h", "<c6x.h>", "<string.h>"
134142
, "<math.h>"],
135143
varFloating = True,
144+
pInline = False,
136145
codeGenerator = "c"
137146
}
138147

src/Feldspar/Compiler/Compiler.hs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ module Feldspar.Compiler.Compiler (
4343
, sicsOptions3
4444
, c99PlatformOptions
4545
, c99OpenMpPlatformOptions
46+
, c99InlineOptions
4647
, tic64xPlatformOptions
4748
, SplitModule(..)
4849
, CompiledModule(..)
@@ -64,6 +65,7 @@ import Feldspar.Compiler.Backend.C.MachineLowering
6465
import Feldspar.Compiler.Backend.C.Tic64x
6566
import Feldspar.Compiler.Imperative.FromCore
6667
import Feldspar.Compiler.Imperative.ArrayOps
68+
import Feldspar.Compiler.Imperative.Inline
6769
import Feldspar.Compiler.Imperative.Representation
6870
import Feldspar.Core.Middleend.PassManager
6971
import Control.Monad (when)
@@ -121,7 +123,7 @@ compileToCCore name opts prg = compileToCCore' opts mod
121123
compileToCCore' :: Options -> Module () -> SplitModule
122124
compileToCCore' opts m = compileSplitModule opts $ splitModule mod
123125
where
124-
mod = adaptTic64x opts $ rename opts False $ arrayOps opts m
126+
mod = adaptTic64x opts $ rename opts False $inline opts $ arrayOps opts m
125127

126128
genIncludeLines :: Options -> Maybe String -> String
127129
genIncludeLines opts mainHeader = concatMap include incs ++ "\n\n"
@@ -151,6 +153,9 @@ c99PlatformOptions = defaultOptions
151153
c99OpenMpPlatformOptions :: Options
152154
c99OpenMpPlatformOptions = defaultOptions { platform = c99OpenMp }
153155

156+
c99InlineOptions :: Options
157+
c99InlineOptions = defaultOptions { platform = c99Inline }
158+
154159
tic64xPlatformOptions :: Options
155160
tic64xPlatformOptions = defaultOptions { platform = tic64x }
156161

@@ -165,6 +170,7 @@ sicsOptions3 = defaultOptions { platform = c99Wool, frontendOpts = defaultFeldOp
165170

166171
data BackendPass = BPFromCore
167172
| BPArrayOps
173+
| BPInline
168174
| BPRename
169175
| BPAdapt
170176
| BPSplit
@@ -189,6 +195,7 @@ backend :: PassCtrl BackendPass -> Options -> String -> UntypedFeld -> ([String]
189195
backend ctrl opts name = evalPasses 0
190196
$ codegen (codeGenerator $ platform opts) ctrl opts
191197
. pc BPRename (rename opts False)
198+
. pc BPInline (inline opts)
192199
. pc BPArrayOps (arrayOps opts)
193200
. pt BPFromCore (fst . fromCoreUT opts (encodeFunctionName name))
194201
where pc :: Pretty a => BackendPass -> (a -> a) -> Prog a Int -> Prog a Int

src/Feldspar/Compiler/Frontend/Interactive/Interface.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ defaultProgOpts =
134134
targetsFromPlatform :: Platform -> [Target]
135135
targetsFromPlatform pf = tfp $ name pf
136136
where tfp "c99" = []
137+
tfp "c99i" = []
137138
tfp "c99OpenMp" = []
138139
tfp "c99Wool" = [Wool]
139140
tfp "ba" = [BA]

src/Feldspar/Compiler/Imperative/ArrayOps.hs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,22 +34,32 @@ module Feldspar.Compiler.Imperative.ArrayOps (arrayOps) where
3434
import Feldspar.Compiler.Imperative.Representation
3535
import Feldspar.Compiler.Imperative.Frontend
3636
(litI32, deepCopy, fun, call, for, toBlock, mkIf, isShallow, variant, arrayFun, freeArrayE,
37-
lowerCopy, mkSequence, elemTyAwL, isAwLType)
37+
lowerCopy, mkSequence, elemTyAwL, isAwLType, encodeType)
3838
import Feldspar.Range (fullRange)
3939
import Feldspar.Core.Types(Length)
4040
import Feldspar.Compiler.Backend.C.Options(Options)
4141

42-
import Data.List (nub, isPrefixOf, concatMap)
42+
import Data.List (nub, isPrefixOf, concatMap, sortBy)
4343
import Control.Monad.Writer(Writer(..), runWriter, tell, censor)
44+
import Data.Bifunctor(bimap)
4445

4546
-- | Main interface for adding needed array operations to a module.
4647
arrayOps :: Options -> Module () -> Module ()
47-
arrayOps opts (Module ents) = Module $ concatMap mkArrayOps dts ++ ents'
48+
arrayOps opts (Module ents) = Module $ concatMap mkArrayOps sdts ++ ents'
4849
where dts = filter (not . either isShallow isShallow) lrts
50+
sdts = map (bimap snd snd) $ sortBy compFst $ map (bimap rank rank) dts
4951
(ents',lrts) = lower opts ents
5052
mkArrayOps (Left t) = [mkInitArray opts t, mkFreeArray opts t]
5153
mkArrayOps (Right t) = [mkCopyArrayPos opts t, mkCopyArray opts t, mkInitCopyArray opts t]
5254

55+
-- | Annotate a type with a measure of the size of the type
56+
rank :: Type -> (Int, Type)
57+
rank t = (length $ encodeType t, t)
58+
59+
-- | Compare two pairs only on their first components
60+
compFst :: Ord a => Either (a,b) (a,b) -> Either (a,c) (a,c) -> Ordering
61+
compFst x y = compare (bimap fst fst x) (bimap fst fst y)
62+
5363
-- | Copying an array to a given position in the destination
5464
mkCopyArrayPos :: Options -> Type -> Entity ()
5565
mkCopyArrayPos opts t = Proc name False [dstVar, dstLVar, srcVar, srcLVar, posVar] (typeof dstVar) (Just body)
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
module Feldspar.Compiler.Imperative.DeadFunElim (deadFunElim) where
2+
3+
import Feldspar.Compiler.Imperative.Representation
4+
import Feldspar.Compiler.Backend.C.Options(Options(..), Platform(..))
5+
6+
import qualified Data.Set as S
7+
8+
type NameSet = S.Set String
9+
10+
deadFunElim :: Options -> Module () -> Module ()
11+
deadFunElim opts (Module ents) = Module $ snd $ foldr (dfeEnt opts) (S.empty, []) ents
12+
13+
dfeEnt :: Options -> Entity () -> (NameSet, [Entity ()]) -> (NameSet, [Entity ()])
14+
dfeEnt opts ent@Proc{procName = name, procBody = body} (names, ents)
15+
| not $ S.member name names || null ents = (names, ents)
16+
| otherwise = (maybeNames blockNames body `S.union` S.delete name names, ent : ents)
17+
dfeEnt opts ent (names, ents) = (names, ent : ents)
18+
19+
blockNames :: Block () -> NameSet
20+
blockNames (Block ds p) = S.unions $ progNames p : map declNames ds
21+
where declNames d = maybeNames exprNames $ initVal d
22+
23+
progNames :: Program () -> NameSet
24+
progNames = go
25+
where go (Assign lhs rhs) = goE lhs `S.union` goE rhs
26+
go (ProcedureCall p aps) = S.unions $ S.singleton p : map goA aps
27+
go (Sequence ps) = S.unions $ map go ps
28+
go (Switch e alts) = S.unions $ goE e : map (goB . snd) alts
29+
go (SeqLoop c cc b) = goE c `S.union` goB cc `S.union` goB b
30+
go (ParLoop _ _ s e i b) = S.unions [goE s, goE e, goE i, goB b]
31+
go (BlockProgram b) = goB b
32+
go _ = S.empty
33+
34+
goE = exprNames
35+
goB = blockNames
36+
goA (ValueParameter e) = goE e
37+
goA (FunParameter name) = S.singleton name
38+
goA _ = S.empty
39+
40+
exprNames :: Expression () -> NameSet
41+
exprNames = go
42+
where go (ArrayElem arr ixs) = S.unions $ go arr : map go ixs
43+
go (StructField e _) = go e
44+
go (FunctionCall f es) = S.unions $ goF f : map go es
45+
go (Cast _ e) = go e
46+
go (AddrOf e) = go e
47+
go (Deref e) = go e
48+
go _ = S.empty
49+
50+
goF (Function name _) = S.singleton name
51+
52+
maybeNames :: (a -> NameSet) -> Maybe a -> NameSet
53+
maybeNames f m = maybe S.empty f m

0 commit comments

Comments
 (0)