summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/cmm/CmmContFlowOpt.hs19
1 files changed, 15 insertions, 4 deletions
diff --git a/compiler/cmm/CmmContFlowOpt.hs b/compiler/cmm/CmmContFlowOpt.hs
index 885e8b54fc..f686aa918b 100644
--- a/compiler/cmm/CmmContFlowOpt.hs
+++ b/compiler/cmm/CmmContFlowOpt.hs
@@ -12,14 +12,11 @@ where
import BlockId
import Cmm
import CmmUtils
-import Digraph
import Maybes
-import Outputable
import Hoopl
import Control.Monad
import Prelude hiding (succ, unzip, zip)
-import qualified Data.IntMap as Map
-----------------------------------------------------------------------------
--
@@ -106,16 +103,30 @@ blockConcat g@CmmGraph { g_entry = entry_id }
, shouldConcatWith b' blk'
= (mapInsert bid (splice head blk') blocks, shortcut_map)
+ -- calls: if we can shortcut the continuation label, then
+ -- we must *also* remember to substitute for the label in the
+ -- code, because we will push it somewhere.
| Just b' <- callContinuation_maybe last
, Just blk' <- mapLookup b' blocks
, Just dest <- canShortcut blk'
= (blocks, mapInsert b' dest shortcut_map)
-- replaceLabels will substitute dest for b' everywhere, later
- | otherwise = unchanged
+ -- non-calls: see if we can shortcut any of the successors.
+ | Nothing <- callContinuation_maybe last
+ = ( mapInsert bid (blockJoinTail head shortcut_last) blocks
+ , shortcut_map )
+
+ | otherwise
+ = (blocks, shortcut_map)
where
(head, last) = blockSplitTail block
bid = entryLabel block
+ shortcut_last = mapSuccessors shortcut last
+ shortcut l =
+ case mapLookup l blocks of
+ Just b | Just dest <- canShortcut b -> dest
+ _otherwise -> l
shouldConcatWith b block
| num_preds b == 1 = True -- only one predecessor: go for it