Skip to content

Commit

Permalink
Improve performance of CallArity
Browse files Browse the repository at this point in the history
the hot path contained a call to

    v `elemUnVarSet` (neighbors g v)

and creating the set of neighbors just to check if `v` is inside
accounted for half the allocations of the test case of #15164.

By introducing a non-allocating function `hasLoopAt` for this we shave
off half the allocations. This brings the total cost of Call Arity down
to 20% of time and 23% of allocations, according to a profiled run. Not
amazing, but still much better.

Differential Revision: https://phabricator.haskell.org/D4718
  • Loading branch information
nomeata committed May 22, 2018
1 parent 97121b6 commit db6085b
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 2 deletions.
2 changes: 1 addition & 1 deletion compiler/simplCore/CallArity.hs
Original file line number Diff line number Diff line change
Expand Up @@ -735,7 +735,7 @@ domRes (_, ae) = varEnvDom ae
lookupCallArityRes :: CallArityRes -> Var -> (Arity, Bool)
lookupCallArityRes (g, ae) v
= case lookupVarEnv ae v of
Just a -> (a, not (v `elemUnVarSet` (neighbors g v)))
Just a -> (a, not (g `hasLoopAt` v))
Nothing -> (0, False)

calledWith :: CallArityRes -> Var -> UnVarSet
Expand Down
8 changes: 8 additions & 0 deletions compiler/utils/UnVarGraph.hs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ module UnVarGraph
, unionUnVarGraph, unionUnVarGraphs
, completeGraph, completeBipartiteGraph
, neighbors
, hasLoopAt
, delNode
) where

Expand Down Expand Up @@ -121,6 +122,13 @@ neighbors (UnVarGraph g) v = unionUnVarSets $ concatMap go $ bagToList g
go (CBPG s1 s2) = (if v `elemUnVarSet` s1 then [s2] else []) ++
(if v `elemUnVarSet` s2 then [s1] else [])

-- hasLoopAt G v <=> v--v ∈ G
hasLoopAt :: UnVarGraph -> Var -> Bool
hasLoopAt (UnVarGraph g) v = any go $ bagToList g
where go (CG s) = v `elemUnVarSet` s
go (CBPG s1 s2) = v `elemUnVarSet` s1 && v `elemUnVarSet` s2


delNode :: UnVarGraph -> Var -> UnVarGraph
delNode (UnVarGraph g) v = prune $ UnVarGraph $ mapBag go g
where go (CG s) = CG (s `delUnVarSet` v)
Expand Down
4 changes: 3 additions & 1 deletion testsuite/tests/perf/compiler/all.T
Original file line number Diff line number Diff line change
Expand Up @@ -1287,7 +1287,9 @@ test ('T9630',

test ('T15164',
[ compiler_stats_num_field('bytes allocated',
[(wordsize(64), 3423873408, 10)
[(wordsize(64), 1945564312, 10)
# initial: 3423873408
# 2018-05-22: 1945564312 Fix bottleneck in CallArity
])
],
compile,
Expand Down

0 comments on commit db6085b

Please sign in to comment.