X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2Fcmm%2FCmm.hs;h=0d1876e0e61068db72f6c8c766dc48b1d08c4a72;hb=d5e821c43df34fa228727e7f4e9453d0fde39fb6;hp=d30f96317e1ca9ca64303e6071412f4020866792;hpb=49c98d143c382a1341e1046f5ca00819a25691ba;p=ghc-hetmet.git diff --git a/compiler/cmm/Cmm.hs b/compiler/cmm/Cmm.hs index d30f963..0d1876e 100644 --- a/compiler/cmm/Cmm.hs +++ b/compiler/cmm/Cmm.hs @@ -10,17 +10,17 @@ module Cmm ( GenCmm(..), Cmm, GenCmmTop(..), CmmTop, GenBasicBlock(..), CmmBasicBlock, blockId, blockStmts, - CmmStmt(..), + CmmStmt(..), CmmActuals, CmmFormals, CmmCallTarget(..), CmmStatic(..), Section(..), CmmExpr(..), cmmExprRep, CmmReg(..), cmmRegRep, CmmLit(..), cmmLitRep, LocalReg(..), localRegRep, - BlockId(..), + BlockId(..), BlockEnv, GlobalReg(..), globalRegRep, - node, nodeReg, spReg, hpReg, + node, nodeReg, spReg, hpReg, spLimReg ) where #include "HsVersions.h" @@ -29,6 +29,7 @@ import MachOp import CLabel import ForeignCall import Unique +import UniqFM import FastString import Data.Word @@ -113,8 +114,8 @@ data CmmStmt | CmmCall -- A foreign call, with CmmCallTarget - [(CmmReg,MachHint)] -- zero or more results - [(CmmExpr,MachHint)] -- zero or more arguments + CmmFormals -- zero or more results + CmmActuals -- zero or more arguments (Maybe [GlobalReg]) -- Global regs that may need to be saved -- if they will be clobbered by the call. -- Nothing <=> save *all* globals that @@ -130,8 +131,50 @@ data CmmStmt -- one -> second block etc -- Undefined outside range, and when there's a Nothing - | CmmJump CmmExpr [LocalReg] -- Jump to another function, with these - -- parameters. + | CmmJump CmmExpr -- Jump to another function, + CmmActuals -- with these parameters. + + | CmmReturn -- Return from a function, + CmmActuals -- with these return values. + +type CmmActuals = [(CmmExpr,MachHint)] +type CmmFormals = [(CmmReg,MachHint)] + +{- +Discussion +~~~~~~~~~~ + +One possible problem with the above type is that the only way to do a +non-local conditional jump is to encode it as a branch to a block that +contains a single jump. This leads to inefficient code in the back end. + +One possible way to fix this would be: + +data CmmStat = + ... + | CmmJump CmmBranchDest + | CmmCondJump CmmExpr CmmBranchDest + ... + +data CmmBranchDest + = Local BlockId + | NonLocal CmmExpr [LocalReg] + +In favour: + ++ one fewer constructors in CmmStmt ++ allows both cond branch and switch to jump to non-local destinations + +Against: + +- not strictly necessary: can already encode as branch+jump +- not always possible to implement any better in the back end +- could do the optimisation in the back end (but then plat-specific?) +- C-- doesn't have it +- back-end optimisation might be more general (jump shortcutting) + +So we'll stick with the way it is, and add the optimisation to the NCG. +-} ----------------------------------------------------------------------------- -- CmmCallTarget @@ -164,6 +207,7 @@ data CmmExpr -- ** is shorthand only, meaning ** -- CmmMachOp (MO_S_Add rep (CmmReg reg) (CmmLit (CmmInt i rep))) -- where rep = cmmRegRep reg + deriving Eq cmmExprRep :: CmmExpr -> MachRep cmmExprRep (CmmLit lit) = cmmLitRep lit @@ -212,6 +256,7 @@ data CmmLit -- It is also used inside the NCG during when generating -- position-independent code. | CmmLabelDiffOff CLabel CLabel Int -- label1 - label2 + offset + deriving Eq cmmLitRep :: CmmLit -> MachRep cmmLitRep (CmmInt _ rep) = rep @@ -231,6 +276,8 @@ newtype BlockId = BlockId Unique instance Uniquable BlockId where getUnique (BlockId u) = u +type BlockEnv a = UniqFM {- BlockId -} a + ----------------------------------------------------------------------------- -- Static Data ----------------------------------------------------------------------------- @@ -307,9 +354,10 @@ data GlobalReg ) -- convenient aliases -spReg, hpReg, nodeReg :: CmmReg +spReg, hpReg, spLimReg, nodeReg :: CmmReg spReg = CmmGlobal Sp hpReg = CmmGlobal Hp +spLimReg = CmmGlobal SpLim nodeReg = CmmGlobal node node :: GlobalReg