\begin{code}
#include "HsVersions.h"
-module AbsCSyn (
+module AbsCSyn {- (
-- export everything
AbstractC(..),
CStmtMacro(..),
mkAbsCStmtList,
mkCCostCentre,
- -- HeapOffsets, plus some convenient synonyms...
- HeapOffset,
- zeroOff, intOff, fixedHdrSize, totHdrSize, varHdrSize,
- maxOff, addOff, subOff, intOffsetIntoGoods,
- isZeroOff, possiblyEqualHeapOffset,
- pprHeapOffset,
- VirtualHeapOffset(..), HpRelOffset(..),
- VirtualSpAOffset(..), VirtualSpBOffset(..),
- SpARelOffset(..), SpBRelOffset(..),
-
-- RegRelatives
RegRelative(..),
-- registers
MagicId(..), node, infoptr,
- isVolatileReg,
-
- -- closure info
- ClosureInfo, LambdaFormInfo, UpdateFlag, SMRep,
-
- -- stuff from AbsCUtils and PprAbsC...
- nonemptyAbsC, flattenAbsC, getAmodeRep,
- mixedTypeLocn, mixedPtrLocn,
- writeRealC,
- dumpRealC,
- kindFromMagicId,
- amodeCanSurviveGC
-
-#ifdef GRAN
- , CostRes(Cost)
-#endif
-
- -- and stuff to make the interface self-sufficient
- ) where
-
-import AbsCUtils -- used, and re-exported
-import ClosureInfo -- ditto
-import Costs
-import PprAbsC -- ditto
-import HeapOffs hiding ( hpRelToInt )
-
-import PrelInfo ( PrimOp
- IF_ATTACK_PRAGMAS(COMMA tagOf_PrimOp)
- IF_ATTACK_PRAGMAS(COMMA pprPrimOp)
+ isVolatileReg, noLiveRegsMask, mkLiveRegsMask,
+ CostRes(Cost)
+ )-} where
+
+IMP_Ubiq(){-uitous-}
+
+import CgCompInfo ( mAX_Vanilla_REG, mAX_Float_REG,
+ mAX_Double_REG, lIVENESS_R1, lIVENESS_R2,
+ lIVENESS_R3, lIVENESS_R4, lIVENESS_R5,
+ lIVENESS_R6, lIVENESS_R7, lIVENESS_R8
+ )
+import HeapOffs ( SYN_IE(VirtualSpAOffset), SYN_IE(VirtualSpBOffset),
+ SYN_IE(VirtualHeapOffset)
)
-import Literal ( mkMachInt, mkMachWord, Literal(..) )
-import CLabel
-import CgCompInfo ( mAX_Vanilla_REG, mAX_Float_REG, mAX_Double_REG )
-import CostCentre -- for CostCentre type
-import Id ( Id, ConTag(..), DataCon(..) )
-import Maybes ( Maybe )
-import Outputable
-import PrimRep ( PrimRep(..) )
-import StgSyn ( GenStgExpr, GenStgArg, StgBinderInfo )
-import UniqSet ( UniqSet(..), UniqFM )
-import Unpretty -- ********** NOTE **********
-import Util
+import Literal ( mkMachInt )
+import PrimRep ( isFollowableRep, PrimRep(..) )
\end{code}
@AbstractC@ is a list of Abstract~C statements, but the data structure
is tree-ish, for easier and more efficient putting-together.
\begin{code}
+absCNop = AbsCNop
+
data AbstractC
= AbsCNop
| AbsCStmts AbstractC AbstractC
| UPD_BH_SINGLE_ENTRY
| PUSH_STD_UPD_FRAME
| POP_STD_UPD_FRAME
- | SET_ARITY
- | CHK_ARITY
| SET_TAG
-#ifdef GRAN
| GRAN_FETCH -- for GrAnSim only -- HWL
| GRAN_RESCHEDULE -- for GrAnSim only -- HWL
| GRAN_FETCH_AND_RESCHEDULE -- for GrAnSim only -- HWL
| THREAD_CONTEXT_SWITCH -- for GrAnSim only -- HWL
-#endif
+ | GRAN_YIELD -- for GrAnSim only -- HWL
deriving Text
-
\end{code}
\item[@CCallProfCtrMacro@:]
= DirectReturn -- Jump directly, if possible
| StaticVectoredReturn Int -- Fixed tag, starting at zero
| DynamicVectoredReturn CAddrMode -- Dynamic tag given by amode, starting at zero
-
\end{code}
%************************************************************************
-- Argument and return registers
| VanillaReg -- pointers, unboxed ints and chars
- PrimRep -- PtrRep, IntRep, CharRep, StablePtrRep or MallocPtrRep
+ PrimRep -- PtrRep, IntRep, CharRep, StablePtrRep or ForeignObjRep
-- (in case we need to distinguish)
FAST_INT -- its number (1 .. mAX_Vanilla_REG)
node = VanillaReg PtrRep ILIT(1) -- A convenient alias for Node
infoptr = VanillaReg DataPtrRep ILIT(2) -- An alias for InfoPtr
+
+--------------------
+noLiveRegsMask :: Int -- Mask indicating nothing live
+noLiveRegsMask = 0
+
+mkLiveRegsMask
+ :: [MagicId] -- Candidate live regs; depends what they have in them
+ -> Int
+
+mkLiveRegsMask regs
+ = foldl do_reg noLiveRegsMask regs
+ where
+ do_reg acc (VanillaReg kind reg_no)
+ | isFollowableRep kind
+ = acc + (reg_tbl !! IBOX(reg_no _SUB_ ILIT(1)))
+
+ do_reg acc anything_else = acc
+
+ reg_tbl -- ToDo: mk Array!
+ = [lIVENESS_R1, lIVENESS_R2, lIVENESS_R3, lIVENESS_R4,
+ lIVENESS_R5, lIVENESS_R6, lIVENESS_R7, lIVENESS_R8]
\end{code}
We need magical @Eq@ because @VanillaReg@s come in multiple flavors.
\begin{code}
instance Eq MagicId where
- reg1 == reg2 = tagOf_MagicId reg1 _EQ_ tagOf_MagicId reg2
-
-tagOf_MagicId BaseReg = (ILIT(0) :: FAST_INT)
-tagOf_MagicId StkOReg = ILIT(1)
-tagOf_MagicId TagReg = ILIT(2)
-tagOf_MagicId RetReg = ILIT(3)
-tagOf_MagicId SpA = ILIT(4)
-tagOf_MagicId SuA = ILIT(5)
-tagOf_MagicId SpB = ILIT(6)
-tagOf_MagicId SuB = ILIT(7)
-tagOf_MagicId Hp = ILIT(8)
-tagOf_MagicId HpLim = ILIT(9)
-tagOf_MagicId LivenessReg = ILIT(10)
-tagOf_MagicId StdUpdRetVecReg = ILIT(12)
-tagOf_MagicId StkStubReg = ILIT(13)
-tagOf_MagicId CurCostCentre = ILIT(14)
-tagOf_MagicId VoidReg = ILIT(15)
-
-tagOf_MagicId (VanillaReg _ i) = ILIT(15) _ADD_ i
-
-tagOf_MagicId (FloatReg i) = ILIT(15) _ADD_ maxv _ADD_ i
- where
- maxv = case mAX_Vanilla_REG of { IBOX(x) -> x }
-
-tagOf_MagicId (DoubleReg i) = ILIT(15) _ADD_ maxv _ADD_ maxf _ADD_ i
- where
- maxv = case mAX_Vanilla_REG of { IBOX(x) -> x }
- maxf = case mAX_Float_REG of { IBOX(x) -> x }
+ reg1 == reg2 = tag reg1 _EQ_ tag reg2
+ where
+ tag BaseReg = (ILIT(0) :: FAST_INT)
+ tag StkOReg = ILIT(1)
+ tag TagReg = ILIT(2)
+ tag RetReg = ILIT(3)
+ tag SpA = ILIT(4)
+ tag SuA = ILIT(5)
+ tag SpB = ILIT(6)
+ tag SuB = ILIT(7)
+ tag Hp = ILIT(8)
+ tag HpLim = ILIT(9)
+ tag LivenessReg = ILIT(10)
+ tag StdUpdRetVecReg = ILIT(12)
+ tag StkStubReg = ILIT(13)
+ tag CurCostCentre = ILIT(14)
+ tag VoidReg = ILIT(15)
+
+ tag (VanillaReg _ i) = ILIT(15) _ADD_ i
+
+ tag (FloatReg i) = ILIT(15) _ADD_ maxv _ADD_ i
+ where
+ maxv = case mAX_Vanilla_REG of { IBOX(x) -> x }
+
+ tag (DoubleReg i) = ILIT(15) _ADD_ maxv _ADD_ maxf _ADD_ i
+ where
+ maxv = case mAX_Vanilla_REG of { IBOX(x) -> x }
+ maxf = case mAX_Float_REG of { IBOX(x) -> x }
\end{code}
Returns True for any register that {\em potentially} dies across