summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
5b82411)
We were being overly conservative, registers that were live only at a
branch target were not recorded as being dead in the branch-not-taken
code.
liveness liveregs blockmap done [] = (liveregs, done)
liveness liveregs blockmap done (instr:instrs)
liveness liveregs blockmap done [] = (liveregs, done)
liveness liveregs blockmap done (instr:instrs)
- = liveness liveregs2 blockmap ((instr,r_dying,w_dying):done) instrs
+ | not_a_branch = liveness liveregs1 blockmap
+ ((instr,r_dying,w_dying):done) instrs
+ | otherwise = liveness liveregs_br blockmap
+ ((instr,r_dying_br,w_dying):done) instrs
where
RU read written = regUsage instr
where
RU read written = regUsage instr
liveregs1 = (liveregs `delListFromUniqSet` written)
`addListToUniqSet` read
liveregs1 = (liveregs `delListFromUniqSet` written)
`addListToUniqSet` read
+ -- registers that are not live beyond this point, are recorded
+ -- as dying here.
+ r_dying = [ reg | reg <- read, reg `notElem` written,
+ not (elementOfUniqSet reg liveregs) ]
+
+ w_dying = [ reg | reg <- written,
+ not (elementOfUniqSet reg liveregs) ]
+
-- union in the live regs from all the jump destinations of this
-- instruction.
targets = jumpDests instr [] -- where we go from here
-- union in the live regs from all the jump destinations of this
-- instruction.
targets = jumpDests instr [] -- where we go from here
- liveregs2 = unionManyUniqSets
- (liveregs1 : map targetLiveRegs targets)
+ not_a_branch = null targets
targetLiveRegs target = case lookupUFM blockmap target of
Just ra -> ra
Nothing -> emptyBlockMap
targetLiveRegs target = case lookupUFM blockmap target of
Just ra -> ra
Nothing -> emptyBlockMap
- -- registers that are not live beyond this point, are recorded
- -- as dying here.
- r_dying = [ reg | reg <- read, reg `notElem` written,
- not (elementOfUniqSet reg liveregs) ]
+ live_from_branch = unionManyUniqSets (map targetLiveRegs targets)
- w_dying = [ reg | reg <- written,
- not (elementOfUniqSet reg liveregs) ]
+ liveregs_br = liveregs1 `unionUniqSets` live_from_branch
+ -- 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`
+ live_branch_only)
-- -----------------------------------------------------------------------------
-- Linear sweep to allocate registers
-- -----------------------------------------------------------------------------
-- Linear sweep to allocate registers