2 % (c) The AQUA Project, Glasgow University, 1993-2000
4 \section[AsmRegAlloc]{Register allocator}
7 module AsmRegAlloc ( runRegAllocate ) where
9 #include "HsVersions.h"
11 import MachCode ( InstrBlock )
12 import MachMisc ( Instr(..) )
13 import PprMach ( pprUserReg, pprInstr ) -- debugging
17 import FiniteMap ( FiniteMap, emptyFM, addListToFM, delListFromFM,
18 lookupFM, keysFM, eltsFM, mapFM, addToFM_C, addToFM,
19 listToFM, fmToList, lookupWithDefaultFM )
20 import Maybes ( maybeToBool )
21 import Unique ( mkBuiltinUnique )
22 import Util ( mapAccumB )
23 import OrdList ( unitOL, appOL, fromOL, concatOL )
25 import Unique ( Unique, Uniquable(..), mkPseudoUnique3 )
26 import CLabel ( CLabel, pprCLabel )
28 import List ( mapAccumL, nub, sort )
29 import Array ( Array, array, (!), bounds )
32 This is the generic register allocator. It does allocation for all
33 architectures. Details for specific architectures are given in
34 RegAllocInfo.lhs. In practice the allocator needs to know next to
35 nothing about an architecture to do its job:
37 * It needs to be given a list of the registers it can allocate to.
39 * It needs to be able to find out which registers each insn reads and
42 * It needs be able to change registers in instructions into other
45 * It needs to be able to find out where execution could go after an
48 * It needs to be able to discover sets of registers which can be
49 used to attempt spilling.
51 First we try something extremely simple. If that fails, we have to do
57 -> ([Instr] -> [[Reg]])
61 runRegAllocate regs find_reserve_regs instrs
63 Just simple -> --trace "SIMPLE"
65 Nothing -> --trace "GENERAL"
69 = error "nativeGen: spilling failed. Workaround: compile with -fvia-C.\n"
70 tryGeneral (resv:resvs)
71 = case generalAlloc resv of
72 Just success -> success
73 Nothing -> tryGeneral resvs
75 reserves = find_reserve_regs flatInstrs
76 flatInstrs = fromOL instrs
77 simpleAlloc = doSimpleAlloc regs flatInstrs
78 generalAlloc resvd = doGeneralAlloc regs resvd flatInstrs
81 Rather than invoke the heavyweight machinery in @doGeneralAlloc@ for
82 each and every code block, we first try using this simple, fast and
83 utterly braindead allocator. In practice it handles about 60\% of the
84 code blocks really fast, even with only 3 integer registers available.
85 Since we can always give up and fall back to @doGeneralAlloc@,
86 @doSimpleAlloc@ is geared to handling the common case as fast as
87 possible. It will succeed only if:
89 * The code mentions registers only of integer class, not floating
92 * The code doesn't mention any real registers, so we don't have to
93 think about dodging and weaving to work around fixed register uses.
95 * The code mentions at most N virtual registers, where N is the number
96 of real registers for allocation.
98 If those conditions are satisfied, we simply trundle along the code,
99 doling out a real register every time we see mention of a new virtual
100 register. We either succeed at this, or give up when one of the above
101 three conditions is no longer satisfied.
104 doSimpleAlloc :: [Reg] -> [Instr] -> Maybe [Instr]
105 doSimpleAlloc available_real_regs instrs
106 = let available_iregs
107 = filter ((== RcInteger).regClass) available_real_regs
109 trundle :: [( {-Virtual-}Reg, {-Real-}Reg )]
114 trundle vreg_map uncommitted_rregs ris_done []
115 = Just (reverse ris_done)
116 trundle vreg_map uncommitted_rregs ris_done (i:is)
120 -- Mentions no regs? Move on quickly
121 | null rds_l && null wrs_l
122 -> trundle vreg_map uncommitted_rregs (i:ris_done) is
124 -- A case we can't be bothered to handle?
125 | any isFloatingOrReal rds_l || any isFloatingOrReal wrs_l
128 -- Update the rreg commitments, and map the insn
130 -> case upd_commitment (wrs_l++rds_l)
131 vreg_map uncommitted_rregs of
132 Nothing -- out of rregs; give up
134 Just (vreg_map2, uncommitted_rregs2)
135 -> let i2 = patchRegs i (subst_reg vreg_map2)
136 in trundle vreg_map2 uncommitted_rregs2
140 = isRealReg reg || regClass reg == RcFloating
142 rds_l = regSetToList rds
143 wrs_l = regSetToList wrs
145 upd_commitment [] vr_map uncomm
146 = Just (vr_map, uncomm)
147 upd_commitment (reg:regs) vr_map uncomm
149 = upd_commitment regs vr_map uncomm
150 | reg `elem` (map fst vr_map)
151 = upd_commitment regs vr_map uncomm
155 = upd_commitment regs ((reg, head uncomm):vr_map)
159 -- If it's a RealReg, it must be STG-specific one
160 -- (Hp,Sp,BaseReg,etc), since regUsage filters them out,
161 -- so isFloatingOrReal would not have objected to it.
165 = case [rr | (vr,rr) <- vreg_map, vr == r] of
168 "doSimpleAlloc: unmapped VirtualReg"
171 trundle [] available_iregs [] instrs
174 From here onwards is the general register allocator and spiller. For
175 each flow edge (possible transition between instructions), we compute
176 which virtual and real registers are live on that edge. Then the
177 mapping is inverted, to give a mapping from register (virtual+real) to
178 sets of flow edges on which the register is live. Finally, we can use
179 those sets to decide whether a virtual reg v can be assigned to a real
180 reg r, by checking that v's live-edge-set does not intersect with r's
181 current live-edge-set. Having made that assignment, we then augment
182 r's current live-edge-set (its current commitment, you could say) with
185 doGeneralAlloc takes reserve_regs as the regs to use as spill
186 temporaries. First it tries to allocate using all regs except
187 reserve_regs. If that fails, it inserts spill code and tries again to
188 allocate regs, but this time with the spill temporaries available.
189 Even this might not work if there are insufficient spill temporaries:
190 in the worst case on x86, we'd need 3 of them, for insns like addl
191 (%reg1,%reg2,4) %reg3, since this insn uses all 3 regs as input.
195 :: [Reg] -- all allocatable regs
196 -> [Reg] -- the reserve regs
197 -> [Instr] -- instrs in
198 -> Maybe [Instr] -- instrs out
200 doGeneralAlloc all_regs reserve_regs instrs
201 -- succeeded without spilling
202 | prespill_ok = Just prespill_insns
203 -- failed, and no spill regs avail, so pointless to attempt spilling
204 | null reserve_regs = Nothing
205 -- success after spilling
206 | postspill_ok = maybetrace (spillMsg True) (Just postspill_insns)
207 -- still not enough reserves after spilling; we have to give up
208 | otherwise = maybetrace (spillMsg False) Nothing
211 = filter (`notElem` reserve_regs) all_regs
212 (prespill_ok, prespill_insns)
213 = allocUsingTheseRegs instrs prespill_regs
214 instrs_with_spill_code
215 = insertSpillCode prespill_insns
216 (postspill_ok, postspill_insns)
217 = allocUsingTheseRegs instrs_with_spill_code all_regs
220 = "nativeGen: spilling "
221 ++ (if success then "succeeded" else "failed ")
223 ++ showSDoc (hsep (map ppr reserve_regs))
226 maybetrace msg x = trace msg x
232 Here we patch instructions that reference ``registers'' which are
233 really in memory somewhere (the mapping is under the control of the
234 machine-specific code generator). We place the appropriate load
235 sequences before any instructions that use memory registers as
236 sources, and we place the appropriate spill sequences after any
237 instructions that use memory registers as destinations. The offending
238 instructions are rewritten with new dynamic registers, so generalAlloc
239 has to run register allocation again after all of this is said and
242 On some architectures (x86, currently), we do without a frame-pointer,
243 and instead spill relative to the stack pointer (%esp on x86).
244 Because the stack pointer may move, the patcher needs to keep track of
245 the current stack pointer "delta". That's easy, because all it needs
246 to do is spot the DELTA bogus-insns which will have been inserted by
247 the relevant insn selector precisely so as to notify the spiller of
248 stack-pointer movement. The delta is passed to loadReg and spillReg,
249 since they generate the actual spill code. We expect the final delta
250 to be the same as the starting one (zero), reflecting the fact that
251 changes to the stack pointer should not extend beyond a basic block.
253 Finally, there is the issue of mapping an arbitrary set of unallocated
254 VirtualRegs into a contiguous sequence of spill slots. The failed
255 allocation will have left the code peppered with references to
256 VirtualRegs, each of which contains a unique. So we make an env which
257 maps these VirtualRegs to integers, starting from zero, and pass that
258 env through to loadReg and spillReg. There, they are used to look up
259 spill slot numbers for the uniques.
262 insertSpillCode :: [Instr] -> [Instr]
263 insertSpillCode insns
264 = let uniques_in_insns
267 (foldl unionRegSets emptyRegSet
268 (map vregs_in_insn insns)))
271 RU rds wrs -> filterRegSet isVirtualReg
272 (rds `unionRegSets` wrs)
273 vreg_to_slot_map :: FiniteMap Unique Int
275 = listToFM (zip uniques_in_insns [0..])
277 ((final_stack_delta, final_ctr), insnss)
278 = mapAccumL (patchInstr vreg_to_slot_map) (0,0) insns
280 if final_stack_delta == 0
282 else pprPanic "patchMem: non-zero final delta"
283 (int final_stack_delta)
286 -- patchInstr has as a running state two Ints, one the current stack delta,
287 -- needed to figure out offsets to stack slots on archs where we spill relative
288 -- to the stack pointer, as opposed to the frame pointer. The other is a
289 -- counter, used to manufacture new temporary register names.
291 patchInstr :: FiniteMap Unique Int -> (Int,Int) -> Instr -> ((Int,Int), [Instr])
292 patchInstr vreg_to_slot_map (delta,ctr) instr
294 | null memSrcs && null memDsts
295 = ((delta',ctr), [instr])
298 = ((delta',ctr'), loadSrcs ++ [instr'] ++ spillDsts)
300 delta' = case instr of DELTA d -> d ; _ -> delta
302 (RU srcs dsts) = regUsage instr
304 -- The instr being patched may mention several vregs -- those which
305 -- could not be assigned real registers. For each such vreg, we
306 -- invent a new vreg, used only around this instruction and nowhere
307 -- else. These new vregs replace the unallocatable vregs; they are
308 -- loaded from the spill area, the instruction is done with them,
309 -- and results if any are then written back to the spill area.
311 = nub (filter isVirtualReg
312 (regSetToList srcs ++ regSetToList dsts))
314 = length vregs_in_instr
316 = ctr + n_vregs_in_instr
318 = zip vregs_in_instr [ctr, ctr+1 ..]
322 = case [vi | (vreg', vi) <- vreg_env, vreg' == vreg] of
323 [i] -> if regClass vreg == RcInteger
324 then VirtualRegI (mkPseudoUnique3 i)
325 else VirtualRegF (mkPseudoUnique3 i)
326 _ -> pprPanic "patchInstr: unmapped VReg" (ppr vreg)
330 memSrcs = filter isVirtualReg (regSetToList srcs)
331 memDsts = filter isVirtualReg (regSetToList dsts)
333 loadSrcs = map load memSrcs
334 spillDsts = map spill memDsts
336 load mem = loadReg vreg_to_slot_map delta mem (mkTmpReg mem)
337 spill mem = spillReg vreg_to_slot_map delta' (mkTmpReg mem) mem
339 instr' = patchRegs instr mkTmpReg
342 allocUsingTheseRegs is the register allocator proper. It attempts
343 to allocate dynamic regs to real regs, given a list of real regs
344 which it may use. If it fails due to lack of real regs, the returned
345 instructions use what real regs there are, but will retain uses of
346 dynamic regs for which a real reg could not be found. It is these
347 leftover dynamic reg references which insertSpillCode will later
348 assign to spill slots.
350 Some implementation notes.
351 ~~~~~~~~~~~~~~~~~~~~~~~~~~
352 Instructions are numbered sequentially, starting at zero.
354 A flow edge (FE) is a pair of insn numbers (MkFE Int Int) denoting
355 a possible flow of control from the first insn to the second.
357 The input to the register allocator is a list of instructions, which
358 mention Regs. A Reg can be a RealReg -- a real machine reg -- or a
359 VirtualReg, which carries a unique. After allocation, all the
360 VirtualReg references will have been converted into RealRegs, and
361 possible some spill code will have been inserted.
363 The heart of the register allocator works in four phases.
365 1. (find_flow_edges) Calculate all the FEs for the code list.
366 Return them not as a [FE], but implicitly, as a pair of
367 Array Int [Int], being the successor and predecessor maps
370 2. (calc_liveness) Returns a FiniteMap FE RegSet. For each
371 FE, indicates the set of registers live on that FE. Note
372 that the set includes both RealRegs and VirtualRegs. The
373 former appear because the code could mention fixed register
374 usages, and we need to take them into account from the start.
376 3. (calc_live_range_sets) Invert the above mapping, giving a
377 FiniteMap Reg FeSet, indicating, for each virtual and real
378 reg mentioned in the code, which FEs it is live on.
380 4. (calc_vreg_to_rreg_mapping) For virtual reg, try and find
381 an allocatable real register for it. Each real register has
382 a "current commitment", indicating the set of FEs it is
383 currently live on. A virtual reg v can be assigned to
384 real reg r iff v's live-fe-set does not intersect with r's
385 current commitment fe-set. If the assignment is made,
386 v's live-fe-set is union'd into r's current commitment fe-set.
387 There is also the minor restriction that v and r must be of
388 the same register class (integer or floating).
390 Once this mapping is established, we simply apply it to the
391 input insns, and that's it.
393 If no suitable real register can be found, the vreg is mapped
394 to itself, and we deem allocation to have failed. The partially
395 allocated code is returned. The higher echelons of the allocator
396 (doGeneralAlloc and runRegAlloc) then cooperate to insert spill
397 code and re-run allocation, until a successful allocation is found.
400 allocUsingTheseRegs :: [Instr] -> [Reg] -> (Bool, [Instr])
401 allocUsingTheseRegs instrs available_real_regs
402 = let (all_vregs_mapped, v_to_r_mapping)
403 = calc_vreg_to_rreg_mapping instrs available_real_regs
405 = map (flip patchRegs sr) instrs
410 = case lookupFM v_to_r_mapping reg of
412 Nothing -> pprPanic "allocateUsingTheseRegs: unmapped vreg: "
415 --trace ("allocUsingTheseRegs: " ++ show available_real_regs) (
416 (all_vregs_mapped, new_insns)
420 -- the heart of the matter.
421 calc_vreg_to_rreg_mapping :: [Instr] -> [Reg] -> (Bool, FiniteMap Reg Reg)
422 calc_vreg_to_rreg_mapping insns available_real_regs
424 lr_sets :: FiniteMap Reg FeSet
425 lr_sets = calc_live_range_sets insns
427 -- lr_sets maps: vregs mentioned in insns to sets of live FEs
428 -- and also: rregs mentioned in insns to sets of live FEs
429 -- We need to extract the rreg mapping, and use it as the
430 -- initial real-register-commitment. Also, add to the initial
431 -- commitment, empty commitments for any real regs not
434 -- which real regs do we want to keep track of in the running
435 -- commitment mapping? Precisely the available_real_regs.
436 -- We don't care about real regs mentioned by insns which are
437 -- not in this list, since we're not allocating to them.
438 initial_rr_commitment :: FiniteMap Reg FeSet
439 initial_rr_commitment
441 case lookupFM lr_sets rreg of
442 Nothing -> emptyFeSet
443 Just fixed_use_fes -> fixed_use_fes
445 | rreg <- available_real_regs]
447 -- These are the vregs for which we actually have to (try to)
448 -- assign a real register. (ie, the whole reason we're here at all :)
449 vreg_liveness_list :: [(Reg, FeSet)]
450 vreg_liveness_list = filter (not.isRealReg.fst)
453 -- A loop, which attempts to assign each vreg to a rreg.
454 loop rr_commitment v_to_r_map []
456 loop rr_commitment v_to_r_map ((vreg,vreg_live_fes):not_yet_done)
458 -- find a real reg which is not live for any of vreg_live_fes
461 | (rreg,rreg_live_FEs) <- fmToList rr_commitment,
462 regClass vreg == regClass rreg,
463 isEmptyFeSet (intersectionFeSets rreg_live_FEs
468 [] -> -- bummer. No register is available. Just go on to
469 -- the next vreg, mapping the vreg to itself.
470 loop rr_commitment (addToFM v_to_r_map vreg vreg)
473 -> -- Hurrah! Found a free reg of the right class.
474 -- Now we need to update the RR commitment.
475 loop rr_commitment2 (addToFM v_to_r_map vreg r)
479 = addToFM_C unionFeSets rr_commitment r
482 -- the final vreg to rreg mapping
484 = loop initial_rr_commitment emptyFM vreg_liveness_list
485 -- did we succeed in mapping everyone to a real reg?
487 = all isRealReg (eltsFM vreg_assignment)
489 (allocation_succeeded, vreg_assignment)
493 -- calculate liveness, then produce the live range info
494 -- as a mapping of VRegs to the set of FEs on which they are live.
495 -- The difficult part is inverting the mapping of Reg -> FeSet
496 -- to produce a mapping FE -> RegSet.
498 calc_live_range_sets :: [Instr] -> FiniteMap Reg FeSet
499 calc_live_range_sets insns
501 -- this is the "original" (old) mapping
502 lis :: FiniteMap FE RegSet
503 lis = calc_liveness insns
505 -- establish the totality of reg names mentioned by the
506 -- insns, by scanning over the insns.
507 all_mentioned_regs :: RegSet
509 = foldl unionRegSets emptyRegSet
510 (map (\i -> case regUsage i of
511 RU rds wrs -> unionRegSets rds wrs)
514 -- Initial inverted mapping, from Reg to sets of FEs
515 initial_imap :: FiniteMap Reg FeSet
517 = listToFM [(reg, emptyFeSet)
518 | reg <- regSetToList all_mentioned_regs]
520 -- Update the new map with one element of the old map
521 upd_imap :: FiniteMap Reg FeSet -> (FE, RegSet)
522 -> FiniteMap Reg FeSet
523 upd_imap imap (fe, regset)
524 = foldl upd_1_imap imap (regSetToList regset)
527 = addToFM_C unionFeSets curr reg (unitFeSet fe)
529 -- the complete inverse mapping
530 final_imap :: FiniteMap Reg FeSet
532 = foldl upd_imap initial_imap (fmToList lis)
538 -- Given the insns, calculate the FEs, and then doing fixpointing to
539 -- figure out the set of live regs (virtual regs AND real regs) live
542 calc_liveness :: [Instr] -> FiniteMap FE RegSet
544 = let (pred_map, succ_map)
545 = find_flow_edges insns
547 -- We use the convention that if the current approximation
548 -- doesn't give a mapping for some FE, that FE maps to the
550 initial_approx, fixpoint :: FiniteMap FE RegSet
552 = mk_initial_approx 0 insns succ_map emptyFM
554 = fix_set initial_approx 1
555 -- If you want to live dangerously, and promise that the code
556 -- doesn't contain any loops (ie, there are no back edges in
557 -- the flow graph), you should be able to get away with this:
558 -- = upd_liveness_info pred_map succ_map insn_array initial_approx
559 -- But since I'm paranoid, and since it hardly makes any difference
560 -- to the compiler run-time (about 0.1%), I prefer to do the
561 -- the full fixpointing game.
564 = let n = length insns
565 in array (0, n-1) (zip [0..] insns)
567 sameSets [] [] = True
568 sameSets (c:cs) (n:ns) = eqRegSets c n && sameSets cs ns
571 fix_set curr_approx iter_number
573 = upd_liveness_info pred_map succ_map insn_array curr_approx
579 = sameSets curr_sets next_sets
581 = if same then curr_approx
582 else fix_set next_approx (iter_number+1)
584 --trace (let qqq (fe, regset)
585 -- = show fe ++ " " ++ show (regSetToList regset)
587 -- "\n::iteration " ++ show iter_number ++ "\n"
588 -- ++ (unlines . map qqq . fmToList)
589 -- next_approx ++"\n"
596 -- Create a correct initial approximation. For each instruction that
597 -- writes a register, we deem that the register is live on the
598 -- flow edges leaving the instruction. Subsequent iterations of
599 -- the liveness AbI augment this based purely on reads of regs, not
600 -- writes. We need to start off with at least this minimal write-
601 -- based information in order that writes to vregs which are never
602 -- used have non-empty live ranges. If we don't do that, we eventually
603 -- wind up assigning such vregs to any old real reg, since they don't
604 -- apparently conflict -- you can't conflict with an empty live range.
605 -- This kludge is unfortunate, but we need to do it to cover not only
606 -- writes to vregs which are never used, but also to deal correctly
607 -- with the fact that calls to C will trash the callee saves registers.
609 mk_initial_approx :: Int -> [Instr] -> Array Int [Int]
610 -> FiniteMap FE RegSet
611 -> FiniteMap FE RegSet
612 mk_initial_approx ino [] succ_map ia_so_far
614 mk_initial_approx ino (i:is) succ_map ia_so_far
616 = case regUsage i of RU rrr www -> www
618 = [case ino of { I# inoh ->
619 case ino_succ of { I# ino_succh ->
622 | ino_succ <- succ_map ! ino]
626 = loop fes (addToFM_C unionRegSets ia fe wrs)
629 = loop new_fes ia_so_far
631 mk_initial_approx (ino+1) is succ_map next_ia
634 -- Do one step in the liveness info calculation (AbI :). Given the
635 -- prior approximation (which tells you a subset of live VRegs+RRegs
636 -- for each flow edge), calculate new information for all FEs.
637 -- Rather than do this by iterating over FEs, it's easier to iterate
638 -- over insns, and update their incoming FEs.
640 upd_liveness_info :: Array Int [Int] -- instruction pred map
641 -> Array Int [Int] -- instruction succ map
642 -> Array Int Instr -- array of instructions
643 -> FiniteMap FE RegSet -- previous approx
644 -> FiniteMap FE RegSet -- improved approx
646 upd_liveness_info pred_map succ_map insn_array prev_approx
647 = do_insns hi prev_approx
649 (lo, hi) = bounds insn_array
651 enquireMapFE :: FiniteMap FE RegSet -> FE
654 = case lookupFM fm fe of
656 Nothing -> emptyRegSet
658 -- Work backwards, from the highest numbered insn to the lowest.
659 -- This is a heuristic which causes faster convergence to the
660 -- fixed point. In particular, for straight-line code with no
661 -- branches at all, arrives at the fixpoint in one iteration.
667 = [case ino of { I# inoh ->
668 case future_ino of { I# future_inoh ->
669 MkFE inoh future_inoh
671 | future_ino <- succ_map ! ino]
673 = map (enquireMapFE approx) fes_to_futures
675 = foldr unionRegSets emptyRegSet future_lives
678 = [case history_ino of { I# history_inoh ->
679 case ino of { I# inoh ->
680 MkFE history_inoh inoh
682 | history_ino <- pred_map ! ino]
684 = foldl update_one_history approx fes_from_histories
688 history_independent_component
689 = case regUsage insn of
692 (minusRegSets future_live wrs)
694 update_one_history :: FiniteMap FE RegSet
696 -> FiniteMap FE RegSet
697 update_one_history approx0 fe
698 = addToFM_C unionRegSets approx0 fe
699 history_independent_component
702 = do_insns (ino-1) new_approx
708 -- Extract the flow edges from a list of insns. Express the information
709 -- as two mappings, from insn number to insn numbers of predecessors,
710 -- and from insn number to insn numbers of successors. (Since that's
711 -- what we need to know when computing live ranges later). Instructions
712 -- are numbered starting at zero. This function is long and complex
713 -- in order to be efficient; it could equally well be shorter and slower.
715 find_flow_edges :: [Instr] -> (Array Int [Int],
717 find_flow_edges insns
719 -- First phase: make a temp env which maps labels
720 -- to insn numbers, so the second pass can know the insn
721 -- numbers for jump targets.
723 label_env :: FiniteMap CLabel Int
725 mk_label_env n env [] = env
726 mk_label_env n env ((LABEL clbl):is)
727 = mk_label_env (n+1) (addToFM env clbl n) is
728 mk_label_env n env (i:is)
729 = mk_label_env (n+1) env is
731 label_env = mk_label_env 0 emptyFM insns
733 find_label :: CLabel -> Int
735 = case lookupFM label_env jmptarget of
737 Nothing -> pprPanic "find_flow_edges: unmapped label"
738 (pprCLabel jmptarget)
740 -- Second phase: traverse the insns, and make up the successor map.
742 least_ino, greatest_ino :: Int
744 greatest_ino = length insns - 1
746 mk_succ_map :: Int -> [(Int, [Int])] -> [Instr] -> [(Int, [Int])]
748 mk_succ_map i_num rsucc_map []
751 mk_succ_map i_num rsucc_map (i:is)
752 = let i_num_1 = i_num + 1
757 -> -- A non-local jump. We can regard this insn as a terminal
758 -- insn in the graph, so we don't add any edges.
759 mk_succ_map i_num_1 ((i_num,[]):rsucc_map) is
762 | null is -- this is the last insn, and it doesn't go anywhere
763 -- (a meaningless scenario); handle it anyway
764 -> mk_succ_map i_num_1 ((i_num,[]):rsucc_map) is
766 | otherwise -- flows to next insn; add fe i_num -> i_num+1
767 -> mk_succ_map i_num_1 ((i_num, [i_num_1]): rsucc_map)
770 Branch lab -- jmps to lab; add fe i_num -> i_target
771 -> let i_target = find_label lab
773 mk_succ_map i_num_1 ((i_num, [i_target]): rsucc_map)
776 | null is -- jmps to label, or falls through, and this is
777 -- the last insn (a meaningless scenario);
779 -> error "find_flow_edges: NextOrBranch is last"
781 | otherwise -- add fes i_num -> i_num+1
782 -- and i_num -> i_target
783 -> let i_target = find_label lab
785 mk_succ_map i_num_1 ((i_num, [i_num_1, i_target]):rsucc_map)
788 -- Third phase: invert the successor map to get the predecessor
789 -- map, using an algorithm which is quadratic in the worst case,
790 -- but runs in almost-linear time, because of the nature of our
791 -- inputs: most insns have a single successor, the next insn.
793 invert :: [(Int, [Int])] -> [(Int, [Int])]
796 = concatMap ( \ (a, bs) -> [(b,a) | b <- bs] ) fmap
797 sorted_inverted_pairs
798 = isort inverted_pairs
800 grp :: Int -> [Int] -> [(Int,Int)] -> [(Int,[Int])]
801 grp k vs [] = [(k, vs)]
802 grp k vs ((kk,vv):rest)
803 | k == kk = grp k (vv:vs) rest
804 | otherwise = (k,vs) : grp kk [vv] rest
807 grp_start ((kk,vv):rest) = grp kk [vv] rest
810 = grp_start sorted_inverted_pairs
812 -- make sure that the reverse mapping maps all inos
814 | ino > greatest_ino = []
815 | otherwise = (ino,[]): add_empties (ino+1) []
816 add_empties ino ((k,vs):rest)
817 | ino < k = (ino,[]): add_empties (ino+1) ((k,vs):rest)
818 | ino == k = (k,vs) : add_empties (ino+1) rest
820 -- This is nearly linear provided that the fsts of the
821 -- list are nearly in order -- a critical assumption
823 isort :: [(Int,Int)] -> [(Int,Int)]
825 isort (x:xs) = insert x (isort xs)
827 insert :: (Int,Int) -> [(Int,Int)] -> [(Int,Int)]
830 -- specifically, this first test should almost always
831 -- be True in order for the near-linearity to happen
832 | fst y <= fst z = y:z:zs
833 | otherwise = z: insert y zs
835 add_empties least_ino grouped
840 = mk_succ_map 0 [] insns
842 = array (least_ino, greatest_ino) succ_list
846 = array (least_ino, greatest_ino) pred_list
851 -- That's all, folks! From here on is just some dull supporting stuff.
853 -- A data type for flow edges
855 = MkFE Int# Int# deriving (Eq, Ord)
857 -- deriving Show on types with unboxed fields doesn't work
858 instance Show FE where
859 showsPrec _ (MkFE s d)
860 = showString "MkFE" . shows (I# s) . shows ' ' . shows (I# d)
862 -- Blargh. Use ghc stuff soon! Or: perhaps that's not such a good
863 -- idea. Most of these sets are either empty or very small, and it
864 -- might be that the overheads of the FiniteMap based set implementation
865 -- is a net loss. The same might be true of RegSets.
867 newtype FeSet = MkFeSet [FE]
870 = MkFeSet (nukeDups (sort xs))
871 where nukeDups :: [FE] -> [FE]
875 = if x == y then nukeDups (y:xys)
876 else x : nukeDups (y:xys)
878 feSetToList (MkFeSet xs) = xs
879 isEmptyFeSet (MkFeSet xs) = null xs
880 emptyFeSet = MkFeSet []
881 eqFeSet (MkFeSet xs1) (MkFeSet xs2) = xs1 == xs2
882 unitFeSet x = MkFeSet [x]
884 elemFeSet x (MkFeSet xs)
888 f (y:ys) | x == y = True
892 unionFeSets (MkFeSet xs1) (MkFeSet xs2)
893 = MkFeSet (f xs1 xs2)
898 | a < b = a : f as (b:bs)
899 | a > b = b : f (a:as) bs
900 | otherwise = a : f as bs
902 minusFeSets (MkFeSet xs1) (MkFeSet xs2)
903 = MkFeSet (f xs1 xs2)
908 | a < b = a : f as (b:bs)
909 | a > b = f (a:as) bs
910 | otherwise = f as bs
912 intersectionFeSets (MkFeSet xs1) (MkFeSet xs2)
913 = MkFeSet (f xs1 xs2)
918 | a < b = f as (b:bs)
919 | a > b = f (a:as) bs
920 | otherwise = a : f as bs