diff options
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) |