diff options
author | doyougnu <jeffrey.young@iohk.io> | 2021-12-08 12:29:07 -0800 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2021-12-14 20:55:06 -0500 |
commit | ecaec722850cce498b67561708ee8e42df367dda (patch) | |
tree | 98eb6c505702858c4663bda1c3f2ec2635df853d /compiler/GHC/Llvm | |
parent | 0198bb1190ffc4ac4963140e81cacd72721eab07 (diff) | |
download | haskell-ecaec722850cce498b67561708ee8e42df367dda.tar.gz |
CmmToLlvm: Remove DynFlags, add LlvmCgConfig
CodeOutput: LCGConfig, add handshake initLCGConfig
Add two modules:
GHC.CmmToLlvm.Config -- to hold the Llvm code gen config
GHC.Driver.Config.CmmToLlvm -- for initialization, other utils
CmmToLlvm: remove HasDynFlags, add LlvmConfig
CmmToLlvm: add lcgContext to LCGConfig
CmmToLlvm.Base: DynFlags --> LCGConfig
Llvm: absorb LlvmOpts into LCGConfig
CmmToLlvm.Ppr: swap DynFlags --> LCGConfig
CmmToLlvm.CodeGen: swap DynFlags --> LCGConfig
CmmToLlvm.CodeGen: swap DynFlags --> LCGConfig
CmmToLlvm.Data: swap LlvmOpts --> LCGConfig
CmmToLlvm: swap DynFlags --> LCGConfig
CmmToLlvm: move LlvmVersion to CmmToLlvm.Config
Additionally:
- refactor Config and initConfig to hold LlvmVersion
- push IO needed to get LlvmVersion to boundary between Cmm and LLvm
code generation
- remove redundant imports, this is much cleaner!
CmmToLlvm.Config: store platformMisc_llvmTarget
instead of all of platformMisc
Diffstat (limited to 'compiler/GHC/Llvm')
-rw-r--r-- | compiler/GHC/Llvm/Ppr.hs | 106 | ||||
-rw-r--r-- | compiler/GHC/Llvm/Types.hs | 15 |
2 files changed, 54 insertions, 67 deletions
diff --git a/compiler/GHC/Llvm/Ppr.hs b/compiler/GHC/Llvm/Ppr.hs index 26c6bf5862..d70ac1ad2d 100644 --- a/compiler/GHC/Llvm/Ppr.hs +++ b/compiler/GHC/Llvm/Ppr.hs @@ -39,6 +39,8 @@ import GHC.Llvm.Types import Data.Int import Data.List ( intersperse ) import GHC.Utils.Outputable + +import GHC.CmmToLlvm.Config import GHC.Utils.Panic import GHC.Types.Unique @@ -47,7 +49,7 @@ import GHC.Types.Unique -------------------------------------------------------------------------------- -- | Print out a whole LLVM module. -ppLlvmModule :: LlvmOpts -> LlvmModule -> SDoc +ppLlvmModule :: LCGConfig -> LlvmModule -> SDoc ppLlvmModule opts (LlvmModule comments aliases meta globals decls funcs) = ppLlvmComments comments $+$ newLine $+$ ppLlvmAliases aliases $+$ newLine @@ -66,11 +68,11 @@ ppLlvmComment com = semi <+> ftext com -- | Print out a list of global mutable variable definitions -ppLlvmGlobals :: LlvmOpts -> [LMGlobal] -> SDoc +ppLlvmGlobals :: LCGConfig -> [LMGlobal] -> SDoc ppLlvmGlobals opts ls = vcat $ map (ppLlvmGlobal opts) ls -- | Print out a global mutable variable definition -ppLlvmGlobal :: LlvmOpts -> LMGlobal -> SDoc +ppLlvmGlobal :: LCGConfig -> LMGlobal -> SDoc ppLlvmGlobal opts (LMGlobal var@(LMGlobalVar _ _ link x a c) dat) = let sect = case x of Just x' -> text ", section" <+> doubleQuotes (ftext x') @@ -108,11 +110,11 @@ ppLlvmAlias (name, ty) -- | Print out a list of LLVM metadata. -ppLlvmMetas :: LlvmOpts -> [MetaDecl] -> SDoc +ppLlvmMetas :: LCGConfig -> [MetaDecl] -> SDoc ppLlvmMetas opts metas = vcat $ map (ppLlvmMeta opts) metas -- | Print out an LLVM metadata definition. -ppLlvmMeta :: LlvmOpts -> MetaDecl -> SDoc +ppLlvmMeta :: LCGConfig -> MetaDecl -> SDoc ppLlvmMeta opts (MetaUnnamed n m) = ppr n <+> equals <+> ppMetaExpr opts m @@ -123,11 +125,11 @@ ppLlvmMeta _opts (MetaNamed n m) -- | Print out a list of function definitions. -ppLlvmFunctions :: LlvmOpts -> LlvmFunctions -> SDoc +ppLlvmFunctions :: LCGConfig -> LlvmFunctions -> SDoc ppLlvmFunctions opts funcs = vcat $ map (ppLlvmFunction opts) funcs -- | Print out a function definition. -ppLlvmFunction :: LlvmOpts -> LlvmFunction -> SDoc +ppLlvmFunction :: LCGConfig -> LlvmFunction -> SDoc ppLlvmFunction opts fun = let attrDoc = ppSpaceJoin (funcAttrs fun) secDoc = case funcSect fun of @@ -183,12 +185,12 @@ ppLlvmFunctionDecl (LlvmFunctionDecl n l c r varg p a) -- | Print out a list of LLVM blocks. -ppLlvmBlocks :: LlvmOpts -> LlvmBlocks -> SDoc +ppLlvmBlocks :: LCGConfig -> LlvmBlocks -> SDoc ppLlvmBlocks opts blocks = vcat $ map (ppLlvmBlock opts) blocks -- | Print out an LLVM block. -- It must be part of a function definition. -ppLlvmBlock :: LlvmOpts -> LlvmBlock -> SDoc +ppLlvmBlock :: LCGConfig -> LlvmBlock -> SDoc ppLlvmBlock opts (LlvmBlock blockId stmts) = let isLabel (MkLabel _) = True isLabel _ = False @@ -207,7 +209,7 @@ ppLlvmBlockLabel id = pprUniqueAlways id <> colon -- | Print out an LLVM statement. -ppLlvmStatement :: LlvmOpts -> LlvmStatement -> SDoc +ppLlvmStatement :: LCGConfig -> LlvmStatement -> SDoc ppLlvmStatement opts stmt = let ind = (text " " <>) in case stmt of @@ -227,7 +229,7 @@ ppLlvmStatement opts stmt = -- | Print out an LLVM expression. -ppLlvmExpression :: LlvmOpts -> LlvmExpression -> SDoc +ppLlvmExpression :: LCGConfig -> LlvmExpression -> SDoc ppLlvmExpression opts expr = case expr of Alloca tp amount -> ppAlloca opts tp amount @@ -249,7 +251,7 @@ ppLlvmExpression opts expr Asm asm c ty v se sk -> ppAsm opts asm c ty v se sk MExpr meta expr -> ppMetaAnnotExpr opts meta expr -ppMetaExpr :: LlvmOpts -> MetaExpr -> SDoc +ppMetaExpr :: LCGConfig -> MetaExpr -> SDoc ppMetaExpr opts = \case MetaVar (LMLitVar (LMNullLit _)) -> text "null" MetaStr s -> char '!' <> doubleQuotes (ftext s) @@ -264,7 +266,7 @@ ppMetaExpr opts = \case -- | Should always be a function pointer. So a global var of function type -- (since globals are always pointers) or a local var of pointer function type. -ppCall :: LlvmOpts -> LlvmCallType -> LlvmVar -> [MetaExpr] -> [LlvmFuncAttr] -> SDoc +ppCall :: LCGConfig -> LlvmCallType -> LlvmVar -> [MetaExpr] -> [LlvmFuncAttr] -> SDoc ppCall opts ct fptr args attrs = case fptr of -- -- if local var function pointer, unwrap @@ -292,7 +294,7 @@ ppCall opts ct fptr args attrs = case fptr of <> fnty <+> ppName opts fptr <> lparen <+> ppValues <+> rparen <+> attrDoc - ppCallParams :: LlvmOpts -> [[LlvmParamAttr]] -> [MetaExpr] -> SDoc + ppCallParams :: LCGConfig -> [[LlvmParamAttr]] -> [MetaExpr] -> SDoc ppCallParams opts attrs args = hsep $ punctuate comma $ zipWith ppCallMetaExpr attrs args where -- Metadata needs to be marked as having the `metadata` type when used @@ -301,13 +303,13 @@ ppCall opts ct fptr args attrs = case fptr of ppCallMetaExpr _ v = text "metadata" <+> ppMetaExpr opts v -ppMachOp :: LlvmOpts -> LlvmMachOp -> LlvmVar -> LlvmVar -> SDoc +ppMachOp :: LCGConfig -> LlvmMachOp -> LlvmVar -> LlvmVar -> SDoc ppMachOp opts op left right = (ppr op) <+> (ppr (getVarType left)) <+> ppName opts left <> comma <+> ppName opts right -ppCmpOp :: LlvmOpts -> LlvmCmpOp -> LlvmVar -> LlvmVar -> SDoc +ppCmpOp :: LCGConfig -> LlvmCmpOp -> LlvmVar -> LlvmVar -> SDoc ppCmpOp opts op left right = let cmpOp | isInt (getVarType left) && isInt (getVarType right) = text "icmp" @@ -322,7 +324,7 @@ ppCmpOp opts op left right = <+> ppName opts left <> comma <+> ppName opts right -ppAssignment :: LlvmOpts -> LlvmVar -> SDoc -> SDoc +ppAssignment :: LCGConfig -> LlvmVar -> SDoc -> SDoc ppAssignment opts var expr = ppName opts var <+> equals <+> expr ppFence :: Bool -> LlvmSyncOrdering -> SDoc @@ -352,12 +354,12 @@ ppAtomicOp LAO_Min = text "min" ppAtomicOp LAO_Umax = text "umax" ppAtomicOp LAO_Umin = text "umin" -ppAtomicRMW :: LlvmOpts -> LlvmAtomicOp -> LlvmVar -> LlvmVar -> LlvmSyncOrdering -> SDoc +ppAtomicRMW :: LCGConfig -> LlvmAtomicOp -> LlvmVar -> LlvmVar -> LlvmSyncOrdering -> SDoc ppAtomicRMW opts aop tgt src ordering = text "atomicrmw" <+> ppAtomicOp aop <+> ppVar opts tgt <> comma <+> ppVar opts src <+> ppSyncOrdering ordering -ppCmpXChg :: LlvmOpts -> LlvmVar -> LlvmVar -> LlvmVar +ppCmpXChg :: LCGConfig -> LlvmVar -> LlvmVar -> LlvmVar -> LlvmSyncOrdering -> LlvmSyncOrdering -> SDoc ppCmpXChg opts addr old new s_ord f_ord = text "cmpxchg" <+> ppVar opts addr <> comma <+> ppVar opts old <> comma <+> ppVar opts new @@ -371,16 +373,16 @@ ppCmpXChg opts addr old new s_ord f_ord = -- access patterns are aligned, in which case we will need a more granular way -- of specifying alignment. -ppLoad :: LlvmOpts -> LlvmVar -> SDoc +ppLoad :: LCGConfig -> LlvmVar -> SDoc ppLoad opts var = text "load" <+> ppr derefType <> comma <+> ppVar opts var <> align where derefType = pLower $ getVarType var align | isVector . pLower . getVarType $ var = text ", align 1" | otherwise = empty -ppALoad :: LlvmOpts -> LlvmSyncOrdering -> SingleThreaded -> LlvmVar -> SDoc +ppALoad :: LCGConfig -> LlvmSyncOrdering -> SingleThreaded -> LlvmVar -> SDoc ppALoad opts ord st var = - let alignment = (llvmWidthInBits (llvmOptsPlatform opts) $ getVarType var) `quot` 8 + let alignment = llvmWidthInBits (lcgPlatform opts) (getVarType var) `quot` 8 align = text ", align" <+> ppr alignment sThreaded | st = text " singlethread" | otherwise = empty @@ -388,7 +390,7 @@ ppALoad opts ord st var = in text "load atomic" <+> ppr derefType <> comma <+> ppVar opts var <> sThreaded <+> ppSyncOrdering ord <> align -ppStore :: LlvmOpts -> LlvmVar -> LlvmVar -> SDoc +ppStore :: LCGConfig -> LlvmVar -> LlvmVar -> SDoc ppStore opts val dst | isVecPtrVar dst = text "store" <+> ppVar opts val <> comma <+> ppVar opts dst <> comma <+> text "align 1" @@ -398,7 +400,7 @@ ppStore opts val dst isVecPtrVar = isVector . pLower . getVarType -ppCast :: LlvmOpts -> LlvmCastOp -> LlvmVar -> LlvmType -> SDoc +ppCast :: LCGConfig -> LlvmCastOp -> LlvmVar -> LlvmType -> SDoc ppCast opts op from to = ppr op <+> ppr (getVarType from) <+> ppName opts from @@ -406,19 +408,19 @@ ppCast opts op from to <+> ppr to -ppMalloc :: LlvmOpts -> LlvmType -> Int -> SDoc +ppMalloc :: LCGConfig -> LlvmType -> Int -> SDoc ppMalloc opts tp amount = let amount' = LMLitVar $ LMIntLit (toInteger amount) i32 in text "malloc" <+> ppr tp <> comma <+> ppVar opts amount' -ppAlloca :: LlvmOpts -> LlvmType -> Int -> SDoc +ppAlloca :: LCGConfig -> LlvmType -> Int -> SDoc ppAlloca opts tp amount = let amount' = LMLitVar $ LMIntLit (toInteger amount) i32 in text "alloca" <+> ppr tp <> comma <+> ppVar opts amount' -ppGetElementPtr :: LlvmOpts -> Bool -> LlvmVar -> [LlvmVar] -> SDoc +ppGetElementPtr :: LCGConfig -> Bool -> LlvmVar -> [LlvmVar] -> SDoc ppGetElementPtr opts inb ptr idx = let indexes = comma <+> ppCommaJoin (map (ppVar opts) idx) inbound = if inb then text "inbounds" else empty @@ -427,27 +429,27 @@ ppGetElementPtr opts inb ptr idx = <> indexes -ppReturn :: LlvmOpts -> Maybe LlvmVar -> SDoc +ppReturn :: LCGConfig -> Maybe LlvmVar -> SDoc ppReturn opts (Just var) = text "ret" <+> ppVar opts var ppReturn _ Nothing = text "ret" <+> ppr LMVoid -ppBranch :: LlvmOpts -> LlvmVar -> SDoc +ppBranch :: LCGConfig -> LlvmVar -> SDoc ppBranch opts var = text "br" <+> ppVar opts var -ppBranchIf :: LlvmOpts -> LlvmVar -> LlvmVar -> LlvmVar -> SDoc +ppBranchIf :: LCGConfig -> LlvmVar -> LlvmVar -> LlvmVar -> SDoc ppBranchIf opts cond trueT falseT = text "br" <+> ppVar opts cond <> comma <+> ppVar opts trueT <> comma <+> ppVar opts falseT -ppPhi :: LlvmOpts -> LlvmType -> [(LlvmVar,LlvmVar)] -> SDoc +ppPhi :: LCGConfig -> LlvmType -> [(LlvmVar,LlvmVar)] -> SDoc ppPhi opts tp preds = let ppPreds (val, label) = brackets $ ppName opts val <> comma <+> ppName opts label in text "phi" <+> ppr tp <+> hsep (punctuate comma $ map ppPreds preds) -ppSwitch :: LlvmOpts -> LlvmVar -> LlvmVar -> [(LlvmVar,LlvmVar)] -> SDoc +ppSwitch :: LCGConfig -> LlvmVar -> LlvmVar -> [(LlvmVar,LlvmVar)] -> SDoc ppSwitch opts scrut dflt targets = let ppTarget (val, lab) = ppVar opts val <> comma <+> ppVar opts lab ppTargets xs = brackets $ vcat (map ppTarget xs) @@ -455,7 +457,7 @@ ppSwitch opts scrut dflt targets = <+> ppTargets targets -ppAsm :: LlvmOpts -> LMString -> LMString -> LlvmType -> [LlvmVar] -> Bool -> Bool -> SDoc +ppAsm :: LCGConfig -> LMString -> LMString -> LlvmType -> [LlvmVar] -> Bool -> Bool -> SDoc ppAsm opts asm constraints rty vars sideeffect alignstack = let asm' = doubleQuotes $ ftext asm cons = doubleQuotes $ ftext constraints @@ -466,19 +468,19 @@ ppAsm opts asm constraints rty vars sideeffect alignstack = in text "call" <+> rty' <+> text "asm" <+> side <+> align <+> asm' <> comma <+> cons <> vars' -ppExtract :: LlvmOpts -> LlvmVar -> LlvmVar -> SDoc +ppExtract :: LCGConfig -> LlvmVar -> LlvmVar -> SDoc ppExtract opts vec idx = text "extractelement" <+> ppr (getVarType vec) <+> ppName opts vec <> comma <+> ppVar opts idx -ppExtractV :: LlvmOpts -> LlvmVar -> Int -> SDoc +ppExtractV :: LCGConfig -> LlvmVar -> Int -> SDoc ppExtractV opts struct idx = text "extractvalue" <+> ppr (getVarType struct) <+> ppName opts struct <> comma <+> ppr idx -ppInsert :: LlvmOpts -> LlvmVar -> LlvmVar -> LlvmVar -> SDoc +ppInsert :: LCGConfig -> LlvmVar -> LlvmVar -> LlvmVar -> SDoc ppInsert opts vec elt idx = text "insertelement" <+> ppr (getVarType vec) <+> ppName opts vec <> comma @@ -486,15 +488,15 @@ ppInsert opts vec elt idx = <+> ppVar opts idx -ppMetaStatement :: LlvmOpts -> [MetaAnnot] -> LlvmStatement -> SDoc +ppMetaStatement :: LCGConfig -> [MetaAnnot] -> LlvmStatement -> SDoc ppMetaStatement opts meta stmt = ppLlvmStatement opts stmt <> ppMetaAnnots opts meta -ppMetaAnnotExpr :: LlvmOpts -> [MetaAnnot] -> LlvmExpression -> SDoc +ppMetaAnnotExpr :: LCGConfig -> [MetaAnnot] -> LlvmExpression -> SDoc ppMetaAnnotExpr opts meta expr = ppLlvmExpression opts expr <> ppMetaAnnots opts meta -ppMetaAnnots :: LlvmOpts -> [MetaAnnot] -> SDoc +ppMetaAnnots :: LCGConfig -> [MetaAnnot] -> SDoc ppMetaAnnots opts meta = hcat $ map ppMeta meta where ppMeta (MetaAnnot name e) @@ -506,7 +508,7 @@ ppMetaAnnots opts meta = hcat $ map ppMeta meta -- | Return the variable name or value of the 'LlvmVar' -- in Llvm IR textual representation (e.g. @\@x@, @%y@ or @42@). -ppName :: LlvmOpts -> LlvmVar -> SDoc +ppName :: LCGConfig -> LlvmVar -> SDoc ppName opts v = case v of LMGlobalVar {} -> char '@' <> ppPlainName opts v LMLocalVar {} -> char '%' <> ppPlainName opts v @@ -515,7 +517,7 @@ ppName opts v = case v of -- | Return the variable name or value of the 'LlvmVar' -- in a plain textual representation (e.g. @x@, @y@ or @42@). -ppPlainName :: LlvmOpts -> LlvmVar -> SDoc +ppPlainName :: LCGConfig -> LlvmVar -> SDoc ppPlainName opts v = case v of (LMGlobalVar x _ _ _ _ _) -> ftext x (LMLocalVar x LMLabel ) -> text (show x) @@ -524,13 +526,13 @@ ppPlainName opts v = case v of (LMLitVar x ) -> ppLit opts x -- | Print a literal value. No type. -ppLit :: LlvmOpts -> LlvmLit -> SDoc +ppLit :: LCGConfig -> LlvmLit -> SDoc ppLit opts l = case l of (LMIntLit i (LMInt 32)) -> ppr (fromInteger i :: Int32) (LMIntLit i (LMInt 64)) -> ppr (fromInteger i :: Int64) (LMIntLit i _ ) -> ppr ((fromInteger i)::Int) - (LMFloatLit r LMFloat ) -> ppFloat (llvmOptsPlatform opts) $ narrowFp r - (LMFloatLit r LMDouble) -> ppDouble (llvmOptsPlatform opts) r + (LMFloatLit r LMFloat ) -> ppFloat (lcgPlatform opts) $ narrowFp r + (LMFloatLit r LMDouble) -> ppDouble (lcgPlatform opts) r f@(LMFloatLit _ _) -> pprPanic "ppLit" (text "Can't print this float literal: " <> ppTypeLit opts f) (LMVectorLit ls ) -> char '<' <+> ppCommaJoin (map (ppTypeLit opts) ls) <+> char '>' (LMNullLit _ ) -> text "null" @@ -542,27 +544,27 @@ ppLit opts l = case l of -- common types) with values that are likely to cause a crash or test -- failure. (LMUndefLit t ) - | llvmOptsFillUndefWithGarbage opts + | lcgFillUndefWithGarbage opts , Just lit <- garbageLit t -> ppLit opts lit | otherwise -> text "undef" -ppVar :: LlvmOpts -> LlvmVar -> SDoc +ppVar :: LCGConfig -> LlvmVar -> SDoc ppVar = ppVar' [] -ppVar' :: [LlvmParamAttr] -> LlvmOpts -> LlvmVar -> SDoc +ppVar' :: [LlvmParamAttr] -> LCGConfig -> LlvmVar -> SDoc ppVar' attrs opts v = case v of LMLitVar x -> ppTypeLit' attrs opts x x -> ppr (getVarType x) <+> ppSpaceJoin attrs <+> ppName opts x -ppTypeLit :: LlvmOpts -> LlvmLit -> SDoc +ppTypeLit :: LCGConfig -> LlvmLit -> SDoc ppTypeLit = ppTypeLit' [] -ppTypeLit' :: [LlvmParamAttr] -> LlvmOpts -> LlvmLit -> SDoc +ppTypeLit' :: [LlvmParamAttr] -> LCGConfig -> LlvmLit -> SDoc ppTypeLit' attrs opts l = case l of LMVectorLit {} -> ppLit opts l _ -> ppr (getLitType l) <+> ppSpaceJoin attrs <+> ppLit opts l -ppStatic :: LlvmOpts -> LlvmStatic -> SDoc +ppStatic :: LCGConfig -> LlvmStatic -> SDoc ppStatic opts st = case st of LMComment s -> text "; " <> ftext s LMStaticLit l -> ppTypeLit opts l @@ -578,7 +580,7 @@ ppStatic opts st = case st of LMSub s1 s2 -> pprStaticArith opts s1 s2 (text "sub") (text "fsub") (text "LMSub") -pprSpecialStatic :: LlvmOpts -> LlvmStatic -> SDoc +pprSpecialStatic :: LCGConfig -> LlvmStatic -> SDoc pprSpecialStatic opts stat = case stat of LMBitc v t -> ppr (pLower t) <> text ", bitcast (" @@ -589,7 +591,7 @@ pprSpecialStatic opts stat = case stat of _ -> ppStatic opts stat -pprStaticArith :: LlvmOpts -> LlvmStatic -> LlvmStatic -> SDoc -> SDoc +pprStaticArith :: LCGConfig -> LlvmStatic -> LlvmStatic -> SDoc -> SDoc -> SDoc -> SDoc pprStaticArith opts s1 s2 int_op float_op op_name = let ty1 = getStatType s1 diff --git a/compiler/GHC/Llvm/Types.hs b/compiler/GHC/Llvm/Types.hs index a62f0857fa..c5feba4c45 100644 --- a/compiler/GHC/Llvm/Types.hs +++ b/compiler/GHC/Llvm/Types.hs @@ -156,21 +156,6 @@ data LlvmStatic -- ** Operations on LLVM Basic Types and Variables -- --- | LLVM code generator options -data LlvmOpts = LlvmOpts - { llvmOptsPlatform :: !Platform -- ^ Target platform - , llvmOptsFillUndefWithGarbage :: !Bool -- ^ Fill undefined literals with garbage values - , llvmOptsSplitSections :: !Bool -- ^ Split sections - } - --- | Get LlvmOptions from DynFlags -initLlvmOpts :: DynFlags -> LlvmOpts -initLlvmOpts dflags = LlvmOpts - { llvmOptsPlatform = targetPlatform dflags - , llvmOptsFillUndefWithGarbage = gopt Opt_LlvmFillUndefWithGarbage dflags - , llvmOptsSplitSections = gopt Opt_SplitSections dflags - } - garbageLit :: LlvmType -> Maybe LlvmLit garbageLit t@(LMInt w) = Just (LMIntLit (0xbbbbbbbbbbbbbbb0 `mod` (2^w)) t) -- Use a value that looks like an untagged pointer, so we are more |