Beef up cmmMiniInline a tiny bit
authorSimon Marlow <marlowsd@gmail.com>
Tue, 16 Feb 2010 15:05:06 +0000 (15:05 +0000)
committerSimon Marlow <marlowsd@gmail.com>
Tue, 16 Feb 2010 15:05:06 +0000 (15:05 +0000)
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.

compiler/cmm/CmmExpr.hs
compiler/cmm/CmmOpt.hs
compiler/codeGen/CgUtils.hs
compiler/codeGen/StgCmmUtils.hs

index a4d07c2..39099f1 100644 (file)
@@ -22,6 +22,7 @@ module CmmExpr
     , DefinerOfSlots, UserOfSlots, foldSlotsDefd, foldSlotsUsed
     , RegSet, emptyRegSet, elemRegSet, extendRegSet, deleteFromRegSet, mkRegSet
             , plusRegSet, minusRegSet, timesRegSet
     , DefinerOfSlots, UserOfSlots, foldSlotsDefd, foldSlotsUsed
     , RegSet, emptyRegSet, elemRegSet, extendRegSet, deleteFromRegSet, mkRegSet
             , plusRegSet, minusRegSet, timesRegSet
+    , regUsedIn
     , Area(..), AreaId(..), SubArea, SubAreaSet, AreaMap, isStackSlotOf
  
    -- MachOp
     , 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
 
   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
 
 -----------------------------------------------------------------------------
 --    Stack slots
index 8326a48..8163073 100644 (file)
@@ -116,27 +116,18 @@ cmmMiniInlineStmts uses (stmt@(CmmAssign (CmmLocal (LocalReg u _)) expr) : stmts
 cmmMiniInlineStmts uses (stmt:stmts)
   = stmt : cmmMiniInlineStmts uses 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
   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
 
                     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)
 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)
index 8ce1ffc..f8b41a0 100644 (file)
@@ -945,13 +945,6 @@ anySrc p (CmmComment _)        = False
 anySrc p CmmNop                    = False
 anySrc p other             = True              -- Conservative
 
 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.
 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.
index 9cfb241..4b1446a 100644 (file)
@@ -49,7 +49,7 @@ module StgCmmUtils (
 import StgCmmMonad
 import StgCmmClosure
 import BlockId
 import StgCmmMonad
 import StgCmmClosure
 import BlockId
-import Cmm
+import Cmm hiding (regUsedIn)
 import MkZipCfgCmm
 import CLabel
 import CmmUtils
 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
 
 reg  `regUsedIn` CmmMachOp _ es             = any (reg `regUsedIn`) es
 _reg `regUsedIn` _other                             = False            -- The CmmGlobal cases
 
-
 -------------------------------------------------------------------------
 --     mkSwitch
 -------------------------------------------------------------------------
 -------------------------------------------------------------------------
 --     mkSwitch
 -------------------------------------------------------------------------