Retrieving the datacon of an arbitrary closure
[ghc-hetmet.git] / compiler / cmm / CmmOpt.hs
index c454ff4..a3de41c 100644 (file)
@@ -15,22 +15,21 @@ module CmmOpt (
 #include "HsVersions.h"
 
 import Cmm
-import CmmUtils        ( hasNoGlobalRegs )
-import CLabel  ( entryLblToInfoLbl )
+import CmmUtils
+import CLabel
 import MachOp
-import SMRep   ( tablesNextToCode )
+import SMRep
+import StaticFlags
 
 import UniqFM
-import Unique  ( Unique )
-import Panic   ( panic )
+import Unique
 
 import Outputable
 
-import Bits
-import Word
-import Int
-import GLAEXTS
-
+import Data.Bits
+import Data.Word
+import Data.Int
+import GHC.Exts
 
 -- -----------------------------------------------------------------------------
 -- The mini-inliner
@@ -313,8 +312,12 @@ cmmMachOpFold op [x@(CmmLit _), y]
 -- put arg1 on the left of the rearranged expression, we'll get into a
 -- loop:  (x1+x2)+x3 => x1+(x2+x3)  => (x2+x3)+x1 => x2+(x3+x1) ...
 --
+-- Also don't do it if arg1 is PicBaseReg, so that we don't separate the
+-- PicBaseReg from the corresponding label (or label difference).
+--
 cmmMachOpFold mop1 [CmmMachOp mop2 [arg1,arg2], arg3]
-   | mop1 == mop2 && isAssociativeMachOp mop1 && not (isLit arg1)
+   | mop1 == mop2 && isAssociativeMachOp mop1
+     && not (isLit arg1) && not (isPicReg arg1)
    = cmmMachOpFold mop1 [arg1, cmmMachOpFold mop2 [arg2,arg3]]
 
 -- Make a RegOff if we can
@@ -385,14 +388,37 @@ cmmMachOpFold mop args@[x, y@(CmmLit (CmmInt 1 rep))]
 cmmMachOpFold mop args@[x, y@(CmmLit (CmmInt n _))]
   = case mop of
        MO_Mul rep
-           -> case exactLog2 n of
-                 Nothing -> unchanged
-                 Just p  -> CmmMachOp (MO_Shl rep) [x, CmmLit (CmmInt p rep)]
+          | Just p <- exactLog2 n ->
+                 CmmMachOp (MO_Shl rep) [x, CmmLit (CmmInt p rep)]
        MO_S_Quot rep
-           -> case exactLog2 n of
-                 Nothing -> unchanged
-                 Just p  -> CmmMachOp (MO_S_Shr rep) [x, CmmLit (CmmInt p rep)]
-       other 
+          | Just p <- exactLog2 n, 
+            CmmReg _ <- x ->   -- We duplicate x below, hence require
+                               -- it is a reg.  FIXME: remove this restriction.
+               -- shift right is not the same as quot, because it rounds
+               -- to minus infinity, whereasq uot rounds toward zero.
+               -- To fix this up, we add one less than the divisor to the
+               -- dividend if it is a negative number.
+               --
+               -- to avoid a test/jump, we use the following sequence:
+               --      x1 = x >> word_size-1  (all 1s if -ve, all 0s if +ve)
+               --      x2 = y & (divisor-1)
+               --      result = (x+x2) >>= log2(divisor)
+               -- this could be done a bit more simply using conditional moves,
+               -- but we're processor independent here.
+               --
+               -- we optimise the divide by 2 case slightly, generating
+               --      x1 = x >> word_size-1  (unsigned)
+               --      return = (x + x1) >>= log2(divisor)
+               let 
+                   bits = fromIntegral (machRepBitWidth rep) - 1
+                   shr = if p == 1 then MO_U_Shr rep else MO_S_Shr rep
+                   x1 = CmmMachOp shr [x, CmmLit (CmmInt bits rep)]
+                   x2 = if p == 1 then x1 else
+                        CmmMachOp (MO_And rep) [x1, CmmLit (CmmInt (n-1) rep)]
+                   x3 = CmmMachOp (MO_Add rep) [x, x2]
+               in
+                CmmMachOp (MO_S_Shr rep) [x3, CmmLit (CmmInt p rep)]
+       other
            -> unchanged
     where
        unchanged = CmmMachOp mop args
@@ -505,3 +531,6 @@ maybeInvertConditionalExpr :: CmmExpr -> Maybe CmmExpr
 maybeInvertConditionalExpr (CmmMachOp op args) 
   | Just op' <- maybeInvertComparison op = Just (CmmMachOp op' args)
 maybeInvertConditionalExpr _ = Nothing
+
+isPicReg (CmmReg (CmmGlobal PicBaseReg)) = True
+isPicReg _ = False
\ No newline at end of file