Skip to content

Commit 8298e3f

Browse files
committed
Merge remote-tracking branch 'origin/master' into migrate-travis-ci
Conflicts: .travis.yml
2 parents 5a53b37 + 919b948 commit 8298e3f

File tree

11 files changed

+174
-217
lines changed

11 files changed

+174
-217
lines changed

.travis.yml

Lines changed: 13 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,18 @@
11
sudo: false
22

3-
matrix:
4-
include:
5-
- env: GHC_VERSION=7.10.1
6-
addons:
7-
apt:
8-
sources:
9-
- hvr-ghc
10-
packages:
11-
- ghc-7.10.1
12-
- cabal-install-1.22
13-
- happy
14-
- alex
15-
before_install:
16-
- export PATH=/opt/ghc/7.10.1/bin:/opt/cabal/1.22/bin:$PATH
17-
- env: GHC_VERSION=7.8.3
18-
addons:
19-
apt:
20-
sources:
21-
- hvr-ghc
22-
packages:
23-
- ghc-7.8.3
24-
- cabal-install-1.18
25-
- happy-1.19.4
26-
- alex-3.1.3
27-
before_install:
28-
- export PATH=/opt/ghc/7.8.3/bin:/opt/cabal/1.18/bin:$PATH
29-
- export PATH=/opt/alex/3.1.3/bin:/opt/happy/1.19.4/bin:$PATH
30-
- env: GHC_VERSION=7.6.3
31-
addons:
32-
apt:
33-
sources:
34-
- hvr-ghc
35-
packages:
36-
- ghc-7.6.3
37-
- cabal-install-1.18
38-
- happy-1.19.4
39-
- alex-3.1.3
40-
before_install:
41-
- export PATH=/opt/ghc/7.6.3/bin:/opt/cabal/1.18/bin:$PATH
42-
- export PATH=/opt/alex/3.1.3/bin:/opt/happy/1.19.4/bin:$PATH
3+
addons:
4+
apt:
5+
sources:
6+
- hvr-ghc
7+
packages:
8+
- ghc-7.10.1
9+
- cabal-install-1.22
10+
- happy
11+
- alex
12+
13+
14+
before_install:
15+
- export PATH=/opt/ghc/7.10.1/bin:/opt/cabal/1.22/bin:$PATH
4316

4417

4518
install:

src/AST/Expression/General.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ data PortImpl expr tipe
6767
= In String (Type.Port tipe)
6868
| Out String expr (Type.Port tipe)
6969
| Task String expr (Type.Port tipe)
70-
deriving (Show)
70+
deriving (Eq, Show)
7171

7272

7373
portName :: PortImpl expr tipe -> String

src/AST/Expression/Optimized.hs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@ import qualified Reporting.Region as R
1919
data Def
2020
= Def Facts String Expr
2121
| TailDef Facts String [String] Expr
22+
deriving (Eq)
2223

2324

2425
data Facts = Facts
2526
{ home :: Maybe ModuleName.Canonical
2627
, dependencies :: [Var.TopLevel]
2728
}
29+
deriving (Eq)
2830

2931

3032
dummyFacts :: Facts
@@ -54,14 +56,17 @@ data Expr
5456
| Port (General.PortImpl Expr Type.Canonical)
5557
| GLShader String String Literal.GLShaderTipe
5658
| Crash R.Region (Maybe String)
59+
deriving (Eq)
5760

5861

5962
data Jump
6063
= Inline Branch
6164
| Jump Int
65+
deriving (Eq)
6266

6367

6468
data Branch = Branch
6569
{ _substitutions :: [(String, DT.Path)]
6670
, _branch :: Expr
67-
}
71+
}
72+
deriving (Eq)

src/AST/Literal.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ data GLTipe
3939
| V4
4040
| M4
4141
| Texture
42-
deriving (Show)
42+
deriving (Eq, Show)
4343

4444

4545
glTipeName :: GLTipe -> String
@@ -59,4 +59,4 @@ data GLShaderTipe = GLShaderTipe
5959
, uniform :: Map.Map String GLTipe
6060
, varying :: Map.Map String GLTipe
6161
}
62-
deriving (Show)
62+
deriving (Eq, Show)

src/AST/Type.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ data Aliased t
5656
data Port t
5757
= Normal t
5858
| Signal { root :: t, arg :: t }
59-
deriving (Show)
59+
deriving (Eq, Show)
6060

6161

6262
getPortType :: Port tipe -> tipe

src/Generate/JavaScript.hs

Lines changed: 48 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -371,28 +371,59 @@ generateDecisionTree root decisionTree =
371371
DT.Match (Opt.Jump target) ->
372372
return [ BreakStmt () (Just (targetLabel root target)) ]
373373

