diff options
author | Bartosz Nitka <niteria@gmail.com> | 2016-07-01 04:58:39 -0700 |
---|---|---|
committer | Bartosz Nitka <niteria@gmail.com> | 2016-07-01 05:44:27 -0700 |
commit | cbfeff4b3caade8092c13f0f71371e6525ece9ac (patch) | |
tree | 300101b60cea80cfd2640e4db74efdaa489b7cd9 /compiler/nativeGen/RegAlloc/Graph | |
parent | 6377757918c1e7f63638d6f258cad8d5f02bb6a7 (diff) | |
download | haskell-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/RegAlloc/Graph')
-rw-r--r-- | compiler/nativeGen/RegAlloc/Graph/ArchBase.hs | 13 | ||||
-rw-r--r-- | compiler/nativeGen/RegAlloc/Graph/Main.hs | 21 | ||||
-rw-r--r-- | compiler/nativeGen/RegAlloc/Graph/Spill.hs | 10 | ||||
-rw-r--r-- | compiler/nativeGen/RegAlloc/Graph/SpillClean.hs | 6 | ||||
-rw-r--r-- | compiler/nativeGen/RegAlloc/Graph/SpillCost.hs | 11 |
5 files changed, 41 insertions, 20 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) |