| ... |
... |
@@ -891,7 +891,7 @@ livenessSCCs _ blockmap done [] |
|
891
|
891
|
= (done, blockmap)
|
|
892
|
892
|
|
|
893
|
893
|
livenessSCCs platform blockmap done (AcyclicSCC block : sccs)
|
|
894
|
|
- = let (_, blockmap', block') = livenessBlock platform blockmap block
|
|
|
894
|
+ = let (blockmap', block') = livenessBlock platform blockmap block
|
|
895
|
895
|
in livenessSCCs platform blockmap' (AcyclicSCC block' : done) sccs
|
|
896
|
896
|
|
|
897
|
897
|
livenessSCCs platform blockmap done
|
| ... |
... |
@@ -909,9 +909,8 @@ livenessSCCs platform blockmap done |
|
909
|
909
|
| otherwise = (bm', blocks'')
|
|
910
|
910
|
where (changed, bm', blocks'') = linearLiveness bm blocks
|
|
911
|
911
|
|
|
912
|
|
- -- Like @mapAccumL (livenessBlock platform)@, but also OR's together
|
|
913
|
|
- -- the per-block changed flags reported by livenessBlock, so the
|
|
914
|
|
- -- caller can detect the fixed point without comparing block maps.
|
|
|
912
|
+ -- Like @mapAccumL (livenessBlock platform)@, but also reports whether
|
|
|
913
|
+ -- any of the SCC's blocks changed.
|
|
915
|
914
|
linearLiveness
|
|
916
|
915
|
:: Instruction instr
|
|
917
|
916
|
=> BlockMap Regs -> [LiveBasicBlock instr]
|
| ... |
... |
@@ -921,8 +920,10 @@ livenessSCCs platform blockmap done |
|
921
|
920
|
go !changed bm [] = (changed, bm, [])
|
|
922
|
921
|
go !changed bm (block : blks') =
|
|
923
|
922
|
case livenessBlock platform bm block of
|
|
924
|
|
- (blockChanged, bm', block') ->
|
|
925
|
|
- let !changed' = changed || blockChanged
|
|
|
923
|
+ (bm', block') ->
|
|
|
924
|
+ let bid = blockId block
|
|
|
925
|
+ !changed' = changed
|
|
|
926
|
+ || mapLookup bid bm /= mapLookup bid bm'
|
|
926
|
927
|
in case go changed' bm' blks' of
|
|
927
|
928
|
(changed'', bm'', blks'') ->
|
|
928
|
929
|
(changed'', bm'', block' : blks'')
|
| ... |
... |
@@ -935,24 +936,19 @@ livenessBlock |
|
935
|
936
|
=> Platform
|
|
936
|
937
|
-> BlockMap Regs
|
|
937
|
938
|
-> LiveBasicBlock instr
|
|
938
|
|
- -> (Bool, BlockMap Regs, LiveBasicBlock instr)
|
|
|
939
|
+ -> (BlockMap Regs, LiveBasicBlock instr)
|
|
939
|
940
|
|
|
940
|
941
|
livenessBlock platform blockmap (BasicBlock block_id instrs)
|
|
941
|
942
|
= let
|
|
942
|
943
|
(regsLiveOnEntry, instrs1)
|
|
943
|
944
|
= livenessBack platform noRegs blockmap [] (reverse instrs)
|
|
|
945
|
+ blockmap' = mapInsert block_id regsLiveOnEntry blockmap
|
|
944
|
946
|
|
|
945
|
947
|
instrs2 = livenessForward platform regsLiveOnEntry instrs1
|
|
946
|
948
|
|
|
947
|
949
|
output = BasicBlock block_id instrs2
|
|
948
|
950
|
|
|
949
|
|
- -- Fuse the insert with the lookup of the old entry, so the fixpoint loop in
|
|
950
|
|
- -- livenessSCCs can tell whether this block changed for free, without a
|
|
951
|
|
- -- separate map traversal. A single 'case' lets the pair from mapInsertLookup
|
|
952
|
|
- -- cancel away rather than being allocated.
|
|
953
|
|
- in case mapInsertLookup block_id regsLiveOnEntry blockmap of
|
|
954
|
|
- (oldEntry, blockmap') ->
|
|
955
|
|
- (oldEntry /= Just regsLiveOnEntry, blockmap', output)
|
|
|
951
|
+ in ( blockmap', output)
|
|
956
|
952
|
|
|
957
|
953
|
-- | Calculate liveness going forwards,
|
|
958
|
954
|
-- filling in when regs are born
|