Commit 6e9501c0 authored by Simon Marlow's avatar Simon Marlow
Browse files

Beef up cmmMiniInline a tiny bit

Allow a temporary assignment to be pushed past an assignment to a
global if the global is not mentioned in the rhs of the assignment we
are inlining.

This fixes up some bad code.  We should make sure we're doing
something equivalent in the new backend in due course.
parent cd81cd88
......@@ -22,6 +22,7 @@ module CmmExpr
, DefinerOfSlots, UserOfSlots, foldSlotsDefd, foldSlotsUsed
, RegSet, emptyRegSet, elemRegSet, extendRegSet, deleteFromRegSet, mkRegSet
, plusRegSet, minusRegSet, timesRegSet
, regUsedIn
, Area(..), AreaId(..), SubArea, SubAreaSet, AreaMap, isStackSlotOf
-- MachOp
......@@ -274,6 +275,16 @@ instance DefinerOfLocalRegs a => DefinerOfLocalRegs (Maybe a) where
foldRegsDefd _ set Nothing = set
foldRegsDefd f set (Just x) = foldRegsDefd f set x
-----------------------------------------------------------------------------
-- Another reg utility
regUsedIn :: CmmReg -> CmmExpr -> Bool
_ `regUsedIn` CmmLit _ = False
reg `regUsedIn` CmmLoad e _ = reg `regUsedIn` e
reg `regUsedIn` CmmReg reg' = reg == reg'
reg `regUsedIn` CmmRegOff reg' _ = reg == reg'
reg `regUsedIn` CmmMachOp _ es = any (reg `regUsedIn`) es
_ `regUsedIn` CmmStackSlot _ _ = False
-----------------------------------------------------------------------------
-- Stack slots
......
......@@ -116,27 +116,18 @@ cmmMiniInlineStmts uses (stmt@(CmmAssign (CmmLocal (LocalReg u _)) expr) : stmts
cmmMiniInlineStmts uses (stmt:stmts)
= stmt : cmmMiniInlineStmts uses stmts
lookForInline u expr (stmt : rest)
| Just 1 <- lookupUFM (countUses stmt) u, ok_to_inline
= Just (inlineStmt u expr stmt : rest)
| ok_to_skip
= case lookForInline u expr rest of
Nothing -> Nothing
Just stmts -> Just (stmt:stmts)
| otherwise
= Nothing
-- Try to inline a temporary assignment. We can skip over assignments to
-- other tempoararies, because we know that expressions aren't side-effecting
-- and temporaries are single-assignment.
lookForInline u expr (stmt@(CmmAssign (CmmLocal (LocalReg u' _)) rhs) : rest)
| u /= u'
= case lookupUFM (countUses rhs) u of
Just 1 -> Just (inlineStmt u expr stmt : rest)
_other -> case lookForInline u expr rest of
Nothing -> Nothing
Just stmts -> Just (stmt:stmts)
lookForInline u expr (CmmNop : rest)
= lookForInline u expr rest
lookForInline _ _ [] = Nothing
lookForInline u expr (stmt:stmts)
= case lookupUFM (countUses stmt) u of
Just 1 | ok_to_inline -> Just (inlineStmt u expr stmt : stmts)
_other -> Nothing
where
-- we don't inline into CmmCall if the expression refers to global
-- registers. This is a HACK to avoid global registers clashing with
......@@ -147,6 +138,16 @@ lookForInline u expr (stmt:stmts)
CmmCall{} -> hasNoGlobalRegs expr
_ -> True
-- We can skip over assignments to other tempoararies, because we
-- know that expressions aren't side-effecting and temporaries are
-- single-assignment.
ok_to_skip = case stmt of
CmmNop -> True
CmmAssign (CmmLocal (LocalReg u' _)) rhs | u' /= u -> True
CmmAssign g@(CmmGlobal _) rhs -> not (g `regUsedIn` expr)
_other -> False
inlineStmt :: Unique -> CmmExpr -> CmmStmt -> CmmStmt
inlineStmt u a (CmmAssign r e) = CmmAssign r (inlineExpr u a e)
inlineStmt u a (CmmStore e1 e2) = CmmStore (inlineExpr u a e1) (inlineExpr u a e2)
......
......@@ -945,13 +945,6 @@ anySrc p (CmmComment _) = False
anySrc p CmmNop = False
anySrc p other = True -- Conservative
regUsedIn :: CmmReg -> CmmExpr -> Bool
reg `regUsedIn` CmmLit _ = False
reg `regUsedIn` CmmLoad e _ = reg `regUsedIn` e
reg `regUsedIn` CmmReg reg' = reg == reg'
reg `regUsedIn` CmmRegOff reg' _ = reg == reg'
reg `regUsedIn` CmmMachOp _ es = any (reg `regUsedIn`) es
locUsedIn :: CmmExpr -> CmmType -> CmmExpr -> Bool
-- (locUsedIn a r e) checks whether writing to r[a] could affect the value of
-- 'e'. Returns True if it's not sure.
......
......@@ -49,7 +49,7 @@ module StgCmmUtils (
import StgCmmMonad
import StgCmmClosure
import BlockId
import Cmm
import Cmm hiding (regUsedIn)
import MkZipCfgCmm
import CLabel
import CmmUtils
......@@ -596,7 +596,6 @@ reg `regUsedIn` CmmRegOff (CmmLocal reg') _ = reg == reg'
reg `regUsedIn` CmmMachOp _ es = any (reg `regUsedIn`) es
_reg `regUsedIn` _other = False -- The CmmGlobal cases
-------------------------------------------------------------------------
-- mkSwitch
-------------------------------------------------------------------------
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment