summaryrefslogtreecommitdiff
path: root/compiler/nativeGen/AsmCodeGen.hs
diff options
context:
space:
mode:
authorJoachim Breitner <mail@joachim-breitner.de>2015-05-16 17:47:31 +0200
committerJoachim Breitner <mail@joachim-breitner.de>2015-05-16 21:29:18 +0200
commit8e4dc8fb63b8d3bfee485c1c830776f3ed704f4d (patch)
tree80194342c14dc6ca1ea6de9ea046ff69bc78ad1a /compiler/nativeGen/AsmCodeGen.hs
parentc256357242ee2dd282fd0516260edccbb7617244 (diff)
downloadhaskell-8e4dc8fb63b8d3bfee485c1c830776f3ed704f4d.tar.gz
Greatly speed up nativeCodeGen/seqBlocks
When working on #10397, I noticed that "reorder" in nativeCodeGen/seqBlocks took more than 60% of the time. With this refactoring, it does not even show up in the profile any more. This fixes #10422. Differential Revision: https://phabricator.haskell.org/D893
Diffstat (limited to 'compiler/nativeGen/AsmCodeGen.hs')
-rw-r--r--compiler/nativeGen/AsmCodeGen.hs53
1 files changed, 35 insertions, 18 deletions
diff --git a/compiler/nativeGen/AsmCodeGen.hs b/compiler/nativeGen/AsmCodeGen.hs
index 4080398e1f..9c57e76143 100644
--- a/compiler/nativeGen/AsmCodeGen.hs
+++ b/compiler/nativeGen/AsmCodeGen.hs
@@ -63,6 +63,7 @@ import UniqFM
import UniqSupply
import DynFlags
import Util
+import Unique
import BasicTypes ( Alignment )
import Digraph
@@ -779,25 +780,41 @@ mkNode block@(BasicBlock id instrs) = (block, id, getOutEdges instrs)
seqBlocks :: BlockEnv i -> [(GenBasicBlock t1, BlockId, [BlockId])]
-> [GenBasicBlock t1]
-seqBlocks _ [] = []
-seqBlocks infos ((block,_,[]) : rest)
- = block : seqBlocks infos rest
-seqBlocks infos ((block@(BasicBlock id instrs),_,[next]) : rest)
- | can_fallthrough = BasicBlock id (init instrs) : seqBlocks infos rest'
- | otherwise = block : seqBlocks infos rest'
+seqBlocks infos blocks = placeNext pullable0 todo0
where
- can_fallthrough = not (mapMember next infos) && can_reorder
- (can_reorder, rest') = reorder next [] rest
- -- TODO: we should do a better job for cycles; try to maximise the
- -- fallthroughs within a loop.
-seqBlocks _ _ = panic "AsmCodegen:seqBlocks"
-
-reorder :: (Eq a) => a -> [(t, a, t1)] -> [(t, a, t1)] -> (Bool, [(t, a, t1)])
-reorder _ accum [] = (False, reverse accum)
-reorder id accum (b@(block,id',out) : rest)
- | id == id' = (True, (block,id,out) : reverse accum ++ rest)
- | otherwise = reorder id (b:accum) rest
-
+ -- pullable: Blocks that are not yet placed
+ -- todo: Original order of blocks, to be followed if we have no good
+ -- reason not to;
+ -- may include blocks that have already been placed, but then
+ -- these are not in pullable
+ pullable0 = listToUFM [ (i,(b,n)) | (b,i,n) <- blocks ]
+ todo0 = [i | (_,i,_) <- blocks ]
+
+ placeNext _ [] = []
+ placeNext pullable (i:rest)
+ | Just (block, pullable') <- lookupDeleteUFM pullable i
+ = place pullable' rest block
+ | otherwise
+ -- We already placed this block, so ignore
+ = placeNext pullable rest
+
+ place pullable todo (block,[])
+ = block : placeNext pullable todo
+ place pullable todo (block@(BasicBlock id instrs),[next])
+ | mapMember next infos
+ = block : placeNext pullable todo
+ | Just (nextBlock, pullable') <- lookupDeleteUFM pullable next
+ = BasicBlock id (init instrs) : place pullable' todo nextBlock
+ | otherwise
+ = block : placeNext pullable todo
+ place _ _ (_,tooManyNextNodes)
+ = pprPanic "seqBlocks" (ppr tooManyNextNodes)
+
+
+lookupDeleteUFM :: Uniquable key => UniqFM elt -> key -> Maybe (elt, UniqFM elt)
+lookupDeleteUFM m k = do -- Maybe monad
+ v <- lookupUFM m k
+ return (v, delFromUFM m k)
-- -----------------------------------------------------------------------------
-- Generate jump tables