| ... |
... |
@@ -26,6 +26,7 @@ import GHC.Types.Literal.Floating |
|
26
|
26
|
import GHC.Types.Unique.FM
|
|
27
|
27
|
import GHC.Types.Unique
|
|
28
|
28
|
import GHC.Utils.Word64 (truncateWord64ToWord32)
|
|
|
29
|
+import GHC.Utils.Panic.Plain (assert)
|
|
29
|
30
|
import Control.Arrow (first, second)
|
|
30
|
31
|
import Data.List.NonEmpty (NonEmpty (..))
|
|
31
|
32
|
import qualified Data.List.NonEmpty as NE
|
| ... |
... |
@@ -60,16 +61,31 @@ import qualified Data.List.NonEmpty as NE |
|
60
|
61
|
|
|
61
|
62
|
-- TODO: Use optimization fuel
|
|
62
|
63
|
elimCommonBlocks :: CmmGraph -> CmmGraph
|
|
63
|
|
-elimCommonBlocks g = replaceLabels env $ copyTicks env g
|
|
|
64
|
+elimCommonBlocks g =
|
|
|
65
|
+ assert (g_entry g == g_entry g') g'
|
|
64
|
66
|
where
|
|
|
67
|
+ g' = replaceLabels env $ copyTicks env g
|
|
65
|
68
|
env = iterate mapEmpty blocks_with_key
|
|
66
|
69
|
-- The order of blocks doesn't matter here. While we could use
|
|
67
|
70
|
-- revPostorder which drops unreachable blocks this is done in
|
|
68
|
71
|
-- ContFlowOpt already which runs before this pass. So we use
|
|
69
|
72
|
-- toBlockList since it is faster.
|
|
70
|
|
- groups = groupByInt hash_block (toBlockList g) :: [[CmmBlock]]
|
|
|
73
|
+ -- One exception: The entry block most come first or we risk eliminating it
|
|
|
74
|
+ -- in favour of another block. See Note [Retain entry block during common block elimination.]
|
|
|
75
|
+ groups = groupByInt hash_block (toBlockListEntryFirst g) :: [[CmmBlock]]
|
|
71
|
76
|
blocks_with_key = [ [ (successors b, [b]) | b <- bs] | bs <- groups]
|
|
72
|
77
|
|
|
|
78
|
+-- Note [Retain entry block during common block elimination.]
|
|
|
79
|
+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
80
|
+-- At the stage we run common block elimination (CBE) we only have one info
|
|
|
81
|
+-- table for the entry label. Which means we can get away without applying the
|
|
|
82
|
+-- block label substitution to the info table *as long as we keep the first block*.
|
|
|
83
|
+-- When combining blocks the first block in the list of blocks is kept, and the later
|
|
|
84
|
+-- one eliminated, so we can achieve this by simply using toBlockListEntryFirst.
|
|
|
85
|
+--
|
|
|
86
|
+-- If we don't we end up with #27722 where the entry block was eliminated in favour
|
|
|
87
|
+-- of another block.
|
|
|
88
|
+
|
|
73
|
89
|
-- Invariant: The blocks in the list are pairwise distinct
|
|
74
|
90
|
-- (so avoid comparing them again)
|
|
75
|
91
|
type DistinctBlocks = [CmmBlock]
|