374-
DT.Decision testPath edges fallback ->
375-
do accessExpr <- generateJsExpr (pathToExpr root testPath)
376-
377-
let testExpr =
378-
case fst (head edges) of
379-
DT.Constructor _ ->
380-
DotRef () accessExpr (Id () "ctor")
381-
382-
DT.Literal _ ->
383-
accessExpr
374+
DT.Decision testPath [(test, subTree)] (Just fallback) ->
375+
let
376+
(tests, deepestSubTree) =
377+
collapseTests [(testPath, test)] fallback subTree
378+
379+
makeTest (path, test) =
380+
do testExpr <- pathToTestableExpr root path test
381+
return (InfixExpr () OpStrictEq testExpr (testToExpr test))
382+
in
383+
do testExprs <- mapM makeTest tests
384+
let cond = List.foldl1' (InfixExpr () OpLAnd) testExprs
385+
thenBranch <- generateDecisionTree root deepestSubTree
386+
elseBranch <- generateDecisionTree root fallback
387+
return [ IfStmt () cond (BlockStmt () thenBranch) (BlockStmt () elseBranch) ]
384388

389+
DT.Decision testPath edges fallback ->
390+
do testExpr <- pathToTestableExpr root testPath (fst (head edges))
385391
caseClauses <- mapM (edgeToCaseClause root) edges
386392
caseDefault <- fallbackToDefault root fallback
387-
388393
return [ SwitchStmt () testExpr (caseClauses ++ caseDefault) ]
389394

390395

396+
collapseTests
397+
:: [(DT.Path, DT.Test)]
398+
-> DT.DecisionTree Opt.Jump
399+
-> DT.DecisionTree Opt.Jump
400+
-> ([(DT.Path, DT.Test)], DT.DecisionTree Opt.Jump)
401+
collapseTests tests outerFallback decisionTree =
402+
case decisionTree of
403+
DT.Decision testPath [(test, subTree)] (Just fallback)
404+
| fallback == outerFallback ->
405+
collapseTests ((testPath, test) : tests) outerFallback subTree
406+
407+
_ ->
408+
(tests, decisionTree)
409+
410+
391411
edgeToCaseClause :: String -> (DT.Test, DT.DecisionTree Opt.Jump) -> State Int (CaseClause ())
392412
edgeToCaseClause root (test, subTree) =
393413
CaseClause () (testToExpr test) <$> generateDecisionTree root subTree
394414

395415

416+
pathToTestableExpr :: String -> DT.Path -> DT.Test -> State Int (Expression ())
417+
pathToTestableExpr root path exampleTest =
418+
do accessExpr <- generateJsExpr (pathToExpr root path)
419+
case exampleTest of
420+
DT.Constructor _ ->
421+
return (DotRef () accessExpr (Id () "ctor"))
422+
423+
DT.Literal _ ->
424+
return accessExpr
425+
426+
396427
testToExpr :: DT.Test -> Expression ()
397428
testToExpr test =
398429
case test of
@@ -419,15 +450,17 @@ fallbackToDefault root fallback =
419450

420451
generateBranch :: String -> Opt.Branch -> State Int [Statement ()]
421452
generateBranch root (Opt.Branch substitutions expr) =
422-
do subts <- mapM (loadPath root) substitutions
453+
do substs <- mapM (loadPath root) substitutions
454+
let substStmts =
455+
if null substs then [] else [ VarDeclStmt () substs ]
423456
code <- generateCode expr
424-
return (subts ++ toStatementList code)
457+
return (substStmts ++ toStatementList code)
425458

426459

427-
loadPath :: String -> (String, DT.Path) -> State Int (Statement ())
460+
loadPath :: String -> (String, DT.Path) -> State Int (VarDecl ())
428461
loadPath root (name, path) =
429462
do jsAccessExpr <- generateJsExpr (pathToExpr root path)
430-
return $ VarDeclStmt () [ varDecl name jsAccessExpr ]
463+
return $ varDecl (Var.safe name) jsAccessExpr
431464

432465

433466
pathToExpr :: String -> DT.Path -> Opt.Expr

src/Optimize/Patterns/DecisionTree.hs

Lines changed: 75 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ as SML/NJ to get nice trees.
1212
-}
1313

1414
import Control.Arrow (second)
15-
import Data.Function (on)
1615
import qualified Data.List as List
1716
import qualified Data.Map as Map
1817
import qualified Data.Set as Set
@@ -74,6 +73,7 @@ data DecisionTree a
7473
, _edges :: [(Test, DecisionTree a)]
7574
, _default :: Maybe (DecisionTree a)
7675
}
76+
deriving (Eq)
7777

7878

