summaryrefslogtreecommitdiff
path: root/compiler/cmm/CmmContFlowOpt.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/cmm/CmmContFlowOpt.hs')
-rw-r--r--compiler/cmm/CmmContFlowOpt.hs45
1 files changed, 36 insertions, 9 deletions
diff --git a/compiler/cmm/CmmContFlowOpt.hs b/compiler/cmm/CmmContFlowOpt.hs
index 82f7243e73..c59a4342b4 100644
--- a/compiler/cmm/CmmContFlowOpt.hs
+++ b/compiler/cmm/CmmContFlowOpt.hs
@@ -4,17 +4,18 @@
module CmmContFlowOpt
( cmmCfgOpts
, cmmCfgOptsProc
+ , removeUnreachableBlocksProc
, removeUnreachableBlocks
, replaceLabels
)
where
+import Hoopl
import BlockId
import Cmm
import CmmUtils
import Maybes
-import Hoopl
import Control.Monad
import Prelude hiding (succ, unzip, zip)
@@ -136,9 +137,10 @@ blockConcat splitting_procs g@CmmGraph { g_entry = entry_id }
= (blocks, mapInsert b' dest shortcut_map)
-- replaceLabels will substitute dest for b' everywhere, later
- -- non-calls: see if we can shortcut any of the successors.
+ -- non-calls: see if we can shortcut any of the successors,
+ -- and check whether we should invert the conditional
| Nothing <- callContinuation_maybe last
- = ( mapInsert bid (blockJoinTail head shortcut_last) blocks
+ = ( mapInsert bid (blockJoinTail head swapcond_last) blocks
, shortcut_map )
| otherwise
@@ -146,17 +148,38 @@ blockConcat splitting_procs g@CmmGraph { g_entry = entry_id }
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
+ where
+ shortcut l =
+ case mapLookup l blocks of
+ Just b | Just dest <- canShortcut b -> dest
+ _otherwise -> l
+
+ -- for a conditional, we invert the conditional if that
+ -- would make it more likely that the branch-not-taken case
+ -- becomes a fallthrough. This helps the native codegen a
+ -- little bit, and probably has no effect on LLVM. It's
+ -- convenient to do it here, where we have the information
+ -- about predecessors.
+ --
+ swapcond_last
+ | CmmCondBranch cond t f <- shortcut_last
+ , numPreds f > 1
+ , numPreds t == 1
+ , Just cond' <- maybeInvertCmmExpr cond
+ = CmmCondBranch cond' f t
+
+ | otherwise
+ = shortcut_last
+
shouldConcatWith b block
| okToDuplicate block = True -- short enough to duplicate
- | num_preds b == 1 = True -- only one predecessor: go for it
+ | numPreds b == 1 = True -- only one predecessor: go for it
| otherwise = False
- where num_preds bid = mapLookup bid backEdges `orElse` 0
+
+ numPreds bid = mapLookup bid backEdges `orElse` 0
canShortcut :: CmmBlock -> Maybe BlockId
canShortcut block
@@ -265,6 +288,10 @@ predMap blocks = foldr add_preds mapEmpty blocks -- find the back edges
--
-- Removing unreachable blocks
+removeUnreachableBlocksProc :: CmmDecl -> CmmDecl
+removeUnreachableBlocksProc (CmmProc info lbl live g)
+ = CmmProc info lbl live (removeUnreachableBlocks g)
+
removeUnreachableBlocks :: CmmGraph -> CmmGraph
removeUnreachableBlocks g
| length blocks < mapSize (toBlockMap g) = ofBlockList (g_entry g) blocks