summaryrefslogtreecommitdiff
path: root/compiler/nativeGen
diff options
context:
space:
mode:
authorBartosz Nitka <niteria@gmail.com>2016-07-01 04:58:39 -0700
committerBartosz Nitka <niteria@gmail.com>2016-07-01 05:44:27 -0700
commitcbfeff4b3caade8092c13f0f71371e6525ece9ac (patch)
tree300101b60cea80cfd2640e4db74efdaa489b7cd9 /compiler/nativeGen
parent6377757918c1e7f63638d6f258cad8d5f02bb6a7 (diff)
downloadhaskell-cbfeff4b3caade8092c13f0f71371e6525ece9ac.tar.gz
Remove uniqSetToList
This documents nondeterminism in code generation and removes the nondeterministic ufmToList function. In the future someone will have to use nonDetEltsUFM (with proper explanation) or pprUFM.
Diffstat (limited to 'compiler/nativeGen')
-rw-r--r--compiler/nativeGen/RegAlloc/Graph/ArchBase.hs13
-rw-r--r--compiler/nativeGen/RegAlloc/Graph/Main.hs21
-rw-r--r--compiler/nativeGen/RegAlloc/Graph/Spill.hs10
-rw-r--r--compiler/nativeGen/RegAlloc/Graph/SpillClean.hs6
-rw-r--r--compiler/nativeGen/RegAlloc/Graph/SpillCost.hs11
-rw-r--r--compiler/nativeGen/RegAlloc/Linear/Main.hs8
-rw-r--r--compiler/nativeGen/RegAlloc/Liveness.hs24
7 files changed, 61 insertions, 32 deletions
diff --git a/compiler/nativeGen/RegAlloc/Graph/ArchBase.hs b/compiler/nativeGen/RegAlloc/Graph/ArchBase.hs
index 787b1d2f85..c3df743454 100644
--- a/compiler/nativeGen/RegAlloc/Graph/ArchBase.hs
+++ b/compiler/nativeGen/RegAlloc/Graph/ArchBase.hs
@@ -22,6 +22,7 @@ module RegAlloc.Graph.ArchBase (
squeese
) where
import UniqSet
+import UniqFM
import Unique
@@ -88,7 +89,10 @@ worst :: (RegClass -> UniqSet Reg)
worst regsOfClass regAlias neighbors classN classC
= let regAliasS regs = unionManyUniqSets
$ map regAlias
- $ uniqSetToList regs
+ $ nonDetEltsUFM regs
+ -- This is non-deterministic but we do not
+ -- currently support deterministic code-generation.
+ -- See Note [Unique Determinism and code generation]
-- all the regs in classes N, C
regsN = regsOfClass classN
@@ -117,7 +121,8 @@ bound :: (RegClass -> UniqSet Reg)
bound regsOfClass regAlias classN classesC
= let regAliasS regs = unionManyUniqSets
$ map regAlias
- $ uniqSetToList regs
+ $ nonDetEltsUFM regs
+ -- See Note [Unique Determinism and code generation]
regsC_aliases
= unionManyUniqSets
@@ -150,5 +155,5 @@ powersetL = map concat . mapM (\x -> [[],[x]])
-- | powersetLS (list of sets)
powersetLS :: Uniquable a => UniqSet a -> [UniqSet a]
-powersetLS s = map mkUniqSet $ powersetL $ uniqSetToList s
-
+powersetLS s = map mkUniqSet $ powersetL $ nonDetEltsUFM s
+ -- See Note [Unique Determinism and code generation]
diff --git a/compiler/nativeGen/RegAlloc/Graph/Main.hs b/compiler/nativeGen/RegAlloc/Graph/Main.hs
index 52ed438f81..f7b3d0179d 100644
--- a/compiler/nativeGen/RegAlloc/Graph/Main.hs
+++ b/compiler/nativeGen/RegAlloc/Graph/Main.hs
@@ -110,8 +110,11 @@ regAlloc_spin dflags spinCount triv regsFree slotsFree debug_codeGraphs code
( text "It looks like the register allocator is stuck in an infinite loop."
$$ text "max cycles = " <> int maxSpinCount
$$ text "regsFree = " <> (hcat $ punctuate space $ map ppr
- $ uniqSetToList $ unionManyUniqSets
- $ eltsUFM regsFree)
+ $ nonDetEltsUFM $ unionManyUniqSets
+ $ nonDetEltsUFM regsFree)
+ -- This is non-deterministic but we do not
+ -- currently support deterministic code-generation.
+ -- See Note [Unique Determinism and code generation]
$$ text "slotsFree = " <> ppr (sizeUniqSet slotsFree))
-- Build the register conflict graph from the cmm code.
@@ -312,15 +315,16 @@ graphAddConflictSet
graphAddConflictSet set graph
= let virtuals = mkUniqSet
- [ vr | RegVirtual vr <- uniqSetToList set ]
+ [ vr | RegVirtual vr <- nonDetEltsUFM set ]
graph1 = Color.addConflicts virtuals classOfVirtualReg graph
graph2 = foldr (\(r1, r2) -> Color.addExclusion r1 classOfVirtualReg r2)
graph1
[ (vr, rr)
- | RegVirtual vr <- uniqSetToList set
- , RegReal rr <- uniqSetToList set]
+ | RegVirtual vr <- nonDetEltsUFM set
+ , RegReal rr <- nonDetEltsUFM set]
+ -- See Note [Unique Determinism and code generation]
in graph2
@@ -410,10 +414,11 @@ seqNode node
= seqVirtualReg (Color.nodeId node)
`seq` seqRegClass (Color.nodeClass node)
`seq` seqMaybeRealReg (Color.nodeColor node)
- `seq` (seqVirtualRegList (uniqSetToList (Color.nodeConflicts node)))
- `seq` (seqRealRegList (uniqSetToList (Color.nodeExclusions node)))
+ `seq` (seqVirtualRegList (nonDetEltsUFM (Color.nodeConflicts node)))
+ `seq` (seqRealRegList (nonDetEltsUFM (Color.nodeExclusions node)))
`seq` (seqRealRegList (Color.nodePreference node))
- `seq` (seqVirtualRegList (uniqSetToList (Color.nodeCoalesce node)))
+ `seq` (seqVirtualRegList (nonDetEltsUFM (Color.nodeCoalesce node)))
+ -- It's OK to use nonDetEltsUFM for seq
seqVirtualReg :: VirtualReg -> ()
seqVirtualReg reg = reg `seq` ()
diff --git a/compiler/nativeGen/RegAlloc/Graph/Spill.hs b/compiler/nativeGen/RegAlloc/Graph/Spill.hs
index 1ec8d1276f..9c3ccae315 100644
--- a/compiler/nativeGen/RegAlloc/Graph/Spill.hs
+++ b/compiler/nativeGen/RegAlloc/Graph/Spill.hs
@@ -62,9 +62,12 @@ regSpill platform code slotsFree regs
| otherwise
= do
-- Allocate a slot for each of the spilled regs.
- let slots = take (sizeUniqSet regs) $ uniqSetToList slotsFree
+ let slots = take (sizeUniqSet regs) $ nonDetEltsUFM slotsFree
let regSlotMap = listToUFM
- $ zip (uniqSetToList regs) slots
+ $ zip (nonDetEltsUFM regs) slots
+ -- This is non-deterministic but we do not
+ -- currently support deterministic code-generation.
+ -- See Note [Unique Determinism and code generation]
-- Grab the unique supply from the monad.
us <- getUniqueSupplyM
@@ -139,7 +142,8 @@ regSpill_top platform regSlotMap cmm
moreSlotsLive = Set.fromList
$ catMaybes
$ map (lookupUFM regSlotMap)
- $ uniqSetToList regsLive
+ $ nonDetEltsUFM regsLive
+ -- See Note [Unique Determinism and code generation]
slotMap'
= Map.insert blockId (Set.union curSlotsLive moreSlotsLive)
diff --git a/compiler/nativeGen/RegAlloc/Graph/SpillClean.hs b/compiler/nativeGen/RegAlloc/Graph/SpillClean.hs
index 2383d7bb3a..25d0ff4e80 100644
--- a/compiler/nativeGen/RegAlloc/Graph/SpillClean.hs
+++ b/compiler/nativeGen/RegAlloc/Graph/SpillClean.hs
@@ -414,7 +414,8 @@ intersects assocs = foldl1' intersectAssoc assocs
findRegOfSlot :: Assoc Store -> Int -> Maybe Reg
findRegOfSlot assoc slot
| close <- closeAssoc (SSlot slot) assoc
- , Just (SReg reg) <- find isStoreReg $ uniqSetToList close
+ , Just (SReg reg) <- find isStoreReg $ nonDetEltsUFM close
+ -- See Note [Unique Determinism and code generation]
= Just reg
| otherwise
@@ -582,7 +583,8 @@ closeAssoc a assoc
= closeAssoc' assoc emptyUniqSet (unitUniqSet a)
where
closeAssoc' assoc visited toVisit
- = case uniqSetToList toVisit of
+ = case nonDetEltsUFM toVisit of
+ -- See Note [Unique Determinism and code generation]
-- nothing else to visit, we're done
[] -> visited
diff --git a/compiler/nativeGen/RegAlloc/Graph/SpillCost.hs b/compiler/nativeGen/RegAlloc/Graph/SpillCost.hs
index 8860ebc7e0..beffde97bb 100644
--- a/compiler/nativeGen/RegAlloc/Graph/SpillCost.hs
+++ b/compiler/nativeGen/RegAlloc/Graph/SpillCost.hs
@@ -108,7 +108,10 @@ slurpSpillCostInfo platform cmm
countLIs rsLiveEntry (LiveInstr instr (Just live) : lis)
= do
-- Increment the lifetime counts for regs live on entry to this instr.
- mapM_ incLifetime $ uniqSetToList rsLiveEntry
+ mapM_ incLifetime $ nonDetEltsUFM rsLiveEntry
+ -- This is non-deterministic but we do not
+ -- currently support deterministic code-generation.
+ -- See Note [Unique Determinism and code generation]
-- Increment counts for what regs were read/written from.
let (RU read written) = regUsageOfInstr platform instr
@@ -137,7 +140,8 @@ slurpSpillCostInfo platform cmm
-- | Take all the virtual registers from this set.
takeVirtuals :: UniqSet Reg -> UniqSet VirtualReg
takeVirtuals set = mkUniqSet
- [ vr | RegVirtual vr <- uniqSetToList set ]
+ [ vr | RegVirtual vr <- nonDetEltsUFM set ]
+ -- See Note [Unique Determinism and code generation]
-- | Choose a node to spill from this graph
@@ -254,7 +258,8 @@ nodeDegree classOfVirtualReg graph reg
, virtConflicts
<- length
$ filter (\r -> classOfVirtualReg r == classOfVirtualReg reg)
- $ uniqSetToList
+ $ nonDetEltsUFM
+ -- See Note [Unique Determinism and code generation]
$ nodeConflicts node
= virtConflicts + sizeUniqSet (nodeExclusions node)
diff --git a/compiler/nativeGen/RegAlloc/Linear/Main.hs b/compiler/nativeGen/RegAlloc/Linear/Main.hs
index 3e2edc7c97..0fe2592e60 100644
--- a/compiler/nativeGen/RegAlloc/Linear/Main.hs
+++ b/compiler/nativeGen/RegAlloc/Linear/Main.hs
@@ -350,7 +350,8 @@ initBlock id block_live
Nothing ->
setFreeRegsR (frInitFreeRegs platform)
Just live ->
- setFreeRegsR $ foldr (frAllocateReg platform) (frInitFreeRegs platform) [ r | RegReal r <- uniqSetToList live ]
+ setFreeRegsR $ foldr (frAllocateReg platform) (frInitFreeRegs platform) [ r | RegReal r <- nonDetEltsUFM live ]
+ -- See Note [Unique Determinism and code generation]
setAssigR emptyRegMap
-- load info about register assignments leading into this block.
@@ -443,8 +444,9 @@ raInsn block_live new_instrs id (LiveInstr (Instr instr) (Just live))
return (new_instrs, [])
_ -> genRaInsn block_live new_instrs id instr
- (uniqSetToList $ liveDieRead live)
- (uniqSetToList $ liveDieWrite live)
+ (nonDetEltsUFM $ liveDieRead live)
+ (nonDetEltsUFM $ liveDieWrite live)
+ -- See Note [Unique Determinism and code generation]
raInsn _ _ _ instr
= pprPanic "raInsn" (text "no match for:" <> ppr instr)
diff --git a/compiler/nativeGen/RegAlloc/Liveness.hs b/compiler/nativeGen/RegAlloc/Liveness.hs
index e4a903e904..53cf241413 100644
--- a/compiler/nativeGen/RegAlloc/Liveness.hs
+++ b/compiler/nativeGen/RegAlloc/Liveness.hs
@@ -221,7 +221,7 @@ instance Outputable instr
where pprRegs :: SDoc -> RegSet -> SDoc
pprRegs name regs
| isEmptyUniqSet regs = empty
- | otherwise = name <> (hcat $ punctuate space $ map ppr $ uniqSetToList regs)
+ | otherwise = name <> (pprUFM regs (hcat . punctuate space . map ppr))
instance Outputable LiveInfo where
ppr (LiveInfo mb_static entryIds liveVRegsOnEntry liveSlotsOnEntry)
@@ -572,7 +572,8 @@ patchEraseLive patchF cmm
patchCmm (CmmProc info label live sccs)
| LiveInfo static id (Just blockMap) mLiveSlots <- info
= let
- patchRegSet set = mkUniqSet $ map patchF $ uniqSetToList set
+ patchRegSet set = mkUniqSet $ map patchF $ nonDetEltsUFM set
+ -- See Note [Unique Determinism and code generation]
blockMap' = mapMap patchRegSet blockMap
info' = LiveInfo static id (Just blockMap') mLiveSlots
@@ -629,9 +630,10 @@ patchRegsLiveInstr patchF li
(patchRegsOfInstr instr patchF)
(Just live
{ -- WARNING: have to go via lists here because patchF changes the uniq in the Reg
- liveBorn = mkUniqSet $ map patchF $ uniqSetToList $ liveBorn live
- , liveDieRead = mkUniqSet $ map patchF $ uniqSetToList $ liveDieRead live
- , liveDieWrite = mkUniqSet $ map patchF $ uniqSetToList $ liveDieWrite live })
+ liveBorn = mkUniqSet $ map patchF $ nonDetEltsUFM $ liveBorn live
+ , liveDieRead = mkUniqSet $ map patchF $ nonDetEltsUFM $ liveDieRead live
+ , liveDieWrite = mkUniqSet $ map patchF $ nonDetEltsUFM $ liveDieWrite live })
+ -- See Note [Unique Determinism and code generation]
--------------------------------------------------------------------------------
@@ -757,7 +759,8 @@ checkIsReverseDependent sccs'
= let dests = slurpJumpDestsOfBlock block
blocksSeen' = unionUniqSets blocksSeen $ mkUniqSet [blockId block]
badDests = dests `minusUniqSet` blocksSeen'
- in case uniqSetToList badDests of
+ in case nonDetEltsUFM badDests of
+ -- See Note [Unique Determinism and code generation]
[] -> go blocksSeen' sccs
bad : _ -> Just bad
@@ -765,7 +768,8 @@ checkIsReverseDependent sccs'
= let dests = unionManyUniqSets $ map slurpJumpDestsOfBlock blocks
blocksSeen' = unionUniqSets blocksSeen $ mkUniqSet $ map blockId blocks
badDests = dests `minusUniqSet` blocksSeen'
- in case uniqSetToList badDests of
+ in case nonDetEltsUFM badDests of
+ -- See Note [Unique Determinism and code generation]
[] -> go blocksSeen' sccs
bad : _ -> Just bad
@@ -858,7 +862,8 @@ livenessSCCs platform blockmap done
= a' == b'
where a' = map f $ mapToList a
b' = map f $ mapToList b
- f (key,elt) = (key, uniqSetToList elt)
+ f (key,elt) = (key, nonDetEltsUFM elt)
+ -- See Note [Unique Determinism and code generation]
@@ -994,7 +999,8 @@ liveness1 platform liveregs blockmap (LiveInstr instr _)
-- registers that are live only in the branch targets should
-- be listed as dying here.
live_branch_only = live_from_branch `minusUniqSet` liveregs
- r_dying_br = uniqSetToList (mkUniqSet r_dying `unionUniqSets`
+ r_dying_br = nonDetEltsUFM (mkUniqSet r_dying `unionUniqSets`
live_branch_only)
+ -- See Note [Unique Determinism and code generation]