7979
data Jump = Jump
@@ -144,37 +144,23 @@ toDecisionTree variantDict rawBranches =
144144
Nothing ->
145145
let
146146
path =
147-
smallDefaults branches
148-
149-
relevantTests =
150-
testsAtPath path branches
151-
152-
allRawEdges =
153-
map (edgesFor path branches) relevantTests
154-
155-
(rawEdges, unexplored) =
156-
if isComplete variantDict relevantTests then
157-
( init allRawEdges
158-
, snd (last allRawEdges)
159-
)
147+
pickPath variantDict branches
160148

161-
else
162-
( allRawEdges
163-
, filter (isIrrelevantTo path) branches
164-
)
149+
(edges, fallback) =
150+
gatherEdges variantDict branches path
165151

166-
edges =
167-
map (second (toDecisionTree variantDict)) rawEdges
152+
decisionEdges =
153+
map (second (toDecisionTree variantDict)) edges
168154
in
169-
case (edges, unexplored) of
155+
case (decisionEdges, fallback) of
170156
([(_tag, decisionTree)], []) ->
171157
decisionTree
172158

173159
(_, []) ->
174-
Decision path edges Nothing
160+
Decision path decisionEdges Nothing
175161

176162
(_, _) ->
177-
Decision path edges (Just (toDecisionTree variantDict unexplored))
163+
Decision path decisionEdges (Just (toDecisionTree variantDict fallback))
178164

179165

180166
isComplete :: VariantDict -> [Test] -> Bool
@@ -283,6 +269,28 @@ getSubstitution (path, A.A _ pattern) =
283269
Nothing
284270

285271

272+
-- GATHER OUTGOING EDGES
273+
274+
gatherEdges :: VariantDict -> [Branch] -> Path -> ([(Test, [Branch])], [Branch])
275+
gatherEdges variantDict branches path =
276+
let
277+
relevantTests =
278+
testsAtPath path branches
279+
280+
allRawEdges =
281+
map (edgesFor path branches) relevantTests
282+
in
283+
if isComplete variantDict relevantTests then
284+
( init allRawEdges
285+
, snd (last allRawEdges)
286+
)
287+
288+
else
289+
( allRawEdges
290+
, filter (isIrrelevantTo path) branches
291+
)
292+
293+
286294
-- FIND RELEVANT TESTS
287295

288296
testsAtPath :: Path -> [Branch] -> [Test]
@@ -420,18 +428,20 @@ needsTests (A.A _ pattern) =
420428
True
421429

422430

423-
-- PATH PICKING HEURISTICS
431+
-- PICK A PATH
424432

425-
smallDefaults :: [Branch] -> Path
426-
smallDefaults branches =
433+
pickPath :: VariantDict -> [Branch] -> Path
434+
pickPath variantDict branches =
427435
let
428436
allPaths =
429437
Maybe.mapMaybe isChoicePath (concatMap _patterns branches)
430-
431-
weightedPaths =
432-
map (\path -> (path, length (filter (isIrrelevantTo path) branches))) allPaths
433438
in
434-
fst (List.minimumBy (compare `on` snd) weightedPaths)
439+
case bests (addWeights (smallDefaults branches) allPaths) of
440+
[path] ->
441+
path
442+
443+
tiedPaths ->
444+
head (bests (addWeights (smallBranchingFactor variantDict branches) tiedPaths))
435445

436446

437447
isChoicePath :: (Path, CPattern) -> Maybe Path
@@ -442,4 +452,38 @@ isChoicePath (path, pattern) =
442452
Nothing
443453

444454

445-
-- smallBranchingFactor :: [Branch] -> Path
455+
addWeights :: (Path -> Int) -> [Path] -> [(Path, Int)]
456+
addWeights toWeight paths =
457+
map (\path -> (path, toWeight path)) paths
458+
459+
460+
bests :: [(Path, Int)] -> [Path]
461+
bests ((path,weight):weightedPaths) =
462+
let
463+
gatherMinimum acc@(minWeight, paths) (path, weight) =
464+
if weight == minWeight then
465+
(minWeight, path : paths)
466+
467+
else if weight < minWeight then
468+
(weight, [path])
469+
470+
else
471+
acc
472+
in
473+
snd (List.foldl' gatherMinimum (weight, [path]) weightedPaths)
474+
475+
476+
-- PATH PICKING HEURISTICS
477+
478+
smallDefaults :: [Branch] -> Path -> Int
479+
smallDefaults branches path =
480+
length (filter (isIrrelevantTo path) branches)
481+
482+
483+
smallBranchingFactor :: VariantDict -> [Branch] -> Path -> Int
484+
smallBranchingFactor variantDict branches path =
485+
let
486+
(edges, fallback) =
487+
gatherEdges variantDict branches path
488+
in
489+
length edges + (if null fallback then 0 else 1)

0 commit comments

Comments
 (0)