| ... |
... |
@@ -879,7 +879,7 @@ computeLiveness platform sccs |
|
879
|
879
|
, ppr sccs'])
|
|
880
|
880
|
|
|
881
|
881
|
livenessSCCs
|
|
882
|
|
- :: Instruction instr
|
|
|
882
|
+ :: forall instr. Instruction instr
|
|
883
|
883
|
=> Platform
|
|
884
|
884
|
-> BlockMap Regs
|
|
885
|
885
|
-> [SCC (LiveBasicBlock instr)] -- accum
|
| ... |
... |
@@ -891,23 +891,27 @@ 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
|
|
898
|
898
|
(CyclicSCC blocks : sccs) =
|
|
899
|
899
|
livenessSCCs platform blockmap' (CyclicSCC blocks':done) sccs
|
|
900
|
|
- where (blockmap', blocks') = fixpoint blockmap
|
|
|
900
|
+ where (blockmap', blocks') = iterateUntilUnchanged blockmap
|
|
901
|
901
|
|
|
902
|
902
|
-- Iterate the liveness pass over the SCC until the block map reaches
|
|
903
|
903
|
-- a fixed point. Only the SCC's own blocks can change between
|
|
904
|
904
|
-- iterations (livenessBlock only inserts the block it processes, and
|
|
905
|
905
|
-- earlier SCCs are already finalised).
|
|
906
|
|
- fixpoint bm
|
|
907
|
|
- | changed = fixpoint bm'
|
|
|
906
|
+ iterateUntilUnchanged :: BlockMap Regs -> (BlockMap Regs, [LiveBasicBlock instr])
|
|
|
907
|
+ iterateUntilUnchanged bm
|
|
|
908
|
+ | changed = iterateUntilUnchanged bm'
|
|
908
|
909
|
| otherwise = (bm', blocks'')
|
|
909
|
910
|
where (changed, bm', blocks'') = linearLiveness bm blocks
|
|
910
|
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.
|
|
911
|
915
|
linearLiveness
|
|
912
|
916
|
:: Instruction instr
|
|
913
|
917
|
=> BlockMap Regs -> [LiveBasicBlock instr]
|
| ... |
... |
@@ -917,16 +921,13 @@ livenessSCCs platform blockmap done |
|
917
|
921
|
go !changed bm [] = (changed, bm, [])
|
|
918
|
922
|
go !changed bm (block : blks') =
|
|
919
|
923
|
case livenessBlock platform bm block of
|
|
920
|
|
- (bm', block') ->
|
|
921
|
|
- let bid = blockId block
|
|
922
|
|
- !changed' = changed
|
|
923
|
|
- || mapLookup bid bm /= mapLookup bid bm'
|
|
|
924
|
+ (blockChanged, bm', block') ->
|
|
|
925
|
+ let !changed' = changed || blockChanged
|
|
924
|
926
|
in case go changed' bm' blks' of
|
|
925
|
927
|
(changed'', bm'', blks'') ->
|
|
926
|
928
|
(changed'', bm'', block' : blks'')
|
|
927
|
929
|
|
|
928
|
930
|
|
|
929
|
|
-
|
|
930
|
931
|
-- | Annotate a basic block with register liveness information.
|
|
931
|
932
|
--
|
|
932
|
933
|
livenessBlock
|
| ... |
... |
@@ -934,19 +935,23 @@ livenessBlock |
|
934
|
935
|
=> Platform
|
|
935
|
936
|
-> BlockMap Regs
|
|
936
|
937
|
-> LiveBasicBlock instr
|
|
937
|
|
- -> (BlockMap Regs, LiveBasicBlock instr)
|
|
|
938
|
+ -> (Bool, BlockMap Regs, LiveBasicBlock instr)
|
|
938
|
939
|
|
|
939
|
940
|
livenessBlock platform blockmap (BasicBlock block_id instrs)
|
|
940
|
941
|
= let
|
|
941
|
942
|
(regsLiveOnEntry, instrs1)
|
|
942
|
943
|
= livenessBack platform noRegs blockmap [] (reverse instrs)
|
|
943
|
|
- blockmap' = mapInsert block_id regsLiveOnEntry blockmap
|
|
|
944
|
+ -- Fuse the insert with the lookup of the old entry, so the fixpoint
|
|
|
945
|
+ -- loop in livenessSCCs can tell whether this block changed for free,
|
|
|
946
|
+ -- without a separate map traversal.
|
|
|
947
|
+ (oldEntry, blockmap') = mapInsertLookup block_id regsLiveOnEntry blockmap
|
|
|
948
|
+ changed = oldEntry /= Just regsLiveOnEntry
|
|
944
|
949
|
|
|
945
|
950
|
instrs2 = livenessForward platform regsLiveOnEntry instrs1
|
|
946
|
951
|
|
|
947
|
952
|
output = BasicBlock block_id instrs2
|
|
948
|
953
|
|
|
949
|
|
- in ( blockmap', output)
|
|
|
954
|
+ in (changed, blockmap', output)
|
|
950
|
955
|
|
|
951
|
956
|
-- | Calculate liveness going forwards,
|
|
952
|
957
|
-- filling in when regs are born
|