[commit: ghc] master: Allow the argument to 'reserve' to be a compile-time expression (58e5843)

git at git.haskell.org git at git.haskell.org
Thu Jan 16 15:52:39 UTC 2014


Repository : ssh://git@git.haskell.org/ghc

On branch  : master
Link       : http://ghc.haskell.org/trac/ghc/changeset/58e5843a4118ca19fd1c93f52f2365d90bb1b9b6/ghc

>---------------------------------------------------------------

commit 58e5843a4118ca19fd1c93f52f2365d90bb1b9b6
Author: Simon Marlow <marlowsd at gmail.com>
Date:   Thu Jan 16 15:14:49 2014 +0000

    Allow the argument to 'reserve' to be a compile-time expression
    
    By using the constant-folder to reduce it to an integer.


>---------------------------------------------------------------

58e5843a4118ca19fd1c93f52f2365d90bb1b9b6
 compiler/cmm/CmmOpt.hs  |   12 ++++++++++++
 compiler/cmm/CmmParse.y |   20 +++++++++++++++-----
 compiler/cmm/CmmSink.hs |   10 ++--------
 3 files changed, 29 insertions(+), 13 deletions(-)

diff --git a/compiler/cmm/CmmOpt.hs b/compiler/cmm/CmmOpt.hs
index acaed28..54dbbeb 100644
--- a/compiler/cmm/CmmOpt.hs
+++ b/compiler/cmm/CmmOpt.hs
@@ -7,6 +7,8 @@
 -----------------------------------------------------------------------------
 
 module CmmOpt (
+        constantFoldNode,
+        constantFoldExpr,
         cmmMachOpFold,
         cmmMachOpFoldM
  ) where
@@ -24,6 +26,16 @@ import Platform
 import Data.Bits
 import Data.Maybe
 
+
+constantFoldNode :: DynFlags -> CmmNode e x -> CmmNode e x
+constantFoldNode dflags = mapExp (constantFoldExpr dflags)
+
+constantFoldExpr :: DynFlags -> CmmExpr -> CmmExpr
+constantFoldExpr dflags = wrapRecExp f
+  where f (CmmMachOp op args) = cmmMachOpFold dflags op args
+        f (CmmRegOff r 0) = CmmReg r
+        f e = e
+
 -- -----------------------------------------------------------------------------
 -- MachOp constant folder
 
diff --git a/compiler/cmm/CmmParse.y b/compiler/cmm/CmmParse.y
index 8438198..5f2c4d8 100644
--- a/compiler/cmm/CmmParse.y
+++ b/compiler/cmm/CmmParse.y
@@ -221,6 +221,7 @@ import StgCmmLayout     hiding (ArgRep(..))
 import StgCmmTicky
 import StgCmmBind       ( emitBlackHoleCode, emitUpdateFrame )
 
+import CmmOpt
 import MkGraph
 import Cmm
 import CmmUtils
@@ -628,8 +629,8 @@ stmt    :: { CmmParse () }
                 { cmmIfThenElse $2 $4 $6 }
         | 'push' '(' exprs0 ')' maybe_body
                 { pushStackFrame $3 $5 }
-        | 'reserve' INT '=' lreg maybe_body
-                { reserveStackFrame (fromIntegral $2) $4 $5 }
+        | 'reserve' expr '=' lreg maybe_body
+                { reserveStackFrame $2 $4 $5 }
 
 foreignLabel     :: { CmmParse CmmExpr }
         : NAME                          { return (CmmLit (CmmLabel (mkForeignLabel $1 Nothing ForeignLabelInThisPackage IsFunction))) }
@@ -1076,12 +1077,21 @@ pushStackFrame fields body = do
   emit g
   withUpdFrameOff new_updfr_off body
 
-reserveStackFrame :: Int -> CmmParse CmmReg -> CmmParse () -> CmmParse ()
-reserveStackFrame size preg body = do
+reserveStackFrame
+  :: CmmParse CmmExpr
+  -> CmmParse CmmReg
+  -> CmmParse ()
+  -> CmmParse ()
+reserveStackFrame psize preg body = do
   dflags <- getDynFlags
   old_updfr_off <- getUpdFrameOff
   reg <- preg
-  let frame = old_updfr_off + wORD_SIZE dflags * size
+  esize <- psize
+  let size = case constantFoldExpr dflags esize of
+               CmmLit (CmmInt n _) -> n
+               _other -> pprPanic "CmmParse: not a compile-time integer: "
+                            (ppr esize)
+  let frame = old_updfr_off + wORD_SIZE dflags * fromIntegral size
   emitAssign reg (CmmStackSlot Old frame)
   withUpdFrameOff frame body
 
diff --git a/compiler/cmm/CmmSink.hs b/compiler/cmm/CmmSink.hs
index 6a3bcb7..c404a2e 100644
--- a/compiler/cmm/CmmSink.hs
+++ b/compiler/cmm/CmmSink.hs
@@ -171,7 +171,7 @@ cmmSink dflags graph = ofBlockList (g_entry graph) $ sink mapEmpty $ blocks
 
       -- Now sink and inline in this block
       (middle', assigs) = walk dflags ann_middles (mapFindWithDefault [] lbl sunk)
-      fold_last = constantFold dflags last
+      fold_last = constantFoldNode dflags last
       (final_last, assigs') = tryToInline dflags live fold_last assigs
 
       -- We cannot sink into join points (successors with more than
@@ -311,7 +311,7 @@ walk dflags nodes assigs = go nodes emptyBlock assigs
     | Just a <- shouldSink dflags node2 = go ns block (a : as1)
     | otherwise                         = go ns block' as'
     where
-      node1 = constantFold dflags node
+      node1 = constantFoldNode dflags node
 
       (node2, as1) = tryToInline dflags live node1 as
 
@@ -321,12 +321,6 @@ walk dflags nodes assigs = go nodes emptyBlock assigs
       block' = foldl blockSnoc block dropped `blockSnoc` node2
 
 
-constantFold :: DynFlags -> CmmNode e x -> CmmNode e x
-constantFold dflags node = mapExpDeep f node
-  where f (CmmMachOp op args) = cmmMachOpFold dflags op args
-        f (CmmRegOff r 0) = CmmReg r
-        f e = e
-
 --
 -- Heuristic to decide whether to pick up and sink an assignment
 -- Currently we pick up all assignments to local registers.  It might



More information about the ghc-commits mailing list